----
url: https://www.selenium.dev/documentation/legacy/developers/tips/
----

# Developer Tips

Details on how to execute Selenium Test Suite with Crazy Fun.

This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/Developer-Tips)

## Running an Individual Test

When developing WebDriver, it is common to want to run a single test rather than the entire test suite for a particular driver.

You can run all the tests in a given test class this way:

```
./go test_firefox onlyRun=CombinedInputActionsTest
```

You can also run a single test directly from the command line by typing:

```
./go test_firefox method=foo
```

## Not Halting On Errors Or Failures

The test suite will halt on errors and failures by default. You can disable this behaviour by setting the `haltonerror` or `haltonfailure` environmental variables to `0`.

## Reviewing the Logs For the Tests

When you run the tests, the test results don’t appear on the screen. They are written to the \`./build/test\_logs’ folder. A pair of files are written. Their names are relatively consistent and include the details of the tests which were run. The pair comprise a txt file and an xml file. The xml file contains more information about the runtime environment such as the path, Ant version, etc. These files are overwritten the next time the same test target is executed so you may want to archive results if they’re important to you.

## Using Rake

Rake is very similar to using other build tools such as “make” or “ant”. You can specify a “target” to run by adding it as a parameter, and you can add more than one target at a time. Note that since WebDriver does not rely on ruby being installed and uses JRuby, rake should **not** be involved directly - use the *go* script instead. For example, in order to clean the build and then build and run the HtmlUnitDriver tests:

```
./go clean test_htmlunit
```

The default target that’s used will compile the code and run all the tests. More interesting targets are:

| **Target**     | **Description**                                                                                                                                                     |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| clean          | Delete the contents of the build directory, removing all compiled artifacts                                                                                         |
| test           | Compile the dependencies of and run all the tests for the HtmlUnitDriver, FirefoxDriver, and InternetExplorerDriver as well as the support library’s tests          |
| firefox        | Compile the FirefoxDriver                                                                                                                                           |
| htmlunit       | Compile the HtmlUnitDriver                                                                                                                                          |
| ie             | Compile the InternetExplorerDriver. This won’t compile the C++ on a non-Windows system, but will always compile the Java, no matter which OS you happen to be using |
| support        | Guess what this does :)                                                                                                                                             |
| test\_htmlunit | Compile the dependencies and then run the tests for the HtmlUnitDriver. The same “test\_x” pattern can be followed for all the compilation targets in this table.   |

### Running a remote Debugger with Java tests

You can run the tests in debug mode and wait for a remote java listener (which one would setup in eclipse or intellij).

```
./go debug=true suspend=true test_firefox
```

## Debugging the Firefox Driver

### Getting output from the Firefox process itself

This is usually useful to debug issues with Firefox starting up. The Java system property `webdriver.firefox.logfile` will instruct the FirefoxDriver to redirect the output to a file:

```
java -Dwebdriver.firefox.logfile=/dev/stdout -cp selenium-2.jar <sometest>
```

### Outputting to the Error Console

A common technique used for debugging of the Firefox driver extension is debug statements. The two following methods can be used from almost any Javascript code inside the extension:

* `Logger.dumpn()` - Logs a string into console (and converts arguments to strings). For example: `Logger.dumpn("Found element: " + node)`.
* `Logger.dump()` - Gets a single argument, an object, and dumps its entire contents: implemented interfaces, data fields, methods, etc.

### Getting output from the error console to a file

To see output generated using the `Logger` utility, one has to open up Firefox’s error console - difficult or simply impossible on remote machines. Fortunately, there’s a way to get the contents of the output dumped to a file:

```
FirefoxProfile p = new FirefoxProfile();
p.setPreference("webdriver.log.file", "/tmp/firefox_console");
WebDriver driver = new FirefoxDriver(p);
...
```

The `webdriver.log.file` preference will instruct the `Logger` to dump all contents of the console to the specified file. webdriver.log.file

### Getting even more output to the command line

When suspecting additional logging from Firefox could be beneficial, one can crank debugging level all the way up:

```
export NSPR_LOG_MODULES=all:3
```

Setting this environment variable will cause Firefox to log additional messages to the console. Use this environment variable together with `webdriver.firefox.logfile` to get a hold of Firefox’s output to the console.

## Debugging the Internet Explorer Driver

In order to get detailed information from IEDriverServer.exe you can run tests with the option devMode=true, this option will set logging level to DEBUG and redirect log output to the file iedriver.log

```
./go test_ie devMode=true
```

## Adding a test

Most of WebDriver’s test cases live under java/client/test/org/openqa/selenium. For example, to demonstrate an issue with clicking on elements, a test case should be added to ClickTest. The test cases already have a driver instance - no need to create one. The test use pages that are served by an in-process server, served from common/src/web. Their URLs are provided by the Pages class, so when adding a page and add it to the Pages class as well.

## Manually interacting with `RemoteWebDriverServer`

We can use a web browser or tools such as telnet to interact with a RemoteWebDriverServer e.g. to debug the JSON protocol. Here’s a simple example of checking the status of a server installed on the local machine

In a web browser

```
http://localhost:8080/wd/hub/status/
```

In telnet

```
telnet localhost 8080

GET /wd/hub/status/ HTTP/1.0
```

On Macs and Unix in general try `curl`

```
curl  http://localhost:8080/wd/hub/status
```

And on linux `wget`

```
wget http://localhost:8080/wd/hub/status
```

In all these cases the RemoteWebDriverServer should respond with

```

{status:0} 
```

----
url: https://www.selenium.dev/documentation/webdriver/support_features/expected_conditions/
----

# Waiting with Expected Conditions

```py
    wait = WebDriverWait(driver, timeout=2)
    wait.until(EC.visibility_of_element_located((By.ID, "revealed")))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_expected_conditions.py#L14-L15)

##### /examples/python/tests/support/test\_expected\_conditions.py

```py
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

# Expected Conditions API Documentation:
# https://www.selenium.dev/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html


def test_expected_condition(driver):
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html")
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(EC.visibility_of_element_located((By.ID, "revealed")))

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"
```

.NET stopped supporting Expected Conditions in Selenium 4 to minimize maintenance hassle and redundancy.

Ruby makes frequent use of blocks, procs and lambdas and does not need Expected Conditions classes

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/interactions/navigation/
----

# 浏览器导航

```java
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L14-L18)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.get("https://www.selenium.dev/selenium/web/index.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L6)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Convenient
            driver.Url = "https://selenium.dev";
            //Longer
            driver.Navigate().GoToUrl("https://selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class NavigationTest
    {
        [TestMethod]
        public void TestNavigationCommands()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            //Convenient
            driver.Url = "https://selenium.dev";
            //Longer
            driver.Navigate().GoToUrl("https://selenium.dev");
            var title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Back
            driver.Navigate().Back();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Forward
            driver.Navigate().Forward();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Refresh
            driver.Navigate().Refresh();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Quit the browser
            driver.Quit();
        }
    }
}
```

```rb

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L7-L9)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L16-L20)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
// 简便的方法
driver.get("https://selenium.dev")

// 更长的方法
driver.navigate().to("https://selenium.dev")
```

```java
        //Back
        driver.navigate().back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L22-L23)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.back()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L11)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Back
             driver.Navigate().Back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L24-L25)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
    driver.navigate.to 'https://www.selenium.dev/'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L15)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Back
    await driver.navigate().back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L24-L25)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().back() 
```

```java
        //Forward
        driver.navigate().forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L27-L28)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.forward()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L15)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Forward
             driver.Navigate().Forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L29-L30)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L23)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Forward
    await driver.navigate().forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L29-L30)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().forward()
```

```java
        //Refresh
        driver.navigate().refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L32-L33)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.refresh()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L19)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Refresh
             driver.Navigate().Refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L34-L35)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
  it 'refreshes the page' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L29)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Refresh
    await driver.navigate().refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L34-L35)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().refresh()
```

----
url: https://www.selenium.dev/pt-br/_print/documentation/webdriver/drivers/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/webdriver/drivers/).

# Sessões de Driver

* 1: [Opções do navegador](#pg-512cc0796dbc865ffe2d95d77675c341)
* 2: [Configuração do Cliente HTTP](#pg-bb62248f1e8a61bc958cebce1b1e8030)
* 3: [Classe de Serviço do Driver](#pg-bafe76e6b048a10ce7f5477057a96e92)
* 4: [WebDriver Remoto](#pg-d9253fad1d06d7d4bafa84d90ec8aa94)

```java
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L23)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L9)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            driver = new ChromeDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BaseTest.cs#L48)

##### /examples/dotnet/SeleniumDocs/BaseTest.cs

```cs
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs
{
    public class BaseTest
    {
        protected IWebDriver driver;
        protected Uri GridUrl;
        private Process _webserverProcess;
        private const string ServerJarName = "selenium-server-4.44.0.jar";
        private static readonly string BaseDirectory = AppContext.BaseDirectory;
        private const string RelativePathToGrid = "../../../../../";
        private readonly string _examplesDirectory = Path.GetFullPath(Path.Combine(BaseDirectory, RelativePathToGrid));

        [TestCleanup]
        public void Cleanup()
        {
            driver?.Quit();

            if (_webserverProcess != null)
            {
                StopServer();
            }
        }

        protected void StartDriver(string browserVersion = null)
        {
            ChromeOptions options = new ChromeOptions();
            if (browserVersion != null)
            {
                options.BrowserVersion = browserVersion;
                string userDataDir = System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetRandomFileName());
                System.IO.Directory.CreateDirectory(userDataDir);
                options.AddArgument($"--user-data-dir={userDataDir}");
                options.AddArgument("--no-sandbox");
                options.AddArgument("--disable-dev-shm-usage");
            }
            driver = new ChromeDriver(options);
        }

        protected async Task StartServer()
        {
            if (_webserverProcess == null || _webserverProcess.HasExited)
            {
                _webserverProcess = new Process();
                _webserverProcess.StartInfo.FileName =
                    RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "java.exe" : "java";
                string port = GetFreeTcpPort().ToString();
                GridUrl = new Uri("http://localhost:" + port + "/wd/hub");
                _webserverProcess.StartInfo.Arguments = " -jar " + ServerJarName +
                                                        " standalone --port " + port +
                                                        " --selenium-manager true --enable-managed-downloads true";
                _webserverProcess.StartInfo.WorkingDirectory = _examplesDirectory;
                _webserverProcess.Start();
                await EnsureGridIsRunningAsync();
            }
        }

        private void StopServer()
        {
            if (_webserverProcess != null && !_webserverProcess.HasExited)
            {
                _webserverProcess.Kill();
                _webserverProcess.Dispose();
                _webserverProcess = null;
            }
        }

        private static int GetFreeTcpPort()
        {
            TcpListener l = new TcpListener(IPAddress.Loopback, 0);
            l.Start();
            int port = ((IPEndPoint)l.LocalEndpoint).Port;
            l.Stop();
            return port;
        }

        private async Task EnsureGridIsRunningAsync()
        {
            DateTime timeout = DateTime.Now.Add(TimeSpan.FromSeconds(240));
            bool isRunning = false;
            HttpClient client = new HttpClient();

            while (!isRunning && DateTime.Now < timeout)
            {
                try
                {
                    HttpResponseMessage response = await client.GetAsync(GridUrl + "/status");
                    if (response.IsSuccessStatusCode)
                    {
                        isRunning = true;
                    }
                    else
                    {
                        await Task.Delay(1000);
                    }
                }
                catch (HttpRequestException)
                {
                    await Task.Delay(1000);
                }
            }

            if (!isRunning)
            {
                throw new TimeoutException("Could not confirm the remote selenium server is running within 30 seconds");
            }
        }
    }
}
```

```rb
      driver = Selenium::WebDriver.for :chrome, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L14)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options)
      .setChromeService(service)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/drivers/service.spec.js#L46-L50)

##### /examples/javascript/test/drivers/service.spec.js

```js
const fs = require('fs');
const os = require('os');
const path = require('path');
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const {getBinaryPaths} = require("selenium-webdriver/common/driverFinder");

describe('Service Test', function () {
  let driver;
  let userDataDir;
  let service;
  let options;

  afterEach(async function () {
    if (driver) {
      await driver.quit();
      driver = null;
    }
    if (userDataDir) {
      fs.rmSync(userDataDir, { recursive: true, force: true });
      userDataDir = null;
    }
  });

  it('Default service', async function () {
    service = new Chrome.ServiceBuilder();
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });

  it('Set Driver Location', async function () {
    options = new Chrome.Options();
    options.setBrowserVersion("stable");
    let paths = getBinaryPaths(options);
    let driverPath = paths.driverPath;
    let browserPath = paths.browserPath;
    options.setChromeBinaryPath(browserPath);
    userDataDir = fs.mkdtempSync(path.join(os.tmpdir(), 'chrome-profile-'));
    options.addArguments(`--user-data-dir=${userDataDir}`);
    options.addArguments('--no-sandbox');
    options.addArguments('--disable-dev-shm-usage');
    service = new Chrome.ServiceBuilder(driverPath);
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });

  it('Set port', async function () {
    service = new Chrome.ServiceBuilder().setPort(1234);
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
        driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L11)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L28)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L16)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L28)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L35)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

# 1 - Opções do navegador

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L73-74)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L79-80)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L11)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L80-82)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L86-88)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options.browser_version = 'latest'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L40)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## pageLoadStrategy

Três tipos de estratégias de carregamento de página estão disponíveis.

A estratégia de carregamento da página consulta o [document.readyState](//developer.mozilla.org/en-US/docs/Web/API/Document/readyState) conforme descrito na tabela abaixo:

| Estratégia | Estado pronto | Notas                                                                                   |
| ---------- | ------------- | --------------------------------------------------------------------------------------- |
| normal     | completo      | Usado por padrão, aguarda o download de todos os recursos                               |
| ansioso    | interativo    | O acesso DOM está pronto, mas outros recursos como imagens ainda podem estar carregando |
| nenhum     | Qualquer      | Não bloqueia o WebDriver                                                                |

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L21-L23)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L7-9)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L13-14)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L11-L12)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L28-L34)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L34-L36)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L15-L17)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L29-30)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L20-L21)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L8-L14)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L47-L49)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L23-L25)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
        public void SetPageLoadStrategyNone()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L41-42)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L29-L30)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L18-L24)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L88-L90)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L94-96)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L38-L39)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L60-L61)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L101-103)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L51-L52)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L38-L41)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L96-L98)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L30-32)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L114-L115)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L111-L113)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L37-39)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L105-L106)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L126-L128)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L44-46)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L96-L97)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L141-L142)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L51-53)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L60-L61)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L151-L152)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L58-60)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L69-L70)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L163-L164)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L65-67)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L78-L79)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class ProxyTest {
  public static void main(String[] args) {
    Proxy proxy = new Proxy();
    proxy.setHttpProxy("<HOST:PORT>");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("proxy", proxy);
    WebDriver driver = new ChromeDriver(options);
    driver.get("https://www.google.com/");
    driver.manage().window().maximize();
    driver.quit();
  }
}
```

```py
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L72-74)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

public class ProxyTest{
public static void Main() {
ChromeOptions options = new ChromeOptions();
Proxy proxy = new Proxy();
proxy.Kind = ProxyKind.Manual;
proxy.IsAutoDetect = false;
proxy.SslProxy = "<HOST:PORT>";
options.Proxy = proxy;
options.AddArgument("ignore-certificate-errors");
IWebDriver driver = new ChromeDriver(options);
driver.Navigate().GoToUrl("https://www.selenium.dev/");
}
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L87-L88)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```javascript
let webdriver = require('selenium-webdriver');
let chrome = require('selenium-webdriver/chrome');
let proxy = require('selenium-webdriver/proxy');
let opts = new chrome.Options();

(async function example() {
opts.setProxy(proxy.manual({http: '<HOST:PORT>'}));
let driver = new webdriver.Builder()
.forBrowser('chrome')
.setChromeOptions(opts)
.build();
try {
await driver.get("https://selenium.dev");
}
finally {
await driver.quit();
}
}());
```

```kotlin
import org.openqa.selenium.Proxy
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

class proxyTest {
fun main() {

        val proxy = Proxy()
        proxy.setHttpProxy("<HOST:PORT>")
        val options = ChromeOptions()
        options.setCapability("proxy", proxy)
        val driver: WebDriver = ChromeDriver(options)
        driver["https://www.google.com/"]
        driver.manage().window().maximize()
        driver.quit()
    }
}
```

# 2 - Configuração do Cliente HTTP

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import org.openqa.selenium.remote.http.ClientConfig;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import java.io.FileInputStream;
import java.net.URL;
import java.nio.file.Path;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.time.Duration;

import org.openqa.selenium.UsernameAndPassword;

import static java.net.http.HttpClient.Version.HTTP_1_1;

public class HttpClientTest extends BaseTest {
    URL gridUrl;

    @BeforeEach
    public void startGrid() {
        gridUrl = startStandaloneGridAdvanced();
    }

    @Test
    public void remoteWebDriverWithClientConfig() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createSSLContextWithCA(Path.of("src/test/resources/tls.crt").toAbsolutePath().toString()))
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
    }

    @Test
    public void remoteWebDriverIgnoreSSL() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createIgnoreSSLContext())
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
    }

    @Test
    public void remoteWebDriverWithEmbedAuthUrl() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createSSLContextWithCA(Path.of("src/test/resources/tls.crt").toAbsolutePath().toString()))
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(embedAuthToUrl(gridUrl, "admin", "myStrongPassword"))
                .config(clientConfig)
                .build();
    }

    private URL embedAuthToUrl(URL url, String username, String password) throws Exception {
        String userInfo = username + ":" + password;
        String urlWithAuth = url.getProtocol() + "://" + userInfo + "@" + url.getHost() + ":" + url.getPort() + url.getPath();
        return new URL(urlWithAuth);
    }

    public static SSLContext createSSLContextWithCA(String caCertPath) throws Exception {
        FileInputStream fis = new FileInputStream(caCertPath);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate caCert = (X509Certificate) cf.generateCertificate(fis);
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, null);
        keyStore.setCertificateEntry("caCert", caCert);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(keyStore);
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);
        return sslContext;
    }

    public static SSLContext createIgnoreSSLContext() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    }
                }
        };
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
        return sslContext;
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/HttpClientTest.java)

```py
import os
import pytest
import sys
from urllib3.util import Retry, Timeout
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType
from selenium.webdriver.remote.client_config import ClientConfig


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_with_client_config(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    retries = Retry(connect=2, read=2, redirect=2)
    timeout = Timeout(connect=300, read=3600)
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 init_args_for_pool_manager={
                                     "init_args_for_pool_manager": {"retries": retries, "timeout": timeout}},
                                 ca_certs=_get_resource_path("tls.crt"),
                                 username="admin", password="myStrongPassword")
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_ignore_certs(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 timeout=3600,
                                 ignore_certificates=True,
                                 username="admin", password="myStrongPassword")
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


def _get_resource_path(file_name: str):
    if os.path.abspath("").endswith("tests"):
        path = os.path.abspath(f"resources/{file_name}")
    else:
        path = os.path.abspath(f"tests/resources/{file_name}")
    return path

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_http_client.py)

[Add Example](/documentation/about/contributing/#creating-examples)

```rb

  it 'sets client configuration' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/http_client_spec.rb#L7-L8)

##### /examples/ruby/spec/drivers/http\_client\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'HTTP Client' do
  let(:url) { 'https://www.selenium.dev/selenium/web/' }

  it 'sets client configuration' do
    client = Selenium::WebDriver::Remote::Http::Default.new(open_timeout: 30, read_timeout: 30)
    expect(client.open_timeout).to eq 30
  end

  it 'uses the custom http client' do
    client = Selenium::WebDriver::Remote::Http::Default.new
    driver = Selenium::WebDriver.for :chrome, http_client: client
    driver.get(url)
    driver.quit
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

# 3 - Classe de Serviço do Driver

```java
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L15-L16)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L5-L6)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L14-L15)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

```rb
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L14-L15)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

```java
    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L25-L26)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(executable_path=chromedriver_bin)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L15)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```cs
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L23)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
    service.executable_path = driver_path
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L26)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

```java
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L33)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(port=1234)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L23)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            service.Port = 1234;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L32)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
    service.port = 1234
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L33)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```


# 4 - WebDriver Remoto

```java
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L38-L39)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L13-L14)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L28-L29)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L20-L21)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L49-L52)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

Python adds a local file detector to remote webdriver instances by default, but you can also create your own class.

```py
    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#LL29-L32)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

.NET adds a local file detector to remote webdriver instances by default, but you can also create your own class.

```cs
            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L47-L50)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

Ruby adds a local file detector to remote webdriver instances by default, but you can also create your own lambda:

```rb
    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L33-L36)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## Downloads

Chrome, Edge and Firefox each allow you to set the location of the download directory. When you do this on a remote computer, though, the location is on the remote computer’s local file system. Selenium allows you to enable downloads to get these files onto the client computer.

### Enable Downloads in the Grid

Regardless of the client, when starting the grid in node or standalone mode, you must add the flag:

```
--enable-managed-downloads true
```

```java
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L60-L62)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L42-L44)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L59-L64)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L43-L44)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    List<String> files = ((HasDownloads) driver).getDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L73)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    files = driver.get_downloadable_files()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L52)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L72)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    files = driver.downloadable_files
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L52)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L83)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    driver.download_file(downloadable_file, target_directory)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L58)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L79)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    driver.download_file(downloadable_file, target_directory)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L57)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((HasDownloads) driver).deleteDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L88)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    driver.delete_downloadable_files()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L64)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ((RemoteWebDriver)driver).DeleteDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L84)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    driver.delete_downloadable_files
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L62)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    driver = new Augmenter().augment(driver);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L98)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

Of interest, using the `RemoteWebDriverBuilder` automatically augments the driver, so it is a great way to get all the functionality by default:

```java
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L106-L111)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

.NET uses a custom command executor for executing commands that are valid for the given browser in the remote driver.

```cs
            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L96-L100)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```xml
  <dependency>
      <groupId>io.opentelemetry</groupId>
      <artifactId>opentelemetry-exporter-jaeger</artifactId>
      <version>1.0.0</version>
    </dependency>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-netty</artifactId>
      <version>1.35.0</version>
    </dependency>
```

### Add/pass the required system properties while running the client

*

```java
System.setProperty("otel.traces.exporter", "jaeger");
System.setProperty("otel.exporter.jaeger.endpoint", "http://localhost:14250");
System.setProperty("otel.resource.attributes", "service.name=selenium-java-client");

ImmutableCapabilities capabilities = new ImmutableCapabilities("browserName", "chrome");

WebDriver driver = new RemoteWebDriver(new URL("http://www.example.com"), capabilities);

driver.get("http://www.google.com");

driver.quit();
```

Please refer to [Tracing Setup](https://github.com/SeleniumHQ/selenium/blob/selenium-4.0.0-beta-1/java/server/src/org/openqa/selenium/grid/commands/tracing.txt) for more information on external dependencies versions required for the desired Selenium version.

More information can be found at:

* OpenTelemetry: <https://opentelemetry.io>
* Configuring OpenTelemetry: <https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure>
* Jaeger: <https://www.jaegertracing.io>
* [Selenium Grid Observability](https://www.selenium.dev/pt-br/documentation/grid/advanced_features/observability/)

----
url: https://www.selenium.dev/documentation/legacy/
----

# Legacy

Documentation related to the legacy components of Selenium. Meant to be kept purely for historical reasons and not as a incentive to use deprecated components.

***

##### [Selenium RC (Selenium 1)](/documentation/legacy/selenium_1/)

The original version of Selenium

##### [Selenium 2](/documentation/legacy/selenium_2/)

Selenium 2 was a rewrite of Selenium 1 that was implemented with WebDriver code.

##### [Selenium 3](/documentation/legacy/selenium_3/)

Selenium 3 was the implementation of WebDriver without the Selenium RC Code. It has since been replaced with Selenium 4, which implements the W3C WebDriver specification.

##### [Legacy Selenium IDE](/documentation/legacy/selenium_ide/)

Selenium IDE was the original Firefox extension for Record and Playback.

##### [JSON Wire Protocol Specification](/documentation/legacy/json_wire_protocol/)

The endpoints and payloads for the now-obsolete open source protocol that was the precursor to the [W3C specification](https://w3c.github.io/webdriver/).

##### [Legacy Selenium Desired Capabilities](/documentation/legacy/desired_capabilities/)

These capabilities worked with the legacy JSON Wire Protocol

##### [Legacy developer documentation](/documentation/legacy/developers/)

Information of interest to developers of Selenium

----
url: https://www.selenium.dev/zh-cn/documentation/grid/advanced_features/customize_node/
----

# 自定义Node

```bash
java -jar custom_node-server.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

```bash
java -jar selenium-server-4.6.0.jar \
--ext custom_node-1.0-SNAPSHOT.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

下面是一个示例：当Node有相关活动（会话创建、会话删除、WebDriver 命令执行等）时，仅在控制台打印一些消息。

自定义Node示例

```java
package org.seleniumhq.samples;

import java.net.URI;
import java.util.UUID;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.NoSuchSessionException;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.grid.config.Config;
import org.openqa.selenium.grid.data.CreateSessionRequest;
import org.openqa.selenium.grid.data.CreateSessionResponse;
import org.openqa.selenium.grid.data.NodeId;
import org.openqa.selenium.grid.data.NodeStatus;
import org.openqa.selenium.grid.data.Session;
import org.openqa.selenium.grid.log.LoggingOptions;
import org.openqa.selenium.grid.node.HealthCheck;
import org.openqa.selenium.grid.node.Node;
import org.openqa.selenium.grid.node.local.LocalNodeFactory;
import org.openqa.selenium.grid.security.Secret;
import org.openqa.selenium.grid.security.SecretOptions;
import org.openqa.selenium.grid.server.BaseServerOptions;
import org.openqa.selenium.internal.Either;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
import org.openqa.selenium.remote.tracing.Tracer;

public class DecoratedLoggingNode extends Node {

  private Node node;

  protected DecoratedLoggingNode(Tracer tracer, NodeId nodeId, URI uri, Secret registrationSecret, Duration sessionTimeout) {
    super(tracer, nodeId, uri, registrationSecret, sessionTimeout);
  }

  public static Node create(Config config) {
    LoggingOptions loggingOptions = new LoggingOptions(config);
    BaseServerOptions serverOptions = new BaseServerOptions(config);
    URI uri = serverOptions.getExternalUri();
    SecretOptions secretOptions = new SecretOptions(config);
    NodeOptions nodeOptions = new NodeOptions(config);
    Duration sessionTimeout = nodeOptions.getSessionTimeout();

    // Refer to the foot notes for additional context on this line.
    Node node = LocalNodeFactory.create(config);

    DecoratedLoggingNode wrapper = new DecoratedLoggingNode(loggingOptions.getTracer(),
        node.getId(),
        uri,
        secretOptions.getRegistrationSecret(),
        sessionTimeout);
    wrapper.node = node;
    return wrapper;
  }

  @Override
  public Either<WebDriverException, CreateSessionResponse> newSession(
      CreateSessionRequest sessionRequest) {
    System.out.println("Before newSession()");
    try {
      return this.node.newSession(sessionRequest);
    } finally {
      System.out.println("After newSession()");
    }
  }

  @Override
  public HttpResponse executeWebDriverCommand(HttpRequest req) {
    try {
      System.out.println("Before executeWebDriverCommand(): " + req.getUri());
      return node.executeWebDriverCommand(req);
    } finally {
      System.out.println("After executeWebDriverCommand()");
    }
  }

  @Override
  public Session getSession(SessionId id) throws NoSuchSessionException {
    try {
      System.out.println("Before getSession()");
      return node.getSession(id);
    } finally {
      System.out.println("After getSession()");
    }
  }

  @Override
  public HttpResponse uploadFile(HttpRequest req, SessionId id) {
    try {
      System.out.println("Before uploadFile()");
      return node.uploadFile(req, id);
    } finally {
      System.out.println("After uploadFile()");
    }
  }

  @Override
  public void stop(SessionId id) throws NoSuchSessionException {
    try {
      System.out.println("Before stop()");
      node.stop(id);
    } finally {
      System.out.println("After stop()");
    }
  }

  @Override
  public boolean isSessionOwner(SessionId id) {
    try {
      System.out.println("Before isSessionOwner()");
      return node.isSessionOwner(id);
    } finally {
      System.out.println("After isSessionOwner()");
    }
  }

  @Override
  public boolean isSupporting(Capabilities capabilities) {
    try {
      System.out.println("Before isSupporting");
      return node.isSupporting(capabilities);
    } finally {
      System.out.println("After isSupporting()");
    }
  }

  @Override
  public NodeStatus getStatus() {
    try {
      System.out.println("Before getStatus()");
      return node.getStatus();
    } finally {
      System.out.println("After getStatus()");
    }
  }

  @Override
  public HealthCheck getHealthCheck() {
    try {
      System.out.println("Before getHealthCheck()");
      return node.getHealthCheck();
    } finally {
      System.out.println("After getHealthCheck()");
    }
  }

  @Override
  public void drain() {
    try {
      System.out.println("Before drain()");
      node.drain();
    } finally {
      System.out.println("After drain()");
    }

  }

  @Override
  public boolean isReady() {
    try {
      System.out.println("Before isReady()");
      return node.isReady();
    } finally {
      System.out.println("After isReady()");
    }
  }
}
```

***注释：***

在上述示例中，`Node node = LocalNodeFactory.create(config);` 这一行显式创建了一个 `LocalNode`。

`org.openqa.selenium.grid.node.Node` 主要有两种*面向用户的实现*。

这些类是学习如何构建自定义 Node 以及了解 Node 内部机制的良好起点。

* `org.openqa.selenium.grid.node.local.LocalNode` - 用于表示长时间运行的 Node，也是默认实现。启动 `node` 时会自动接入。

  * 可通过 `LocalNodeFactory.create(config);` 创建，其中：

    * `LocalNodeFactory` 属于 `org.openqa.selenium.grid.node.local`
    * `Config` 属于 `org.openqa.selenium.grid.config`

* `org.openqa.selenium.grid.node.k8s.OneShotNode` - 这是一个特殊的参考实现，节点在服务完一个测试会话后会自动关闭。该类目前未包含在任何预构建的 maven 包中。

  * 你可以在 [这里](https://github.com/SeleniumHQ/selenium/blob/trunk/java/src/org/openqa/selenium/grid/node/k8s/OneShotNode.java) 查看源码。

  * 参考 [这里](https://github.com/SeleniumHQ/selenium/blob/trunk/deploys/k8s/README.md) 了解本地构建方法。

  * 可通过 `OneShotNode.create(config)` 创建，其中：

    * `OneShotNode` 属于 `org.openqa.selenium.grid.node.k8s`
    * `Config` 属于 `org.openqa.selenium.grid.config`

最后修改 October 30, 2025: [docs: translate customizing a node documentation to Chinese (#2503) (eab32ade00d)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/eab32ade00d7bdc41cfd575f813047c3667cdb95)

----
url: https://www.selenium.dev/ja/documentation/legacy/selenium_2/
----

# Selenium 2

Selenium 2 was a rewrite of Selenium 1 that was implemented with WebDriver code.

***

##### [RCからWebDriverへの移行](/ja/documentation/legacy/selenium_2/upgrading/)

##### [リモートWebDriverサーバー](/ja/documentation/legacy/selenium_2/remote_server/)

----
url: https://www.selenium.dev/zh-cn/_print/documentation/legacy/selenium_3/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/legacy/selenium_3/).

# Selenium 3

Selenium 3是摒除了Selenium RC代码的WebDriver实现. 其已被实现了W3C WebDriver规范的Selenium 4所替代.

* 1: [服务网格 3](#pg-ac76bae276f27fd0f1424e73b7d95663)
* 2: [配置自己的服务网格](#pg-31b83379d2b863eb0549de7e457f5733)
* 3: [服务网格的组件](#pg-7b2bda126f0ba862a2f42215dac75b96)

# 1 - 服务网格 3

# 2 - 配置自己的服务网格

```shell
java -jar selenium-server-standalone.jar -role hub
```

转发器(hub)默认会监听4444端口，你也可以通过打开浏览器访问<http://localhost:4444/grid/console>来查看转发器(hub)的状态。

如果需要改变默认端口，你可以添加`-port`加上一个数字作为参数来代表你期望监听的端口， 同时，所有其他的可选参数都可以在下面这个JSON配置文件里找到。

你已经在上面获得了一个简单命令，当然如果你希望一些更高级的配置， 方便起见，你也可以指定一个JSON格式的配置文件来配置并启动你的转发器(hub)。 你可以这么做：

```shell
java -jar selenium-server-standalone.jar -role hub -hubConfig hubConfig.json -debug
```

下面你可以看到一个配置文件`hubConfig.json`的例子。 我们会在第二步深入探讨怎么来提供节点配置文件。

```json
{
  "_comment" : "Configuration for Hub - hubConfig.json",
  "host": ip,
  "maxSession": 5,
  "port": 4444,
  "cleanupCycle": 5000,
  "timeout": 300000,
  "newSessionWaitTimeout": -1,
  "servlets": [],
  "prioritizer": null,
  "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
  "throwOnCapabilityNotPresent": true,
  "nodePolling": 180000,
  "platform": "WINDOWS"}
```

### 第二部: 启动节点

无论你期望你的服务网格使用新的WebDriver的功能，还是Selenium 1 RC的功能，或者2者皆有。 你都只需要使用`selenium-server-standalone.jar`来启动节点。

```shell
java -jar selenium-server-standalone.jar -role node -hub http://localhost:4444
```

如果不通过`-port`来指定端口，会选一个可用端口。你也可以在一个终端机上运行多个节点， 但是如果你这么做了，你需要意识到当你的测试使用截屏会引发你的系统内存资源和问题。

#### 配置节点的可选参数

正如前面提到的，作为一个向下兼容，“wd"和”rc”这两个角色都是节点角色的合法的自己。 当节点同时允许RC饿WebDriver的远程链接时，这些角色限制了远程连接使用的API。

通过在命令行中设置JVM属性(\_在-jar参数前\_使用`-D`参数)，会被传递到节点里： `-Dwebdriver.chrome.driver=chromedriver.exe`

#### 使用JSON配置节点

你也可以使用JSON配置文件来启动服务网格节点

```shell
java -Dwebdriver.chrome.driver=chromedriver.exe -jar selenium-server-standalone.jar -role node -nodeConfig node1Config.json
```

这里是一个配置文件`nodeConfig.json`的例子:

```json
{
  "capabilities": [
    {
      "browserName": "firefox",
      "acceptSslCerts": true,
      "javascriptEnabled": true,
      "takesScreenshot": false,
      "firefox_profile": "",
      "browser-version": "27",
      "platform": "WINDOWS",
      "maxInstances": 5,
      "firefox_binary": "",
      "cleanSession": true
    },
    {
      "browserName": "chrome",
      "maxInstances": 5,
      "platform": "WINDOWS",
      "webdriver.chrome.driver": "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"
    },
    {
      "browserName": "internet explorer",
      "maxInstances": 1,
      "platform": "WINDOWS",
      "webdriver.ie.driver": "C:/Program Files (x86)/Internet Explorer/iexplore.exe"
    }
  ],
  "configuration": {
    "_comment" : "Configuration for Node",
    "cleanUpCycle": 2000,
    "timeout": 30000,
    "proxy": "org.openqa.grid.selenium.proxy.WebDriverRemoteProxy",
    "port": 5555,
    "host": ip,
    "register": true,
    "hubPort": 4444,
    "maxSession": 5
  }
}
```

```shell
java -jar selenium-server-standalone.jar -role hub -log log.txt
```

使用你习惯的文本编辑器来打开日志文件(例子里用的log.txt)，查找"ERROR"日志来定位你的问题。

### 使用 `-debug` 参数

同时，你也可以通过使用`-debug`来向控制台打印debug日志。 启动Selenium服务网格的转发器(hub)或节点的时候使用`-debug`参数。下面是一个例子：

```shell
java -jar selenium-server-standalone.jar -role hub -debug
```

# 3 - 服务网格的组件

----
url: https://www.selenium.dev/documentation/overview/components/
----

# Selenium components

Last modified October 29, 2025: [Robotium does not support natural language features. Robot Framework … (#2508) (9667de56d4f)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/9667de56d4f85dfa29d81741893570c0b7ae4cdd)

----
url: https://www.selenium.dev/pt-br/documentation/grid/advanced_features/endpoints/
----

# Rotas da Grid

## Grid

### Status da Grid

O status da Grid fornece o estado atual da grid. Consiste em detalhes sobre cada nó registrado. Para cada nó, o status inclui informações sobre a disponibilidade, sessões e slots do nó.

```shell
curl --request GET 'http://localhost:4444/status'
```

### Deletar sessão

A exclusão da sessão encerra a sessão do WebDriver, fecha o driver e o remove do mapa de sessões ativas. Qualquer solicitação usando o id de sessão removido ou reutilizando a instância do driver gerará um erro.

```shell
curl --request DELETE 'http://localhost:4444/session/<session-id>'
```

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret> '
```

No modo totalmente distribuído, a URL é o endereço do servidor Router.

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

Se nenhum segredo de registro foi configurado durante a configuração da Grid, use

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET;'
```

### Drenar Nó

O comando de drenagem de nó é para desligamento normal de nó. A drenagem para o Node após a conclusão de todas as sessões em andamento. No entanto, ele não aceita novas solicitações de sessão.

No modo Standalone, a URL do distribuidor é o endereço do servidor Standalone.

No modo Hub-Node, a URL do Distribuidor é o endereço do servidor Hub.

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret> '
```

No modo totalmente distribuído, a URL é o endereço do servidor Router.

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

Se nenhum segredo de registro foi configurado durante a configuração da Grid, use

```shell
curl --request POST 'http://<Router-URL>/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET;'
```

## Nó

Os terminais nesta seção são aplicáveis ao modo Hub-Node e ao modo Grid totalmente distribuída, onde o Nó é executado de forma independente. A URL do Nó padrão é http\://localhost:5555 no caso de um Nó. No caso de vários Nós, use [Grid status](/pt-br/documentation/grid/advanced_features/endpoints/#grid-status) para obter todos os detalhes do Nó e localizar o endereço do Nó.

### Status

O status do Nó é essencialmente uma verificação de integridade do Nó. O distribuidor executa ping no status do Nó em intervalos regulares e atualiza o modelo de Grid de acordo. O status inclui informações sobre disponibilidade, sessões e slots.

```shell
curl --request GET 'http://localhost:5555/status'
```

### Drenagem

O Distribuidor passa o comando \[drain]\(# drain-node) para o Nó apropriado identificado pelo ID do Nó. Para drenar o Nó diretamente, use o comando curl listado abaixo. Ambos as rotas são válidas e produzem o mesmo resultado. Drenar termina as sessões em andamento antes de interromper o Nó.

```shell
curl --request POST 'http://localhost:5555/se/grid/node/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

Se nenhum segredo de registro foi configurado durante a configuração da Grid, use

```shell
curl --request POST 'http://<node-URL>/se/grid/node/drain' --header 'X-REGISTRATION-SECRET;'
```

### Checar dono da sessão

Para verificar se uma sessão pertence a um Nó, use o comando curl listado abaixo.

```shell
curl --request GET 'http://localhost:5555/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

Se nenhum segredo de registro foi configurado durante a configuração da Grid, use

```shell
curl --request GET 'http://<node-URL>/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

Ele retornará true se a sessão pertencer ao Nó, caso contrário, retornará false.

### Deletar sessão

A exclusão da sessão encerra a sessão do WebDriver, fecha o driver e o remove do mapa de sessões ativas. Qualquer solicitação usando o id de sessão removido ou reutilizando a instância do driver gerará um erro.

```shell
curl --request DELETE 'http://localhost:5555/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

Se nenhum segredo de registro foi configurado durante a configuração da Grid, use

```shell
curl --request DELETE 'http://<node-URL>/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

## Fila de Sessão

### Limpar a Fila de Sessão

A Fila de Sessão contém as novas solicitações de sessão. Para limpar a fila, use o comando curl listado abaixo. Limpar a fila rejeita todas as solicitações na fila. Para cada solicitação, o servidor retorna uma resposta de erro ao respectivo cliente. O resultado do comando clear é o número total de solicitações excluídas.

No modo Standalone, a URL Queue é o endereço do servidor Standalone.

No modo Hub-Node, a URL do enfileirador é o endereço do servidor Hub.

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

No modo totalmente distribuído, a URL do enfileirador é o endereço do servidor do Enfileirador de Sessões.

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET;'
```

### Obter novos pedidos da Fila de Sessão

Novos pedidos da Fila de Sessão contém os novos pedidos de sessão. Para obter os pedidos na Fila, utiliza o comando curl listado abaixo. É retornado o número total de pedidos na Fila.

No modo Standalone, a URL é a do servidor, em modo Grid, a URL será a do HUB.

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

No modo totalmente distribuido, a URL da Fila é a porta do servidor de Fila.

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

----
url: https://www.selenium.dev/documentation/test_practices/discouraged/performance_testing/
----

# Performance testing

Performance testing using Selenium and WebDriver is generally not advised. Not because it is incapable, but because it is not optimised for the job and you are unlikely to get good results.

It may seem ideal to performance test in the context of the user but a suite of WebDriver tests are subjected to many points of external and internal fragility which are beyond your control; for example browser startup speed, speed of HTTP servers, response of third party servers that host JavaScript or CSS, and the instrumentation penalty of the WebDriver implementation itself. Variation at these points will cause variation in your results. It is difficult to separate the difference between the performance of your website and the performance of external resources, and it is also hard to tell what the performance penalty is for using WebDriver in the browser, especially if you are injecting scripts.

The other potential attraction is “saving time” — carrying out functional and performance tests at the same time. However, functional and performance tests have opposing objectives. To test functionality, a tester may need to be patient and wait for loading, but this will cloud the performance testing results and vice versa.

To improve the performance of your website, you will need to be able to analyse overall performance independent of environment differences, identify poor code practices, breakdown of performance of individual resources (i.e. CSS or JavaScript), in order to know what to improve. There are performance testing tools available that can do this job already, that provide reporting and analysis, and can even make improvement suggestions.

Example (open source) packages to use are: [JMeter](/)

----
url: https://www.selenium.dev/documentation/legacy/selenium_2/mobile/
----

# WebDriver For Mobile Browsers

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/
----

# WebDriver

WebDriver以原生的方式驱动浏览器; 在此了解更多内容.

WebDriver 以本地化方式驱动浏览器，就像用户在本地或使用 Selenium 服务器的远程机器上所做的那样，这标志着浏览器自动化的飞跃。

Selenium WebDriver 指的是语言绑定和各个浏览器控制代码的实现。 这通常被称为 *WebDriver*。

Selenium WebDriver 是 [W3C 推荐标准](https://www.w3.org/TR/webdriver1/)

* WebDriver 被设计成一个简单和简洁的编程接口。

* WebDriver 是一个简洁的面向对象 API。

* 它能有效地驱动浏览器。

***

##### [入门指南](/zh-cn/documentation/webdriver/getting_started/)

如果你是Selenium的新手, 我们有一些资源帮助你快速入门.

##### [驱动会话](/zh-cn/documentation/webdriver/drivers/)

##### [支持的浏览器列表](/zh-cn/documentation/webdriver/browsers/)

##### [等待策略](/zh-cn/documentation/webdriver/waits/)

##### [网络元素](/zh-cn/documentation/webdriver/elements/)

在DOM中识别和使用元素对象.

##### [浏览器交互](/zh-cn/documentation/webdriver/interactions/)

##### [Actions接口](/zh-cn/documentation/webdriver/actions_api/)

用于向 Web 浏览器提供虚拟化设备输入操作的低级接口.

##### [双向功能](/zh-cn/documentation/webdriver/bidi/)

##### [Support features](/zh-cn/documentation/webdriver/support_features/)

针对更高层面功能的额外支持类.

##### [故障排除协助](/zh-cn/documentation/webdriver/troubleshooting/)

如何管理 WebDriver 的问题.

最后修改 March 29, 2024: [fix grammer fixes #1647 \[deploy site\] (690cd94e738)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/690cd94e738dee759adbfecf05b02b8fe3f8ef36)

----
url: https://www.selenium.dev/ja/documentation/ie_driver_server/
----

# IE Driver サーバー

Internet Explorer Driverは、WebDriverの仕様を実装するスタンドアロンサーバーです。

| Switch                         | 意味                                                                                    |
| ------------------------------ | ------------------------------------------------------------------------------------- |
| –port=`<portNumber>`           | IEドライバーのHTTPサーバーが言語バインディングからのコマンドをリッスンするポートを指定します。 デフォルトは5555です。                      |
| –host=`<hostAdapterIPAddress>` | IEドライバーのHTTPサーバーが言語バインディングからのコマンドをリッスンするホストアダプターのIPアドレスを指定します。 デフォルトは127.0.0.1です。     |
| –log-level=`<logLevel>`        | ロギングメッセージを出力するレベルを指定します。 有効な値は、FATAL、ERROR、WARN、INFO、DEBUG、およびTRACEです。 デフォルトはFATALです。 |
| –log-file=`<logFile>`          | ログファイルのフルパスとファイル名を指定します。 デフォルトはstdoutです。                                              |
| –extract-path=`<path>`         | サーバーが使用するサポートファイルの抽出に使用されるディレクトリへのフルパスを指定します。 指定しない場合、デフォルトでTEMPディレクトリになります。          |
| –silent                        | サーバーの起動時に診断出力を抑制します。                                                                  |

## 重要なシステムプロパティ

次のシステムプロパティ（Javaコードで `System.getProperty()` を使用して読み取り、 `System.setProperty()` または “`-DpropertyName=value`” コマンドラインフラグを使用して設定）は、 `InternetExplorerDriver` によって利用されます。

| **プロパティ**                         | **意味**                                                                                |
| --------------------------------- | ------------------------------------------------------------------------------------- |
| `webdriver.ie.driver`             | IEドライバーバイナリの場所                                                                        |
| `webdriver.ie.driver.host`        | IEドライバーがリッスンするホストアダプターのIPアドレスを指定します。                                                  |
| `webdriver.ie.driver.loglevel`    | ロギングメッセージを出力するレベルを指定します。 有効な値は、FATAL、ERROR、WARN、INFO、DEBUG、およびTRACEです。 デフォルトはFATALです。 |
| `webdriver.ie.driver.logfile`     | ログファイルのフルパスとファイル名を指定します。                                                              |
| `webdriver.ie.driver.silent`      | IEドライバーの起動時に診断出力を抑制します。                                                               |
| `webdriver.ie.driver.extractpath` | サーバーが使用するサポートファイルの抽出に使用されるディレクトリへのフルパスを指定します。 指定しない場合、デフォルトでTEMPディレクトリになります。          |


***

##### [Internet Explorer Driver Internals](/ja/documentation/ie_driver_server/internals/)

More detailed information on the IE Driver.

最終更新 January 23, 2022: [Updating IE info links in all docs\[deploy site\] (a5c7b8a0d9e)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/a5c7b8a0d9e1a6087da8f68bea1ce8f972b7dd92)

----
url: https://www.selenium.dev/pt-br/_print/documentation/legacy/selenium_2/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/legacy/selenium_2/).

# Selenium 2

Selenium 2 was a rewrite of Selenium 1 that was implemented with WebDriver code.

* 1: [Migrando do RC para WebDriver](#pg-25a61dabe1d835dcab4b1fffc7ff6b8b)
* 2: [Servidor do WebDriver remoto](#pg-2de1674c55bc150347c683000f704dc2)

# 1 - Migrando do RC para WebDriver

```java
Selenium selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.yoursite.com");
selenium.start();
```

Isso deve ser substituído assim:

```java
WebDriver driver = new FirefoxDriver();
Selenium selenium = new WebDriverBackedSelenium(driver, "http://www.yoursite.com");
```

## Próximos passos

Depois que seus testes forem executados sem erros, a próxima etapa é migrar o código de teste real para usar as APIs WebDriver. Dependendo de quão bem você abstrair o seu código, pode ser um processo curto ou longo. Em ambos os casos, a abordagem é a mesma e pode ser resumida simplesmente: modifique o código para usar a nova API quando for editá-lo.

Se você precisar extrair a implementação WebDriver subjacente da instância Selenium, você pode simplesmente fazer um cast para WrapsDriver:

```java
WebDriver driver = ((WrapsDriver) selenium).getWrappedDriver();
```

Isso permite que você continue passando a instância Selenium como normal, mas desembrulhar a instância do WebDriver conforme necessário.

Em algum ponto, sua base de código usará principalmente as APIs mais recentes. Neste ponto, você pode inverter o relacionamento, usando WebDriver em tudo e instanciar uma instância do Selenium sob demanda:

```java
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);
```

## Problemas comuns

Felizmente, você não é a primeira pessoa a passar por essa migração, então, aqui estão alguns problemas comuns que outras pessoas viram e como resolvê-los.

### Clicar e digitar são mais completos

Um padrão comum em um teste de Selenium RC é ver algo como:

```java
selenium.type("name", "exciting tex");
selenium.keyDown("name", "t");
selenium.keyPress("name", "t");
selenium.keyUp("name", "t");
```

```java
Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(30));
WebElement element= wait.until(visibilityOfElementLocated(By.id("some_id")));
```

Onde “visibilityOfElementLocated” é implementado como:

```java
public ExpectedCondition<WebElement> visibilityOfElementLocated(final By locator) {
  return new ExpectedCondition<WebElement>() {
    public WebElement apply(WebDriver driver) {
      WebElement toReturn = driver.findElement(locator);
      if (toReturn.isDisplayed()) {
        return toReturn;
      }
      return null;
    }
  };
}
```

Isso pode parecer complexo, mas é quase todo um código padrão. O único interessante é que a “condição esperada” será avaliada repetidamente até que o método “apply” retorne algo que não seja “null” nem Boolean.FALSE.

Claro, adicionar todas essas chamadas de “wait” pode confundir seu código. E se esse é o caso, e suas necessidades são simples, considere usar as esperas implícitas:

```java
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
```

```java
String name = selenium.getEval(
    "selenium.browserbot.findElement('id=foo', browserbot.getCurrentWindow()).tagName");
```

se torna:

```java
WebElement element = driver.findElement(By.id("foo"));
String name = (String) ((JavascriptExecutor) driver).executeScript(
    "return arguments[0].tagName", element);
```

Observe como a variável “element” passada aparece como o primeiro item na array de “arguments” padrão do JS.

### A execução de Javascript não retorna nada

O JavascriptExecutor do WebDriver envolverá todo o JS e o avaliará como uma expressão anônima. Isso significa que você precisa usar a palavra-chave “return”:

```java
String title = selenium.getEval("browserbot.getCurrentWindow().document.title");
```

se torna:

```java
((JavascriptExecutor) driver).executeScript("return document.title;");
```

# 2 - Servidor do WebDriver remoto

O servidor sempre será executado na máquina com o navegador que você deseja testar. O servidor pode ser usado a partir da linha de comando ou por meio de configuração de código.

## Iniciando o servidor a partir da linha de comando

Depois de fazer o download do `selenium-server-standalone-{VERSION}.jar`, coloque-o no computador com o navegador que deseja testar. Então, a partir do diretório com o jar, execute o seguinte:

```shell
java -jar selenium-server-standalone-{VERSION}.jar
```

## Considerações para executar o servidor

O chamador deve encerrar cada sessão adequadamente, chamando ou `Selenium#stop()` ou `WebDriver#quit`.

O selenium-server mantém registros na memória para cada sessão em andamento, que são apagados quando `Selenium#stop()` ou `WebDriver#quit` é chamado. E se você se esquecer de encerrar essas sessões, seu servidor pode vazar memória. E se você mantém sessões de duração extremamente longa, você provavelmente precisará parar / sair de vez em quando (ou aumentar a memória com a opção -Xmx jvm).

## Timeouts (a partir da versão 2.21)

O servidor tem dois timeouts diferentes, que podem ser definidos da seguinte forma:

```shell
java -jar selenium-server-standalone-{VERSION}.jar -timeout=20 -browserTimeout=60
```

```java
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.security.SslSocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;

import javax.servlet.Servlet;
import java.io.File;

import org.openqa.selenium.remote.server.DriverServlet;

public class AppServer {
  private Server server = new Server();

  public AppServer() throws Exception {
    WebAppContext context = new WebAppContext();
    context.setContextPath("");
    context.setWar(new File("."));
    server.addHandler(context);

    context.addServlet(DriverServlet.class, "/wd/*");

    SelectChannelConnector connector = new SelectChannelConnector();
    connector.setPort(3001);
    server.addConnector(connector);

    server.start();
  }
}
```

----
url: https://www.selenium.dev/ja/_print/documentation/legacy/selenium_ide/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/legacy/selenium_ide/).

# レガシー Selenium IDE

* 1: [HTMLランナー](#pg-83d0a8171b15b9b98fe401350fa5a31d)

```html
<tr>
    <td>Command</td>
    <td>target (locator)</td>
    <td>Value</td>
</tr>
```

|            |              |       |
| ---------- | ------------ | ----- |
| verifyText | //div//a\[2] | Login |

パラメーターは必ずしも必要ではありません。 コマンドに依存します。 両方のパラメータが必要な場合もあれば、1つのパラメータが必要な場合もあります。 また、コマンドがパラメータをまったく受け取らない場合もあります。 ここにいくつかの例があります。

|                   |             |                         |
| ----------------- | ----------- | ----------------------- |
| goBackAndWait     |             |                         |
| verifyTextPresent |             | Welcome to My Home Page |
| type              | id=phone    | (555) 666-7066          |
| type              | id=address1 | ${myVariableAddress}    |

```html
<table>
    <tr><td>open</td><td>/download/</td><td></td></tr>
    <tr><td>assertTitle</td><td></td><td>Downloads</td></tr>
    <tr><td>verifyText</td><td>//h2</td><td>Downloads</td></tr>
</table>
```

ブラウザでテーブルとしてレンダリングされると、次のようになります。

|             |            |           |
| ----------- | ---------- | --------- |
| open        | /download/ |           |
| assertTitle |            | Downloads |
| verifyText  | //h2       | Downloads |

The Selenese HTML syntax can be used to write and run tests without requiring knowledge of a programming language. With a basic knowledge of selenese and Selenium-IDE you can quickly produce and run testcases.

## テストスイート

テストスイートは、テストのコレクションです。 多くの場合、テストスイート内のすべてのテストを1つの連続バッチジョブとして実行します。

Selenium-IDEを使用する場合、テストスイートは単純なHTMLファイルを使用して定義することもできます。 構文も簡単です。 HTMLテーブルはテストのリストを定義し、各行は各テストへのファイルシステムパスを定義します。 例ですべてがわかります。

```html
<html>
<head>
<title>Test Suite Function Tests - Priority 1</title>
</head>
<body>
<table>
  <tr><td><b>Suite Of Tests</b></td></tr>
  <tr><td><a href="./Login.html">Login</a></td></tr>
  <tr><td><a href="./SearchValues.html">Test Searching for Values</a></td></tr>
  <tr><td><a href="./SaveValues.html">Test Save</a></td></tr>
</table>
</body>
</html>
```

| Command     | Target     | Value        |
| ----------- | ---------- | ------------ |
| open        | /download/ |              |
| assertTitle |            | Downloads    |
| verifyText  | //h2       | Downloads    |
| assertTable | 1.2.1      | Selenium IDE |
| verifyTable | 1.2.2      | June 3, 2008 |
| verifyTable | 1.2.3      | 1.0 beta 2   |

上記の例では、最初にページを開き、次にタイトルを期待値と比較することで正しいページがロードされることを“アサート”します。 これが成功した場合にのみ、次のコマンドが実行され、テキストが予想される場所に存在することを“検証”します。 テストケースは、最初のテーブルの2行目の最初の列に期待値が含まれていることを“アサート”します。 これに合格した場合にのみ、その行の残りのセルが“検証”されます。

### **verifyTextPresent**

`verifyTextPresent` コマンドは、 特定のテキストがページ上のどこかに存在することを検証するのに使います。 このコマンドは引数を 1 つだけ取ります。 引数には、検証するテキストのパターンを指定します。 次に例を示します。

| Command           | Target             | Value |
| ----------------- | ------------------ | ----- |
| verifyTextPresent | Marketing Analysis |       |

この例では、現在テストの対象になっているページ上で “Marketing Analysis” というテキスト文字列を探し、この文字列がページ上のどこかにあるかどうかを検証します。 verifyTextPresent コマンドは、テキストそれ自体がページ上に存在するかどうかだけを調べるときに使います。 テキストがページ上に現れる場所もテストの対象に含める必要がある場合には、このコマンドは使わないでください。

### **verifyElementPresent**

このコマンドは、特定の UI 要素について、その内容ではなく、要素の存在自体をチェックするのに使います。 具体的にはテキストはチェックせず、HTML タグだけをチェックします。 一般的な使い方として、画像が存在するかどうかのチェックなどがあります。

| Command              | Target      | Value |
| -------------------- | ----------- | ----- |
| verifyElementPresent | //div/p/img |       |

この例では、\<img> HTML タグの存在によって指定される画像が、ページ上に存在するかどうか、そして \<img> タグが \<div> タグと \<p> タグに続いて出現するかどうかを検証しています。 最初の (1 つだけの) パラメータは、要素を探す方法を Selenese コマンドに指示するための ロケータ です。 ロケータについては、次のセクションで説明します。

`verifyElementPresent`を使用して、ページ内のHTMLタグの存在を確認できます。 リンク、段落、分割 \<div>などの存在を確認できます。 さらにいくつかの例を示します。

| Command              | Target                        | Value |
| -------------------- | ----------------------------- | ----- |
| verifyElementPresent | //div/p                       |       |
| verifyElementPresent | //div/a                       |       |
| verifyElementPresent | id=Login                      |       |
| verifyElementPresent | link=Go to Marketing Research |       |
| verifyElementPresent | //a\[2]                       |       |
| verifyElementPresent | //head/title                  |       |

これらの例は、UI要素をテストするさまざまな方法を示しています。 繰り返しになりますが、ロケータについては次のセクションで説明します。

### **verifyText**

テキストとそのUI要素の両方をテストする必要がある場合は、`verifyText`を使用します。 verifyTextはロケーターを使用する必要があります。 *XPath* ロケーターまたは *DOM* ロケーターを選択した場合、特定のテキストが、ページ上のほかの UI コンポーネントとの相対位置で指定される特定の場所に出現するかどうかを検証できます。

| Command    | Target              | Value                                                               |
| ---------- | ------------------- | ------------------------------------------------------------------- |
| verifyText | //table/tr/td/div/p | This is my text and it occurs right after the div inside the table. |

## 要素の特定

多くの Selenium コマンドでは、対象を指定する必要があります。 この対象は、Web アプリケーションのコンテキスト内で要素を特定するためのもので、ロケーションストラテジーに続けて、 `locatorType=location` の形でロケーションを指定します。 多くの場合、ロケーションのタイプは省略できます。 ロケーションのタイプについては、以下で例を挙げながら説明します。

### 識別子による特定

この方法は、要素を特定する方法としておそらく最も一般的で、ロケータタイプとして認識されるものが使われていない場合の汎用デフォルトです。 このストラテジーでは、id 属性を持つ要素のうち、ロケーションに一致する最初の要素が使われます。 id 属性に一致する要素がない場合には、name 属性を持つ要素のうち、ロケーションに一致する最初の要素が使われます。

たとえば、ページソースに次のような id 属性と name 属性があったとします。

```html
  <html>
   <body>
    <form id="loginForm">
     <input name="username" type="text" />
     <input name="password" type="password" />
     <input name="continue" type="submit" value="Login" />
    </form>
   </body>
  <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
    </body>
   <html>
```

* `id=loginForm` (3)

### Nameによる特定

name ロケータタイプは、name 属性に一致する最初の要素を特定します。 1つの name 属性に対して、複数の要素が同じ値を持っている場合には、フィルタを使ってロケーションストラテジーの精度を高めることができます。 デフォルトのフィルタタイプは value です (value 属性に一致)。

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
  <html>
   <body>
    <p>Are you sure you want to do this?</p>
    <a href="continue.html">Continue</a> 
    <a href="cancel.html">Cancel</a>
  </body>
  <html>
```

* `link=Continue` (4)
* `link=Cancel` (5)

### DOMによる特定

ドキュメントオブジェクトモデルはHTMLドキュメントを表し、JavaScriptを使用してアクセスできます。 このロケーションストラテジーでは、ページ上の要素に評価される JavaScript を使用します。 単に階層型ドット記法を使って要素の位置を特定できます。

“document” で始まるのは `dom` ロケーターだけなので、DOMロケーターを指定するときに `dom=` ラベルを含める必要はありません。

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input class="required" name="username" type="text" />
      <input class="required passfield" name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | glob:\*Film\*Television\*             |       |

リンクをクリックして表示されるページの実際のタイトルは “De Anza Film And Television Department - Menu” でした。正確に一致するテキストではなく、パターンを使うと、ページのタイトルに “Film” と “Television” の 2 つの単語が (この順序で) 出現する限り、 `verifyTitle` はパスします。 たとえば、ページのオーナーがタイトルを短縮して “Film & Television Department” としても、テストはパスします。リンクとリンクが動作するかどうかのテスト (上の例では `verifyTitle`) との両方でパターンを使うことで、こうしたテストケースの保守の手間を大幅に減らすことができます。

#### 正規表現パターン

*正規表現* パターンは、Selenese がサポートしている 3 種類のパターンの中で最も強力です。 正規表現はほとんどの高水準プログラミング言語、多くのテキストエディタ、さらに Linux/Unix のコマンドラインユーティリティである **grep** や **sed** 、 **awk** など、さまざまなツールでもサポートされています。 Selenese では、正規表現パターンを使うと、それ以外の方法では実現が難しい数多くのタスクを実行することができます。 たとえば、テーブルの特定のセルに入力されているのが数字だけかどうかをテストする必要があるとします。 この場合、 `regexp: [0-9]+` と指定するだけで、任意の長さの数字に一致させることができます。

Selenese のグロビングパターンでサポートしているのは **\*** と **\[ ]** (文字クラス) だけですが、Selenese の正規表現パターンでは JavaScript に存在するものと同じ幅広い特殊文字を使用できます。 次に示すのは、これらの特殊文字です。

| PATTERN | MATCH                                                                            |
| ------- | -------------------------------------------------------------------------------- |
| .       | any single character                                                             |
| \[ ]    | character class: any single character that appears inside the brackets           |
| \*      | quantifier: 0 or more of the preceding character (or group)                      |
| +       | quantifier: 1 or more of the preceding character (or group)                      |
| ?       | quantifier: 0 or 1 of the preceding character (or group)                         |
| {1,5}   | quantifier: 1 through 5 of the preceding character (or group)                    |
| \|      | alternation: the character/group on the left or the character/group on the right |
| ( )     | grouping: often used with alternation and/or quantifier                          |

Selenese の正規表現パターンでは、先頭に `regexp:` または `regexpi:` を付ける必要があります。 前者は大文字と小文字を区別しますが、後者は大文字と小文字を区別しません。

Selenese コマンドでの正規表現パターンの使い方については、いくつか実例を挙げた方がわかりやすいでしょう。 最初の例は、おそらく最もよく使われる正規表現である **.\*** (“ドットスター”) を使ったものです。 この 2 文字の並びは、「任意の文字の 0 回以上の繰り返し」、もっとかみくだいて言えば、「すべて、または何もない」ものに一致します。1 文字のグロビングパターンで **\*** (アスタリスク 1 つ) と指定するのと等価です。

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | regexp:.\*Film.\*Television.\*        |       |

上のテスト例は、すでに示したグロビングパターンを使ったテストの例と機能的には同じです。 違いは、プリフィックス (**glob:** の代わりに **regexp:** が使われていること) と、「すべて、または何もない」パターンが指定されていること ( **\*** の代わりに **.\*** が使われていること) だけです。

次に示すのは、アラスカ州アンカレジの日の出時刻に関する情報が掲載されている Yahoo! Weather のページを対象としたもう少し複雑なテスト例です。

| Command           | Target                                            | Value |
| ----------------- | ------------------------------------------------- | ----- |
| open              | <http://weather.yahoo.com/forecast/USAK0012.html> |       |
| verifyTextPresent | regexp:Sunrise: \*\[0-9]{1,2}:\[0-9]{2} \[ap]m    |       |

上の例で使われている正規表現を 1 つずつ見てみましょう。

|              |                                       |
| ------------ | ------------------------------------- |
| `Sunrise: *` | **Sunrise:** という文字列とそれに続く 0 個以上の空白    |
| `[0-9]{1,2}` | 1 個または 2 個の数字 (時間を表す)                 |
| `:`          | 文字 : そのもの (特殊文字は使われていない)              |
| `[0-9]{2}`   | 2 個の数字 (分を表す) とそれに続く 1 個の空白           |
| `[ap]m`      | 文字 “a” または “p” とそれに続く “m” (am または pm) |

#### 完全一致

Selenium の **完全一致** パターンは、それほど使う機会はないでしょう。 完全一致パターンでは、特殊文字は一切使いません。 したがって、(グロビングパターンと正規表現パターンでは特別な意味を持つ) アスタリスク文字を検索する必要がある場合には、完全一致パターンを使うのも 1 つの方法です。 たとえば、ドロップダウンリストで “Real \*” というラベルの付いた項目を選択する場合、次のようなコードでは、期待どおりに動作する場合もそうでない場合もあります。 `glob:Real *`パターンに含まれるアスタリスクは、「すべて、または何もない」ものに一致します。 したがって、目的の select のオプションより前に “Real Numbers” というラベルの付いたオプションがあれば、それが選択され、目的の “Real \*” というオプションは選択されないことになります。

| Command | Target   | Value        |
| ------- | -------- | ------------ |
| select  | //select | glob:Real \* |

項目 “Real \*” が確実に選択されるようにするには、 `exact:` プリフィックスを使って次のように **完全一致** パターンを指定します。

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| select  | //select | exact:Real \* |

ただし、正規表現パターンで次のようにアスタリスクをエスケープしても同じ結果が得られます。

| Command | Target   | Value            |
| ------- | -------- | ---------------- |
| select  | //select | regexp:Real \\\* |

| Command | Target            | Value |
| ------- | ----------------- | ----- |
| store   | <paul@mysite.org> |       |

上のように記述すると、スクリプトのあとの方で、変数に格納された値を利用できます。 変数の値にアクセスするには、次に示すように、変数をブレース ({}) で囲み、先頭にドル記号を付けます。

| Command    | Target  | Value         |
| ---------- | ------- | ------------- |
| verifyText | //div/p | \\${userName} |

変数の一般的な使い方の 1 つに、入力フィールドへの入力を格納する操作があります。

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| type    | id=login | \\${userName} |

| Command         | Target                                         | Value       |
| --------------- | ---------------------------------------------- | ----------- |
| store           | 10                                             | hits        |
| storeXpathCount | //blockquote                                   | blockquotes |
| storeEval       | storedVars\[‘hits’].storedVars\[‘blockquotes’] | paragraphs  |

次に示すのは、JavaScript コードの断片でメソッドを呼び出す例です。 この例では、JavaScript String オブジェクトの `toUpperCase` メソッドと `toLowerCase` メソッドを呼び出しています。

| Command   | Target                            | Value |
| --------- | --------------------------------- | ----- |
| store     | Edith Wharton                     | name  |
| storeEval | storedVars\[’name’].toUpperCase() | uc    |
| storeEval | storedVars\[’name’].toUpperCase() | lc    |

#### 非スクリプトパラメータでの JavaScript の使用

コマンドが取るパラメータの種類が **スクリプト** ではない場合でも、パラメータに使う値を JavaScript を使って生成することができます。 ただし、この場合には特別な構文が必要になり、JavaScript コードの断片をブレースで囲み、その前にラベル javascript を付ける必要があります。 具体的には、 `javascript {*ここにコードを記述*}` のように指定します。 次に示すのは、 `type` コマンドの 2 番目のパラメータ `value` を、特別な構文を使って JavaScript コードから生成する例です。

| Command | Target            | Value                                                 |
| ------- | ----------------- | ----------------------------------------------------- |
| store   | league of nations | searchString                                          |
| type    | q                 | javascript{storedVars\[‘searchString’].toUpperCase()} |

## *echo* - Selenese の Print コマンド

Selenese には、テスト出力にテキストを書き込むことができる簡単なコマンドが用意されています。 このコマンドを使うと、テストの実行中に進捗状況を示す情報をコンソールに表示できるので便利です。 これらの情報を使えば、テスト結果のレポートに実行時の状況を埋め込むこともできるので、テストで問題が見つかったときに、ページ上のどこにバグがあるのか探すのに役立ちます。 また、echo 文を使うと、Selenium 変数の内容を出力できます。次に例を示します。

| Command | Target                    | Value |
| ------- | ------------------------- | ----- |
| echo    | Testing page footer now.  |       |
| echo    | Username is \\${userName} |       |

## 警告、ポップアップ、および複数のウィンドウ

次のようなページをテストしているとします。

```html
  <!DOCTYPE HTML>
  <html>
  <head>
    <script type="text/javascript">
      function output(resultText){
        document.getElementById('output').childNodes[0].nodeValue=resultText;
      }

      function show_confirm(){
        var confirmation=confirm("Chose an option.");
        if (confirmation==true){
          output("Confirmed.");
        }
        else{
          output("Rejected!");
        }
      }
      
      function show_alert(){
        alert("I'm blocking!");
        output("Alert is gone.");
      }
      function show_prompt(){
        var response = prompt("What's the best web QA tool?","Selenium");
        output(response);
      }
      function open_window(windowName){
        window.open("newWindow.html",windowName);
      }
      </script>
  </head>
  <body>

    <input type="button" id="btnConfirm" onclick="show_confirm()" value="Show confirm box" />
    <input type="button" id="btnAlert" onclick="show_alert()" value="Show alert" />
    <input type="button" id="btnPrompt" onclick="show_prompt()" value="Show prompt" />
    <a href="newWindow.html" id="lnkNewWindow" target="_blank">New Window Link</a>
    <input type="button" id="btnNewNamelessWindow" onclick="open_window()" value="Open Nameless Window" />
    <input type="button" id="btnNewNamedWindow" onclick="open_window('Mike')" value="Open Named Window" />

    <br />
    <span id="output">
    </span>
  </body>
  </html>
```

ユーザーは、アラート/確認ボックスに応答するとともに、新しく開いたポップアップウィンドウにフォーカスを移動する必要があります。 幸いなことに、SeleniumはJavaScriptポップアップをカバーできます。

ただし、アラート/確認/プロンプトを個別に詳細に説明する前に、それらの共通点を理解しておくと役立ちます。 アラート、確認ボックス、プロンプトにはすべて次のバリエーションがあります。

| Command                   | Description                          |
| ------------------------- | ------------------------------------ |
| assertFoo(pattern)        | パターンがポップアップのテキストと一致しない場合、エラーをスローします  |
| assertFooPresent          | ポップアップが利用できない場合はエラーをスローします           |
| assertFooNotPresent       | ポップアップが存在する場合、エラーをスローします             |
| storeFoo(variable)        | ポップアップのテキストを変数に保存します                 |
| storeFooPresent(variable) | ポップアップのテキストを変数に保存し、trueまたはfalseを返します |

Seleniumで実行している場合、JavaScriptポップアップは表示されません。 これは、関数呼び出しが実行時に実際にSeleniumのJavaScriptによってオーバーライドされるためです。 ただし、ポップアップが表示されないからといって、ポップアップを処理する必要はありません。 ポップアップを処理するには、その `assertFoo(pattern)` 関数を呼び出す必要があります。 ポップアップの存在をアサートしないと、次のコマンドがブロックされ、次のようなエラーが表示されます。 `[エラー]エラー：予期しない確認がありました！ [オプションを選択してください。]`

### アラート

アラートは処理が最も簡単なポップアップなので、始めましょう。 まず、ブラウザで上記のHTMLサンプルを開き、“Show alert” ボタンをクリックします。 アラートを閉じると、“Alert is gone.” というテキストが表示されます。 ページに表示されます。 次に、Selenium IDE記録で同じ手順を実行し、アラートを閉じた後にテキストが追加されたことを確認します。 テストは次のようになります。

| Command           | Target         | Value |
| ----------------- | -------------- | ----- |
| open              | /              |       |
| click             | btnAlert       |       |
| assertAlert       | I’m blocking!  |       |
| verifyTextPresent | Alert is gone. |       |

あなたは「それはおかしい、私はそのアラートをアサートしようとしたことはない」と考えているかもしれません。 ただし、これはSelenium-IDEの処理であり、アラートを閉じます。 そのステップを削除してテストを再生すると、次のエラーが表示されます `[エラー]エラー：予期しないアラートがありました！ [I'm blocking!]` 。 アラートの存在を確認するには、アラートのアサーションを含める必要があります。

アラートが存在することをアサートしたいが、アラートに含まれるテキストがわからないか気にする必要がない場合は、`assertAlertPresent`を使うことができます。 これはtrueまたはfalseを返し、falseはテストを停止します。

### 確認

確認はアラートとほぼ同じように動作し、 `assertConfirmation` と `assertConfirmationPresent` は対応するアラートと同じ特性を提供します。 ただし、デフォルトでは、確認が表示されたときにSeleniumはOKを選択します。 サンプルページの"確認ダイアログを表示"ボタンをクリックして記録を試みますが、ポップアップの"キャンセル"ボタンをクリックして、出力テキストをアサートします。 テストは次のようになります。

| Command                        | Target            | Value |
| ------------------------------ | ----------------- | ----- |
| open                           | /                 |       |
| click                          | btnConfirm        |       |
| chooseCancelOnNextConfirmation |                   |       |
| assertConfirmation             | Choose an option. |       |
| verifyTextPresent              | Rejected          |       |

`chooseCancelOnNextConfirmation` 関数は、後続のすべての確認がfalseを返すことをSeleniumに伝えます。 chooseOkOnNextConfirmationを呼び出すことでリセットできます。

Seleniumは未処理の確認があると苦情を言うので、このテストを再生できないことに気付くかもしれません。 これは、Selenium-IDEが記録するイベントの順序により、クリックしてchooseCancelOnNextConfirmationが間違った順序になるためです（考えてみれば、Seleniumは、確認を開く前にキャンセルしていることを知ることができません）。 これら2つのコマンドを切り替えると、テストは正常に実行されます。

### プロンプト

プロンプトは、`assertPrompt` および `assertPromptPresent` が対応するアラートと同じ特性を提供することで、アラートとほぼ同じように動作します。 デフォルトでは、Seleniumはプロンプトがポップアップしたときにデータの入力を待機します。 サンプルページの “Show prompt” ボタンをクリックして記録を試み、プロンプトに “Selenium” と入力します。 テストは次のようになります。

| Command            | Target                       | Value |
| ------------------ | ---------------------------- | ----- |
| open               | /                            |       |
| answerOnNextPrompt | Selenium!                    |       |
| click              | id=btnPrompt                 |       |
| assertPrompt       | What’s the best web QA tool? |       |
| verifyTextPresent  | Selenium!                    |       |

```html
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Sample Selenium Test Suite</title>
    </head>
    <body>
        <table cellpadding="1" cellspacing="1" border="1">
            <thead>
                <tr><td>Test Cases for De Anza A-Z Directory Links</td></tr>
            </thead>
        <tbody>
            <tr><td><a href="./a.html">A Links</a></td></tr>
            <tr><td><a href="./b.html">B Links</a></td></tr>
            <tr><td><a href="./c.html">C Links</a></td></tr>
            <tr><td><a href="./d.html">D Links</a></td></tr>
        </tbody>
        </table>
    </body>
</html>
```

***

*error loading test case: no command found*

「ファイル」メニューの「開く」を使用して、テストスイートファイルを開こうとしました。 代わりに「ファイル」メニューの「テストスイートを開く」を使用してください。

このエラーメッセージを改善するために、機能の拡張がリクエストされました。 詳細は、[issue 1010](http://code.google.com/p/selenium/issues/detail?id=1010)を参照してください。

***

このタイプの **エラー** は、タイミングの問題を示している可能性があります。 つまり、コマンドのロケーターによって指定された要素が、コマンドの実行時に完全にロードされていません。 コマンドの前に **pause 5000** を入れて、問題が本当にタイミングに関連しているかどうかを判断してください。 その場合、失敗したコマンドの前に適切な **waitFor\*** または **\*AndWait** コマンドを使って調査してください。

***

上記の **open** コマンドの場合のように変数置換を使用しようとして失敗した場合は、アクセスしようとしている値を持つ変数を実際に作成していないことを示します。 これは、変数を **Target** フィールドに配置する必要がある場合に **Value** フィールドに配置するか、その逆の場合があります。 上記の例では、storeコマンドの2つのパラメーターが、必要なものと逆の順序で誤って配置されています。 Seleneseコマンドの場合、最初の必須パラメーターは **Target** フィールドに入力し、2番目の必須パラメーター（存在する場合）は **Value** フィールドに入力する必要があります。

***

*error loading test case: \[Exception… “Component returned failure code: 0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND) \[nsIFileInputStream.init]” nresult: “0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND)” location: “JS frame :: chrome://selenium-ide/content/file-utils.js :: anonymous :: line 48” data: no]*

テストスイートのテストケースの1つが見つかりません。 テストケースが配置されていることを示すテストスイートが実際に配置されていることを確認してください。 また、実際のテストケースファイルのファイル名と参照先のテストスイートファイルの両方に.html拡張子が付いていることを確認してください。

このエラーメッセージを改善するために、機能の拡張がリクエストされました。 詳細は、[issue 1011](http://code.google.com/p/selenium/issues/detail?id=1011)を参照してください。

***

拡張ファイルの内容が、Selenium-IDEによって読み取られていません。 Selenium-IDE の *“オプション” メニューで “設定” をクリックし、 “一般” タブ* の **Selenium Core 拡張スクリプト (user-extension.js) のパス** フィールドに適切なパス名を指定していることを確認してください。 また、 **Selenium Core 拡張スクリプト (user-extension.js) のパス** フィールドの内容を変更した後は、Selenium-IDEを再起動する必要があります。

# 1 - HTMLランナー

```shell
[user@localhost ~]$ cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

[user@localhost ~]$ rpm -qa | egrep -i "xvfb|java-1.8|firefox"
xorg-x11-server-Xvfb-1.19.3-11.el7.x86_64
firefox-52.4.0-1.el7.centos.x86_64
java-1.8.0-openjdk-1.8.0.151-1.b12.el7_4.x86_64
java-1.8.0-openjdk-headless-1.8.0.151-1.b12.el7_4.x86_64
```

テストスイートの例

```html
[user@localhost ~]$ cat testsuite.html
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
  <title>Test Suite</title>
</head>
<body>
<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium"><tbody>
<tr><td><b>Test Suite</b></td></tr>
<tr><td><a href="YOUR-TEST-SCENARIO.html">YOUR-TEST-SCENARIO</a></td></tr>
</tbody></table>
</body>
</html>
```

## selenium-html-runnerをヘッドレスで実行する方法

さて、最も重要な部分、selenium-html-runnerの実行方法の例！ 経験によってソフトウェアの組み合わせ、- geckodriver / FF / html-runnerリリースによって異なる場合があります。

```shell
xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
```

```shell
[user@localhost ~]$ xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "*firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
Multi-window mode is longer used as an option and will be ignored.
1510061109691   geckodriver     INFO    geckodriver 0.18.0
1510061109708   geckodriver     INFO    Listening on 127.0.0.1:2885
1510061110162   geckodriver::marionette INFO    Starting browser /usr/bin/firefox with args ["-marionette"]
1510061111084   Marionette      INFO    Listening on port 43229
1510061111187   Marionette      WARN    TLS certificate errors will be ignored for this session
Nov 07, 2017 1:25:12 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
2017-11-07 13:25:12.714:INFO::main: Logging initialized @3915ms to org.seleniumhq.jetty9.util.log.StdErrLog
2017-11-07 13:25:12.804:INFO:osjs.Server:main: jetty-9.4.z-SNAPSHOT
2017-11-07 13:25:12.822:INFO:osjsh.ContextHandler:main: Started o.s.j.s.h.ContextHandler@87a85e1{/tests,null,AVAILABLE}
2017-11-07 13:25:12.843:INFO:osjs.AbstractConnector:main: Started ServerConnector@52102734{HTTP/1.1,[http/1.1]}{0.0.0.0:31892}
2017-11-07 13:25:12.843:INFO:osjs.Server:main: Started @4045ms
Nov 07, 2017 1:25:13 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |open | /auth_mellon.php |  |
Nov 07, 2017 1:25:14 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |waitForPageToLoad | 3000 |  |
.
.
.etc

<td>result:</td>
<td>PASS</td>
```

----
url: https://www.selenium.dev/documentation/webdriver/support_features/colors/
----

# Working With Colors

```java
import org.openqa.selenium.support.Color;
  
```

```python
from selenium.webdriver.support.color import Color
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```ruby
include Selenium::WebDriver::Support
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```kotlin
import org.openqa.selenium.support.Color
```

```java
private final Color HEX_COLOUR = Color.fromString("#2F7ED8");
private final Color RGB_COLOUR = Color.fromString("rgb(255, 255, 255)");
private final Color RGB_COLOUR = Color.fromString("rgb(40%, 20%, 40%)");
private final Color RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)");
private final Color RGBA_COLOUR = Color.fromString("rgba(40%, 20%, 40%, 0.5)");
private final Color HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)");
private final Color HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)");
  
```

```python
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```ruby
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```kotlin
private val HEX_COLOUR = Color.fromString("#2F7ED8")
private val RGB_COLOUR = Color.fromString("rgb(255, 255, 255)")
private val RGB_COLOUR_PERCENT = Color.fromString("rgb(40%, 20%, 40%)")
private val RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)")
private val RGBA_COLOUR_PERCENT = Color.fromString("rgba(40%, 20%, 40%, 0.5)")
private val HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)")
private val HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)")
  
```

```java
private final Color BLACK = Color.fromString("black");
private final Color CHOCOLATE = Color.fromString("chocolate");
private final Color HOTPINK = Color.fromString("hotpink");
  
```

```python
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```ruby
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```kotlin
private val BLACK = Color.fromString("black")
private val CHOCOLATE = Color.fromString("chocolate")
private val HOTPINK = Color.fromString("hotpink")
  
```

```java
private final Color TRANSPARENT = Color.fromString("transparent");
  
```

```python
TRANSPARENT = Color.from_string('transparent')
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```ruby
TRANSPARENT = Color.from_string('transparent')
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```kotlin
private val TRANSPARENT = Color.fromString("transparent")
  
```

```java
Color loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"));

Color loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"));
  
```

```python
login_button_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('color'))

login_button_background_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('background-color'))
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```ruby
login_button_colour = Color.from_string(driver.find_element(id: 'login').css_value('color'))

login_button_background_colour = Color.from_string(driver.find_element(id: 'login').css_value('background-color'))
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```kotlin
val loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"))

val loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"))
  
```

```java
assert loginButtonBackgroundColour.equals(HOTPINK);
  
```

```python
assert login_button_background_colour == HOTPINK
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```ruby
assert(login_button_background_colour == HOTPINK)
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```kotlin
assert(loginButtonBackgroundColour.equals(HOTPINK))
  
```

```java
assert loginButtonBackgroundColour.asHex().equals("#ff69b4");
assert loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)");
assert loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)");
  
```

```python
assert login_button_background_colour.hex == '#ff69b4'
assert login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)'
assert login_button_background_colour.rgb == 'rgb(255, 105, 180)'
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```ruby
assert(login_button_background_colour.hex == '#ff69b4')
assert(login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)')
assert(login_button_background_colour.rgb == 'rgb(255, 105, 180)')
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```kotlin
assert(loginButtonBackgroundColour.asHex().equals("#ff69b4"))
assert(loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)"))
assert(loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)"))
  
```

Colours are no longer a problem.

Last modified September 12, 2023: [replace code alerts with tabpanes that have code badges in each tab (59dc7de8fa6)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/59dc7de8fa68b56032da3f6415f2dc2e11f9fd69)

----
url: https://www.selenium.dev/pt-br/documentation/grid/advanced_features/external_datastore/
----

# External datastore

```sql
CREATE TABLE IF NOT EXISTS sessions_map(
    session_ids varchar(256),
    session_caps text,
    session_uri varchar(256),
    session_stereotype text,
    session_start varchar(256)
 );
```

* In the same directory as the `init.sql`, create a file named `docker-compose.yml` with its contents as below:

```yaml
version: '3.8'
services:
  db:
    image: postgres:9.6-bullseye
    restart: always
    environment:
      - POSTGRES_USER=seluser
      - POSTGRES_PASSWORD=seluser
      - POSTGRES_DB=selenium_sessions
    ports:
      - "5432:5432"
    volumes:
    - ./init.sql:/docker-entrypoint-initdb.d/init.sql
```

We can now start our database container by running:

```bash
docker-compose up -d
```

*Our database name is `selenium_sessions` with its username and password set to `seluser`*

If you are working with an already running PostGreSQL DB instance, then you just need to create a database named `selenium_sessions` and the table `sessions_map` using the above mentioned SQL statement.

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
implementation = "org.openqa.selenium.grid.sessionmap.jdbc.JdbcBackedSessionMap"
jdbc-url = "jdbc:postgresql://localhost:5432/selenium_sessions"
jdbc-user = "seluser"
jdbc-password = "seluser"
```

*Note:* If you plan to use an existing PostGreSQL DB instance, then replace `localhost:5432` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed Grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Sessions Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

```yaml
version: '3.8'
services:
  redis:
    image: redis:bullseye
    restart: always
    ports:
      - "6379:6379"
```

We can now start our Redis container by running:

```bash
docker-compose up -d
```

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
scheme = "redis"
implementation = "org.openqa.selenium.grid.sessionmap.redis.RedisBackedSessionMap"
hostname = "localhost"
port = 6379
```

*Note:* If you plan to use an existing Redis Cache instance, then replace `localhost` and `6379` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Session Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

* At this point the current directory should contain the following files:

  * `docker-compose.yml`
  * `sessions.toml`
  * `distributed.sh`

* You can now spawn the Grid by running `distributed.sh` shell script and quickly run a test. You will notice that the Grid now stores session information into the Redis instance. You can perhaps make use of a Redis GUI such as [TablePlus](https://tableplus.com/) to see them (Make sure that you have setup a debug point in your test, because the values will get deleted as soon as the test runs to completion).

In the line which spawns a `SessionMap` on a machine:

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

* The variable names from the above script have been replaced with their actual values for clarity.
* Remember to substitute `localhost` with the actual hostname of the machine where your `Event-Bus` is running.
* The arguments being passed to `coursier` are basically the GAV (Group Artifact Version) Maven co-ordinates of:
  * [selenium-session-map-redis](https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-session-map-redis) which is needed to help us store sessions information in Redis Cache.
* `sessions.toml` is the configuration file that we created earlier.

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/elements/file_upload/
----

# File Upload

```java
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/FileUploadTest.java#L17-L19)

##### /examples/java/src/test/java/dev/selenium/elements/FileUploadTest.java

```java
package dev.selenium.elements;

import dev.selenium.BaseChromeTest;
import java.io.File;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

public class FileUploadTest extends BaseChromeTest {

  @Test
  public void fileUploadTest() {
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }
}
```

```py
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_file_upload.py#L12-L14)

##### /examples/python/tests/elements/test\_file\_upload.py

```py
import os

from selenium import webdriver
from selenium.webdriver.common.by import By


def test_uploads(driver):
    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"
```

```cs
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/FileUploadTest.cs#L21-L23)

##### /examples/dotnet/SeleniumDocs/Elements/FileUploadTest.cs

```cs
using System;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;

namespace SeleniumDocs.Elements
{
    [TestClass]
    public class FileUploadTest : BaseChromeTest
    {
        [TestMethod]
        public void Uploads()
        {
            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }
    }
}
```

```rb
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/file_upload_spec.rb#L12-L14)

##### /examples/ruby/spec/elements/file\_upload\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'File Upload' do
  let(:driver) { start_session }

  it 'uploads' do
    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    file_name = driver.find_element(id: 'uploaded-files')
    expect(file_name.text).to eq 'selenium-snapshot.png'
  end
end
```

```js
    await driver.get('https://the-internet.herokuapp.com/upload');
    // Upload snapshot
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/fileUpload.spec.js#L24-L25)

##### /examples/javascript/test/elements/fileUpload.spec.js

```js

const {Browser, By, until, Builder} = require("selenium-webdriver");
const path = require("path");
const assert = require('node:assert');


describe('File Upload Test', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async() => await driver.quit());

  it('Should be able to upload a file successfully', async function() {
    const image = path.resolve('./test/resources/selenium-snapshot.png')

    await driver.manage().setTimeouts({implicit: 5000});

    // Navigate to URL
    await driver.get('https://the-internet.herokuapp.com/upload');
    // Upload snapshot
    await driver.findElement(By.id("file-upload")).sendKeys(image);
    await driver.findElement(By.id("file-submit")).submit();

    const revealed = await driver.findElement(By.id('uploaded-files'))
    await driver.wait(until.elementIsVisible(revealed), 2000);
    const data = await driver.findElement(By.css('h3'));

    assert.equal(await data.getText(), `File Uploaded!`);
  });
});
```

[Move Code](/documentation/about/contributing/#moving-examples)

\`\`\`java import org.openqa.selenium.By import org.openqa.selenium.chrome.ChromeDriver fun main() { val driver = ChromeDriver() driver.get("https\://the-internet.herokuapp.com/upload") driver.findElement(By.id("file-upload")).sendKeys("selenium-snapshot.jpg") driver.findElement(By.id("file-submit")).submit() if(driver.pageSource.contains("File Uploaded!")) { println("file uploaded") } else{ println("file not uploaded") } } \`\`\`

Última modificação October 30, 2025: [modified link weight for file upload to come in logical order for element (#2491) (f297c0685df)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/f297c0685df60e4c7aaebca746612ee8c659a886)

----
url: https://www.selenium.dev/pt-br/documentation/grid/configuration/
----

# Configurando componentes

Leia aqui como pode configurar cada um dos componentes Grid com base em valores comuns ou específicos para o componente.

***

##### [Ajuda de configuração](/pt-br/documentation/grid/configuration/help/)

Obtenha ajuda sobre todas as opções disponíveis para configurar a Grid.

##### [Opções CLI](/pt-br/documentation/grid/configuration/cli_options/)

Todas os detalhes das opções CLI de cada componente Grid.

##### [Toml Options](/pt-br/documentation/grid/configuration/toml_options/)

Grid configuration examples using Toml files.

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/interactions/print_page/
----

# 打印页面

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L14-L17)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L12-L19)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L12-L14)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L23-L26)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L22-L29)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L18-L20)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L32-L35)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L32-L38)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L24-L26)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L41-L48)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L51-L57)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L30-L35)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L53-L57)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L61-L68)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L42-L45)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L63-L66)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L41-L48)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L49-L51)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L72-L75)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L71-L78)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L55-L57)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java#L27-L31)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.Pdf;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.PrintsPage;
import dev.selenium.BaseTest;

public class PrintsPageTest extends BaseTest{

    @BeforeEach
    public void setup() {
        ChromeOptions options = getDefaultChromeOptions();
        options.setCapability("webSocketUrl", true);
        driver = new ChromeDriver(options);
    }

    @Test
    public void PrintWithPrintsPageTest() 
    {
        driver.get("https://www.selenium.dev/");
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }

    @Test
    public void PrintWithBrowsingContextTest() 
    {
        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);
        Assertions.assertTrue(printPage.length() > 0);
    }
}
```

**BrowsingContext()**

```java
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        PrintOptions printOptions = new PrintOptions();
        String printPage = browsingContext.print(printOptions);
        Assertions.assertTrue(printPage.length() > 0);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java#L37-L41)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.Pdf;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.PrintsPage;
import dev.selenium.BaseTest;

public class PrintsPageTest extends BaseTest{

    @BeforeEach
    public void setup() {
        ChromeOptions options = getDefaultChromeOptions();
        options.setCapability("webSocketUrl", true);
        driver = new ChromeDriver(options);
    }

    @Test
    public void PrintWithPrintsPageTest() 
    {
        driver.get("https://www.selenium.dev/");
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }

    @Test
    public void PrintWithBrowsingContextTest() 
    {
        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);
        Assertions.assertTrue(printPage.length() > 0);
    }
}
```

```cs
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L81-L88)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

**print\_page()**

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    pdf = driver.print_page(print_options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_prints_page.py#L12-L14)

##### /examples/python/tests/interactions/test\_prints\_page.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_prints_page(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    pdf = driver.print_page(print_options)
    assert len(pdf) > 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

----
url: https://www.selenium.dev/ja/documentation/test_practices/testing_types/
----

# テストの種類

### 受け入れテスト

このタイプのテストは、機能またはシステムが顧客の期待と要件を満たしているかどうかを判断するために行われます。 このタイプのテストには通常、顧客の協力またはフィードバックが関与します。 下記質問に答えることで確認することができます。

> ***正しい*** 製品を作っていますか？

Webアプリケーションの場合、ユーザーの予想される動作をシミュレートすることで、 このテストの自動化をSeleniumで直接実行できます。 このシミュレーションは、このドキュメントで説明されているように、記録/再生によって、 またはサポートされているさまざまな言語によって実行できます。 注：受け入れテストは ***機能テスト*** のサブタイプであり、一部の人はこれにも言及する場合があります。

### 機能テスト

このタイプのテストは、機能またはシステムが問題なく正常に機能するかどうかを判断するために行われます。 システムをさまざまなレベルでチェックして、すべてのシナリオがカバーされていること、 およびシステムが実行すべきことを実行していることを確認します。 下記質問に答えることで確認することができます。

> 製品を ***正しく*** 作っていますか？

> For example, ***Testing that the site can handle numerous orders/users at once.***

#### ストレステスト

ストレステストは、ストレス下（またはサポートされている最大負荷以上）でアプリケーションがどの程度機能するかを確認するために行われます。

> For example, ***Testing that your ecommerce site can handle Black Friday***

> For example, ***Testing that your new search bar doesn’t break the other buttons on the menu***

最終更新 March 9, 2025: [Added more examples to testing type descriptions (#1970)\[deploy site\] (9f7a22b43fc)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/9f7a22b43fcd2d4158aa007d622c9a6d7bf4ca6b)

----
url: https://www.selenium.dev/zh-cn/_print/documentation/grid/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/grid/).

# Grid

要在多台计算机上并行运行测试吗? 那么, Grid正是为你准备的.

* 1: [Selenium Grid快速起步](#pg-9c9914771fbff5e2210e763c63e98094)
* 2: [什么时候应该使用Grid](#pg-e2c3220801c7eb142b84fad49bc5b858)
* 3: [服务网格的组件](#pg-9c8ff9881742928aaf1544b3c5de86a1)
* 4: [配置组件](#pg-37e2305b972ad696e0a785d1dbaeff39)
* * 4.1: [配置帮助](#pg-93fa084268206a9aa52621f65987bf76)
  * 4.2: [CLI 选项](#pg-4eef2fd47f890b3bd4246fa0b9f9e349)
  * 4.3: [Toml配置选项](#pg-9908b5b7f21b6519e90ed597e0ccd1e4)
  5: [Grid架构](#pg-95174e92571847894c6295f2bd10b6bc)
* 6: [高级功能](#pg-9586edf2b9ce7e57a4873d12c1cb49bf)
  * 6.1: [可观测性](#pg-58fa36fce0115e0cac81fa0157f35027)
  * 6.2: [GraphQL查询支持](#pg-5accfc3d64bfa8a3f37b3a48872e2e2d)
  * 6.3: [Grid端点](#pg-d465290d42e97f4e216fb472ad892ff3)
  * 6.4: [自定义Node](#pg-5072bf299379dd6eab5265a6c5e77cdf)
  * 6.5: [External datastore](#pg-a39cd5d25428eb436570d7f73037fed5)

Selenium Grid 允许通过将客户端发送的命令路由到远程浏览器实例来在远程机器上执行 WebDriver 脚本。

Grid 的目标:

* 提供一种在多台机器上并行运行测试的简单方法
* 允许在不同的浏览器版本上进行测试
* 启用跨平台测试

感兴趣? 通过以下部分了解Grid的工作原理, 以及如何设置自己的.

# 1 - Selenium Grid快速起步

     * [Selenium Manager](https://www.selenium.dev/zh-cn/documentation/selenium_manager/) will configure the drivers automatically if you add `--selenium-manager true`.
     * [需要已经安装并配置了 PATH 环境变量](https://www.selenium.dev/zh-cn/documentation/webdriver/troubleshooting/errors/driver_location/#3-path-环境变量)

```shell
java -jar selenium-server-<version>.jar standalone
```

```shell
java -jar selenium-server-<version>.jar hub
```

默认情况下，服务器将在 <http://localhost:4444> 上监听`RemoteWebDriver`请求。

#### Node

在启动时，**Node**将从系统的[`PATH`](https://www.selenium.dev/zh-cn/documentation/webdriver/troubleshooting/errors/driver_location/#3-path-环境变量)中检测可用的驱动程序。

以下命令假设**Node**正在运行的机器与**Hub**在同一台机器上。

```shell
java -jar selenium-server-<version>.jar node
```

##### 同一台机器上的多个Node

**Node** 1

```shell
java -jar selenium-server-<version>.jar node --port 5555
```

**Node** 2

```shell
java -jar selenium-server-<version>.jar node --port 6666
```

##### 不同机器上的Node和Hub

**Hub**和**Nodes**通过HTTP和[**事件总线**](https://www.selenium.dev/zh-cn/documentation/grid/components/#event-bus)（**事件总线**位于**Hub**内部）进行通信。

**Node**通过事件总线向**Hub**发送消息以开始注册过程。当**Hub**收到消息时，通过HTTP与**Node**联系以确认其存在。

要成功将**Node**注册到**Hub**，重要的是要在**Hub**机器上公开**事件总线**端口（默认为4442和4443）。这也适用于**Node**端口。有了这个，**Hub**和**Node**都能够通信。

如果**Hub**使用默认端口，则可以使用 `--hub` 注册**Node**。

```shell
java -jar selenium-server-<version>.jar node --hub http://<hub-ip>:4444
```

当**Hub**未使用默认端口时，需要使用`--publish-events`和`--subscribe-events`。

例如，如果**Hub**使用端口8886、8887和8888。

```shell
java -jar selenium-server-<version>.jar hub --publish-events tcp://<hub-ip>:8886 --subscribe-events tcp://<hub-ip>:8887 --port 8888
```

**Node**需要使用这些端口才能成功注册。

```shell
java -jar selenium-server-<version>.jar node --publish-events tcp://<hub-ip>:8886 --subscribe-events tcp://<hub-ip>:8887
```

### 分部署部署（Distributed）

在使用分布式Grid时，每个组件都需要单独启动，并且理想情况下应该在不同的机器上。

重要的是要正确暴露所有端口，以允许所有组件之间的流畅通信。

1. **事件总线（Event Bus）**: 使不同网格组件之间的内部通信成为可能。

默认端口为：`4442`、`4443`和`5557`。

```shell
java -jar selenium-server-<version>.jar event-bus --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --port 5557
```

2. **新会话队列（New Session Queue）**: 将新的会话请求添加到一个队列中，Distributor将查询该队列。

默认端口为`5559`。

```shell
java -jar selenium-server-<version>.jar sessionqueue --port 5559
```

3. **会话映射（Session Map）**: 将会话ID映射到运行该会话的节点。

默认**会话映射**端口为`5556`。**会话映射**与**事件总线**进行交互。

```shell
java -jar selenium-server-<version>.jar sessions --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --port 5556
```

4. **分配器（Distributor）**: 查询新 **会话队列（New Session Queue）** 以获取新会话请求，并在能力匹配时将其分配给 **Node**。 **Nodes** 注册到 **Distributor** 的方式与在 **Hub/Node** 网格中注册到 **Hub** 相同。

默认**分配器**端口为`5553`。**分配器** 与 **新会话队列**、**会话映射**、**事件总线** 和 **Node(s)** 进行交互。

```shell
java -jar selenium-server-<version>.jar distributor --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --sessions http://<sessions-ip>:5556 --sessionqueue http://<new-session-queue-ip>:5559 --port 5553 --bind-bus false
```

5. **路由器（Router）**: 将新会话请求重定向到队列，并将正在运行的会话请求重定向到运行该会话的**Node**。

默认**路由器**端口为`4444`。**路由器** 与 **新会话队列**、**会话映射**和**分配器** 进行交互。

```shell
java -jar selenium-server-<version>.jar router --sessions http://<sessions-ip>:5556 --distributor http://<distributor-ip>:5553 --sessionqueue http://<new-session-queue-ip>:5559 --port 4444
```

6. **Node(s)**

默认 **Node** 端口是 `5555`.

```shell
java -jar selenium-server-<version>.jar node --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443
```

## 测试中的 Metadata

向测试中添加 `Metadata` 并通过[GraphQL](https://www.selenium.dev/zh-cn/documentation/grid/advanced_features/graphql_support/)进行消费，或通过 `Selenium Grid UI` 可视化其部分内容（例如`se:name`）。

可以通过在 `capability` 前加上 `se:` 来添加元数据。以下是一个Java的快速示例。

```java
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setCapability("browserVersion", "100");
chromeOptions.setCapability("platformName", "Windows");
// Showing a test name instead of the session id in the Grid UI
chromeOptions.setCapability("se:name", "My simple test"); 
// Other type of metadata can be seen in the Grid UI by clicking on the 
// session info or via GraphQL
chromeOptions.setCapability("se:sampleMetadata", "Sample metadata value"); 
WebDriver driver = new RemoteWebDriver(new URL("http://gridUrl:4444"), chromeOptions);
driver.get("http://www.google.com");
driver.quit();
```

```bash
java -Dwebdriver.http.factory=jdk-http-client -jar selenium-server-<version>.jar --ext selenium-http-jdk-client-<version>.jar standalone
```

下载 `selenium-http-jdk-client` jar 文件的替代方法是使用 [Coursier](https://get-coursier.io/docs/cli-installation)。

```bash
java -Dwebdriver.http.factory=jdk-http-client -jar selenium-server-<version>.jar --ext $(coursier fetch -p org.seleniumhq.selenium:selenium-http-jdk-client:<version>) standalone
```

# 2 - 什么时候应该使用Grid

```
   15      *       45s        /        1        =      11m 15s   // 没有Grid
   15      *       45s        /        5        =      2m 15s    // 5节点的Grid
   15      *       45s        /        15       =      45s       // 15节点的Grid
  100      *       120s       /        15       =      13m 20s   // 如果没有Grid, 需要3个多小时
```

在测试案例执行时，`Grid` 会按照测试配置将测试分配到相应的浏览器上运行.

即使对于比较复杂的 `Selenium` 测试案例，这样的配置也可以极大地加快执行时间.

`Selenium Grid` 是 `Selenium` 项目中的重要组成部分，由同一团队的核心Selenium开发人员并行维护. 由于意识到测试执行速度的重要性，`Grid` 自设计之初就成为 `Selenium` 项目的关键部分.

# 3 - 服务网格的组件

# 4 - 配置组件

在这里，您可以看到如何根据公共配置值和特定于组件的配置值分别配置每个网格组件.

# 4.1 - 配置帮助

```shell
java -jar selenium-server-<version>.jar info config
```

### 安全

获取构建网格服务器的详细信息, 用于安全通信和节点注册.

```shell
java -jar selenium-server-<version>.jar info security
```

### 会话表配置

默认情况下, 网格使用本地会话表来存储会话信息. 网格支持额外的存储选项, 比如Redis和JDBC-SQL支持的数据库. 要设置不同的会话存储, 请使用以下命令获取设置步骤:

```shell
java -jar selenium-server-<version>.jar info sessionmap
```

### 基于OpenTelemetry和Jaeger的追踪配置

默认情况下, 追踪是启用的. 要通过Jaeger导出追踪并将其可视化, 请使用以下命令进行说明:

```shell
java -jar selenium-server-<version>.jar info tracing
```

## 列出Selenium网格的命令

```shell
java -jar selenium-server-<version>.jar --config-help
```

上述命令将显示所有可用的命令及其描述.

## 组件帮助命令

在Selenium后面键入–help的配置选项, 以获取特定组件的配置信息.

### Standalone

```shell
java -jar selenium-server-<version>.jar standalone --help
```

### Hub

```shell
java -jar selenium-server-<version>.jar hub --help
```

### Sessions

```shell
java -jar selenium-server-<version>.jar sessions --help
```

### 队列器

```shell
java -jar selenium-server-<version>.jar sessionqueue --help
```

### Distributor

```shell
java -jar selenium-server-<version>.jar distributor --help
```

### Router

```shell
java -jar selenium-server-<version>.jar router --help
```

### Node

```shell
java -jar selenium-server-<version>.jar node --help
```

# 4.2 - CLI 选项

所有网格组件配置CLI选项的详细信息.

**Page being translated from English to Chinese. Do you speak Chinese? Help us to translate it by sending us pull requests!

Different sections are available to configure a Grid. Each section has options can be configured through command line arguments.

A complete description of the component to section mapping can be seen below.

Note that this documentation could be outdated if an option was modified or added but has not been documented yet. In case you bump into this situation, please check the [“Config help”](https://www.selenium.dev/zh-cn/documentation/grid/configuration/help/) section and feel free to send us a pull request updating this page.

## Sections

|                               | Standalone | Hub | Node | Distributor | Router | Sessions | SessionQueue |
| ----------------------------- | ---------- | --- | ---- | ----------- | ------ | -------- | ------------ |
| [Distributor](#distributor)   | **         | **  |      | **          | **     |          |              |
| [Docker](#docker)             | **         |     | **   |             |        |          |              |
| [Events](#events)             |            | **  | **   | **          |        | **       | **           |
| [Logging](#logging)           | **         | **  | **   | **          | **     | **       | **           |
| [Network](#network)           | **         | **  |      |             | **     |          |              |
| [Node](#node)                 | **         |     | **   |             |        |          |              |
| [Router](#router)             | **         | **  |      |             | **     |          |              |
| [Relay](#relay)               | **         |     | **   |             |        |          |              |
| [Server](#server)             | **         | **  | **   | **          | **     | **       | **           |
| [SessionQueue](#sessionqueue) | **         | **  |      | **          | **     |          | **           |
| [Sessions](#sessions)         |            |     |      | **          | **     | **       |              |

### Distributor

| Option                         | Type    | Value/Example                                                       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ------------------------------ | ------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--healthcheck-interval`       | int     | `120`                                                               | How often, in seconds, will the health check run for all Nodes. This ensures the server can ping all the Nodes successfully.                                                                                                                                                                                                                                                                                                                        |
| `--distributor`                | uri     | `http://localhost:5553`                                             | Url of the distributor.                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `--distributor-host`           | string  | `localhost`                                                         | Host on which the distributor is listening.                                                                                                                                                                                                                                                                                                                                                                                                         |
| `--distributor-implementation` | string  | `org.openqa.selenium.grid.distributor.local.LocalDistributor`       | Full class name of non-default distributor implementation                                                                                                                                                                                                                                                                                                                                                                                           |
| `--distributor-port`           | int     | `5553`                                                              | Port on which the distributor is listening.                                                                                                                                                                                                                                                                                                                                                                                                         |
| `--reject-unsupported-caps`    | boolean | `false`                                                             | Allow the Distributor to reject a request immediately if the Grid does not support the requested capability. Rejecting requests immediately is suitable for a Grid setup that does not spin up Nodes on demand.                                                                                                                                                                                                                                     |
| `--slot-matcher`               | string  | `org.openqa.selenium.grid.data.DefaultSlotMatcher`                  | Full class name of non-default slot matcher to use. This is used to determine whether a Node can support a particular session.                                                                                                                                                                                                                                                                                                                      |
| `--slot-selector`              | string  | `org.openqa.selenium.grid.distributor.selector.DefaultSlotSelector` | Full class name of non-default slot selector. This is used to select a slot in a Node once the Node has been matched.                                                                                                                                                                                                                                                                                                                               |
| `--newsession-threadpool-size` | int     | `24`                                                                | The Distributor uses a fixed-sized thread pool to create new sessions as it consumes new session requests from the queue. This allows configuring the size of the thread pool. The default value is no. of available processors \* 3. Note: If the no. of threads is way greater than the available processors it will not always increase the performance. A high number of threads causes more context switching which is an expensive operation. |
| `--purge-nodes-interval`       | int     | `30`                                                                | How often, in seconds, will the Distributor purge Nodes that have been down for a while. This is calculated based on the heartbeat received from a particular node.                                                                                                                                                                                                                                                                                 |

### Docker

| Option                      | Type      | Value/Example                                                     | Description                                                                                                                                                                                                                                                                                 |
| --------------------------- | --------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--docker-assets-path`      | string    | `/opt/selenium/assets`                                            | Absolute path where assets will be stored                                                                                                                                                                                                                                                   |
| `--docker-`                 | string\[] | `selenium/standalone-firefox:latest '{"browserName": "firefox"}'` | Docker configs which map image name to stereotype capabilities (example \`-D selenium/standalone-firefox:latest ‘{“browserName”: “firefox”}’)                                                                                                                                               |
| `--docker-devices`          | string\[] | `/dev/kvm:/dev/kvm`                                               | Exposes devices to a container. Each device mapping declaration must have at least the path of the device in both host and container separated by a colon like in this example: /device/path/in/host:/device/path/in/container                                                              |
| `--docker-host`             | string    | `localhost`                                                       | Host name where the Docker daemon is running                                                                                                                                                                                                                                                |
| `--docker-port`             | int       | `2375`                                                            | Port where the Docker daemon is running                                                                                                                                                                                                                                                     |
| `--docker-url`              | string    | `http://localhost:2375`                                           | URL for connecting to the Docker daemon                                                                                                                                                                                                                                                     |
| `--docker-video-image`      | string    | `selenium/video:latest`                                           | Docker image to be used when video recording is enabled                                                                                                                                                                                                                                     |
| `--docker-host-config-keys` | string\[] | `Dns DnsOptions DnsSearch ExtraHosts Binds`                       | Specify which docker host configuration keys should be passed to browser containers. Keys name can be found in the Docker API [documentation](https://docs.docker.com/engine/api/v1.41/#tag/Container/operation/ContainerCreate), or by running `docker inspect` the node-docker container. |

### Events

| Option                    | Type    | Value/Example                                      | Description                                                                                                                                                                                                                                                                         |
| ------------------------- | ------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--bind-bus`              | boolean | `false`                                            | Whether the connection string should be bound or connected. When true, the component will be bound to the Event Bus (as in the Event Bus will also be started by the component, typically by the Distributor and the Hub). When false, the component will connect to the Event Bus. |
| `--events-implementation` | string  | `org.openqa.selenium.events.zeromq.ZeroMqEventBus` | Full class name of non-default event bus implementation                                                                                                                                                                                                                             |
| `--publish-events`        | string  | `tcp://*:4442`                                     | Connection string for publishing events to the event bus                                                                                                                                                                                                                            |
| `--subscribe-events`      | string  | `tcp://*:4443`                                     | Connection string for subscribing to events from the event bus                                                                                                                                                                                                                      |

### Logging

| Option                   | Type    | Value/Example                                                                                                                                              | Description                                                                                                                                                            |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--http-logs`            | boolean | `false`                                                                                                                                                    | Enable http logging. Tracing should be enabled to log http logs.                                                                                                       |
| `--log-encoding`         | string  | `UTF-8`                                                                                                                                                    | Log encoding                                                                                                                                                           |
| `--log`                  | string  | Windows path example : `'\path\to\file\gridlog.log'` or `'C:\path\path\to\file\gridlog.log'` Linux/Unix/MacOS path example : `'/path/to/file/gridlog.log'` | File to write out logs. Ensure the file path is compatible with the operating system’s file path.                                                                      |
| `--log-level`            | string  | `“INFO”`                                                                                                                                                   | Log level. Default logging level is INFO. Log levels are described here <https://docs.oracle.com/en/java/javase/11/docs/api/java.logging/java/util/logging/Level.html> |
| `--plain-logs`           | boolean | `true`                                                                                                                                                     | Use plain log lines                                                                                                                                                    |
| `--structured-logs`      | boolean | `false`                                                                                                                                                    | Use structured logs                                                                                                                                                    |
| `--tracing`              | boolean | `true`                                                                                                                                                     | Enable trace collection                                                                                                                                                |
| `--log-timestamp-format` | string  | `HH:mm:ss.SSS`                                                                                                                                             | Allows the configure log timestamp format                                                                                                                              |

### Network

| Option           | Type    | Value/Example | Description                                                                                                          |
| ---------------- | ------- | ------------- | -------------------------------------------------------------------------------------------------------------------- |
| `--relax-checks` | boolean | `false`       | Relax checks on origin header and content type of incoming requests, in contravention of strict W3C spec compliance. |

### Node

| Option                           | Type      | Value/Example                                                                                                                                                                                                                                                              | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |   |
| -------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - |
| `--detect-drivers`               | boolean   | `true`                                                                                                                                                                                                                                                                     | Autodetect which drivers are available on the current system, and add them to the Node.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |   |
| `--driver-configuration`         | string\[] | `display-name="Firefox Nightly" max-sessions=2 webdriver-path="/usr/local/bin/geckodriver" stereotype="{\"browserName\": \"firefox\", \"browserVersion\": \"86\", \"moz:firefoxOptions\": {\"binary\":\"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"` | List of configured drivers a Node supports. It is recommended to provide this type of configuration through a toml config file to improve readability                                                                                                                                                                                                                                                                                                                                                                                                                                                   |   |
| `--driver-factory`               | string\[] | `org.openqa.selenium.example.LynxDriverFactory '{"browserName": "lynx"}'`                                                                                                                                                                                                  | Mapping of fully qualified class name to a browser configuration that this matches against.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |   |
| `--driver-implementation`        | string\[] | `"firefox"`                                                                                                                                                                                                                                                                | Drivers that should be checked. If specified, will skip autoconfiguration.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |   |
| `--node-implementation`          | string    | `"org.openqa.selenium.grid.node.local.LocalNodeFactory"`                                                                                                                                                                                                                   | Full classname of non-default Node implementation. This is used to manage a session’s lifecycle.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |   |
| `--grid-url`                     | string    | `https://grid.example.com`                                                                                                                                                                                                                                                 | Public URL of the Grid as a whole (typically the address of the Hub or the Router)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |   |
| `--heartbeat-period`             | int       | `60`                                                                                                                                                                                                                                                                       | How often, in seconds, will the Node send heartbeat events to the Distributor to inform it that the Node is up.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |   |
| `--max-sessions`                 | int       | `8`                                                                                                                                                                                                                                                                        | Maximum number of concurrent sessions. Default value is the number of available processors.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |   |
| `--override-max-sessions`        | boolean   | `false`                                                                                                                                                                                                                                                                    | The # of available processors is the recommended max sessions value (1 browser session per processor). Setting this flag to true allows the recommended max value to be overwritten. Session stability and reliability might suffer as the host could run out of resources.                                                                                                                                                                                                                                                                                                                             |   |
| `--register-cycle`               | int       | `10`                                                                                                                                                                                                                                                                       | How often, in seconds, the Node will try to register itself for the first time to the Distributor.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |   |
| `--register-period`              | int       | `120`                                                                                                                                                                                                                                                                      | How long, in seconds, will the Node try to register to the Distributor for the first time. After this period is completed, the Node will not attempt to register again.                                                                                                                                                                                                                                                                                                                                                                                                                                 |   |
| `--session-timeout`              | int       | `300`                                                                                                                                                                                                                                                                      | Let X be the session-timeout in seconds. The Node will automatically kill a session that has not had any activity in the last X seconds. This will release the slot for other tests.                                                                                                                                                                                                                                                                                                                                                                                                                    |   |
| `--vnc-env-var`                  | string\[] | `SE_START_XVFB SE_START_VNC SE_START_NO_VNC`                                                                                                                                                                                                                               | Environment variable to check in order to determine if a vnc stream is available or not.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |   |
| `--no-vnc-port`                  | int       | `7900`                                                                                                                                                                                                                                                                     | If VNC is available, sets the port where the local noVNC stream can be obtained                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |   |
| `--drain-after-session-count`    | int       | `1`                                                                                                                                                                                                                                                                        | Drain and shutdown the Node after X sessions have been executed. Useful for environments like Kubernetes. A value higher than zero enables this feature.                                                                                                                                                                                                                                                                                                                                                                                                                                                |   |
| `--hub`                          | string    | `http://localhost:4444`                                                                                                                                                                                                                                                    | The address of the Hub in a Hub-and-Node configuration. Can be a hostname or IP address (`hostname`), in which case the Hub will be assumed to be `http://hostname:4444`, the `--grid-url` will be the same `--publish-events` will be `tcp://hostname:4442` and `--subscribe-events` will be `tcp://hostname:4443`. If `hostname` contains a port number, that will be used for `--grid-url` but the URIs for the event bus will remain the same. Any of these default values may be overridden but setting the correct flags. If the hostname has a protocol (such as `https`) that will be used too. |   |
| `--enable-cdp`                   | boolean   | `true`                                                                                                                                                                                                                                                                     | Enable CDP proxying in Grid. A Grid admin can disable CDP if the network does not allow websockets. True by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |   |
| `--enable-managed-downloads`     | boolean   | `false`                                                                                                                                                                                                                                                                    | This causes the Node to auto manage files downloaded for a given session on the Node.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |   |
| `--selenium-manager`             | boolean   | `false`                                                                                                                                                                                                                                                                    | When drivers are not available on the current system, use Selenium Manager. False by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |   |
| `--connection-limit-per-session` | int       | `10`                                                                                                                                                                                                                                                                       | Let X be the maximum number of websocket connections per session.This will ensure one session is not able to exhaust the connection limit of the host.                                                                                                                                                                                                                                                                                                                                                                                                                                                  |   |

### Relay

| Option                       | Type      | Value/Example                                                                                                     | Description                                                                                                                                                              |
| ---------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--service-url`              | string    | `http://localhost:4723`                                                                                           | URL for connecting to the service that supports WebDriver commands like an Appium server or a cloud service.                                                             |
| `--service-host`             | string    | `localhost`                                                                                                       | Host name where the service that supports WebDriver commands is running                                                                                                  |
| `--service-port`             | int       | `4723`                                                                                                            | Port where the service that supports WebDriver commands is running                                                                                                       |
| `--service-status-endpoint`  | string    | `/status`                                                                                                         | Optional, endpoint to query the WebDriver service status, an HTTP 200 response is expected                                                                               |
| `--service-protocol-version` | string    | `HTTP/1.1`                                                                                                        | Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status                                                          |
| `--service-configuration`    | string\[] | `max-sessions=2 stereotype='{"browserName": "safari", "platformName": "iOS", "appium:platformVersion": "14.5"}}'` | Configuration for the service where calls will be relayed to. It is recommended to provide this type of configuration through a toml config file to improve readability. |

### Router

| Option         | Type    | Value/Example              | Description                                                                                                         |
| -------------- | ------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `--password`   | string  | `myStrongPassword`         | Password clients must use to connect to the server. Both this and the username need to be set in order to be used.  |
| `--username`   | string  | `admin`                    | User name clients must use to connect to the server. Both this and the password need to be set in order to be used. |
| `--sub-path`   | string  | `my_company/selenium_grid` | A sub-path that should be considered for all user facing routes on the Hub/Router/Standalone.                       |
| `--disable-ui` | boolean | `true`                     | Disable the Grid UI.                                                                                                |

### Server

| Option                | Type    | Value/Example        | Description                                                                                                                                                                                                                                                                           |
| --------------------- | ------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--allow-cors`        | boolean | `true`               | Whether the Selenium server should allow web browser connections from any host                                                                                                                                                                                                        |
| `--host`              | string  | `localhost`          | Server IP or hostname: usually determined automatically.                                                                                                                                                                                                                              |
| `--bind-host`         | boolean | `true`               | Whether the server should bind to the host address/name, or only use it to" report its reachable url. Helpful in complex network topologies where the server cannot report itself with the current IP/hostname but rather an external IP or hostname (e.g. inside a Docker container) |
| `--https-certificate` | path    | `/path/to/cert.pem`  | Server certificate for https. Get more detailed information by running “java -jar selenium-server.jar info security”                                                                                                                                                                  |
| `--https-private-key` | path    | `/path/to/key.pkcs8` | Private key for https. Get more detailed information by running “java -jar selenium-server.jar info security”                                                                                                                                                                         |
| `--max-threads`       | int     | `24`                 | Maximum number of listener threads. Default value is: (available processors) \* 3.                                                                                                                                                                                                    |
| `--port`              | int     | `4444`               | Port to listen on. There is no default as this parameter is used by different components, for example, Router/Hub/Standalone will use 4444 and Node will use 5555.                                                                                                                    |

### SessionQueue

| Option                      | Type   | Value/Example           | Description                                                                                                                                               |
| --------------------------- | ------ | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--sessionqueue`            | uri    | `http://localhost:1237` | Address of the session queue server.                                                                                                                      |
| `-sessionqueue-host`        | string | `localhost`             | Host on which the session queue server is listening.                                                                                                      |
| `--sessionqueue-port`       | int    | `1234`                  | Port on which the session queue server is listening.                                                                                                      |
| `--session-request-timeout` | int    | `300`                   | Timeout in seconds. A new incoming session request is added to the queue. Requests sitting in the queue for longer than the configured time will timeout. |
| `--session-retry-interval`  | int    | `5`                     | Retry interval in seconds. If all slots are busy, new session request will be retried after the given interval.                                           |
| `--maximum-response-delay`  | int    | `8`                     | How often, in seconds, will the the SessionQueue response in case there is no data, to reduce the http requests while polling for new session requests.   |

### Sessions

| Option            | Type   | Value/Example           | Description                                        |
| ----------------- | ------ | ----------------------- | -------------------------------------------------- |
| `--sessions`      | uri    | `http://localhost:1234` | Address of the session map server.                 |
| `--sessions-host` | string | `localhost`             | Host on which the session map server is listening. |
| `--sessions-port` | int    | `1234`                  | Port on which the session map server is listening. |

## Configuration examples

All the options mentioned above can be used when starting the Grid components. They are a good way of exploring the Grid options, and trying out values to find a suitable configuration.

We recommend the use of [Toml files](https://www.selenium.dev/zh-cn/documentation/grid/configuration/toml_options/) to configure a Grid. Configuration files improve readability, and you can also check them in source control.

When needed, you can combine a Toml file configuration with CLI arguments.

### Command-line flags

To pass config options as command-line flags, identify the valid options for the component and follow the template below.

```
java -jar selenium-server-<version>.jar <component> --<option> value
```

#### Standalone, setting max sessions and main port

```
java -jar selenium-server-<version>.jar standalone --max-sessions 4 --port 4444
```

#### Hub, setting a new session request timeout, a main port, and disabling tracing

```
java -jar selenium-server-<version>.jar hub --session-request-timeout 500 --port 3333 --tracing false
```

#### Node, with 4 max sessions, with debug(fine) log, 7777 as port, and only with Firefox and Edge

```
java -jar selenium-server-<version>.jar node --max-sessions 4 --log-level "fine" --port 7777 --driver-implementation "firefox" --driver-implementation "edge"
```

#### Distributor, setting Session Map server url, Session Queue server url, and disabling bus

```
java -jar selenium-server-<version>.jar distributor --sessions http://localhost:5556 --sessionqueue http://localhost:5559 --bind-bus false
```

#### Setting custom capabilities for matching specific Nodes

**Important:** Custom capabilities need to be set in the configuration in all Nodes. They also need to be included always in every session request.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node A with custom cap set to `true`

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":true}' --port 6161
```

##### Start the Node B with custom cap set to `false`

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":false}' --port 6262
```

##### Matching Node A

```java
ChromeOptions options = new ChromeOptions();
options.setCapability("gsg:customcap", true);
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

Set the custom capability to `false` in order to match the Node B.

#### Enabling Managed downloads by the Node

At times a test may need to access files that were downloaded by it on the Node. To retrieve such files, following can be done.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node with manage downloads enabled

```
java -jar selenium-server-<version>.jar node --enable-managed-downloads true
```

##### Set the capability at the test level

Tests that want to use this feature should set the capability `"se:downloadsEnabled"`to `true`

```java
options.setCapability("se:downloadsEnabled", true);
```

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

In the response the list of file names appear under the key `names`.

##### Dowloading a file:

* The endpoint to `POST` from is `/session/<sessionId>/se/files` with a payload of the form `{"name": "fileNameGoesHere}`
* The session needs to be active in order for the command to work.
* The raw response looks like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "Base64EncodedStringContentsOfDownloadedFileAsZipGoesHere"
  }
}
```

* The response blob contains two keys,

  * `filename` - The file name that was downloaded.
  * `contents` - Base64 encoded zipped contents of the file.

* The file contents are Base64 encoded and they need to be unzipped.

##### List files that can be downloaded

The below mentioned `curl` example can be used to list all the files that were downloaded by the current session in the Node, and which can be retrieved locally.

```bash
curl -X GET "http://localhost:4444/session/90c0149a-2e75-424d-857a-e78734943d4c/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

##### Retrieve a downloaded file

Assuming the downloaded file is named `Red-blue-green-channel.jpg`, and using `curl`, the file could be downloaded with the following command:

```bash
curl -H "Accept: application/json" \
-H "Content-Type: application/json; charset=utf-8" \
-X POST -d '{"name":"Red-blue-green-channel.jpg"}' \
"http://localhost:4444/session/18033434-fa4f-4d11-a7df-9e6d75920e19/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "UEsDBBQACAgIAJpagVYAAAAAAAAAAAAAAAAaAAAAUmVkLWJsAAAAAAAAAAAAUmVkLWJsdWUtZ3JlZW4tY2hhbm5lbC5qcGdQSwUGAAAAAAEAAQBIAAAAcNkAAAAA"
  }
}
```

##### Complete sample code in Java

Below is an example in Java that does the following:

* Sets the capability to indicate that the test requires automatic managing of downloaded files.
* Triggers a file download via a browser.
* Lists the files that are available for retrieval from the remote node (These are essentially files that were downloaded in the current session)
* Picks one file and downloads the file from the remote node to the local machine.

```java
import com.google.common.collect.ImmutableMap;

import org.openqa.selenium.By;
import org.openqa.selenium.io.Zip;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.io.File;
import java.net.URL;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import static org.openqa.selenium.remote.http.Contents.asJson;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.HttpMethod.GET;
import static org.openqa.selenium.remote.http.HttpMethod.POST;

public class DownloadsSample {

  public static void main(String[] args) throws Exception {
    // Assuming the Grid is running locally.
    URL gridUrl = new URL("http://localhost:4444");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("se:downloadsEnabled", true);
    RemoteWebDriver driver = new RemoteWebDriver(gridUrl, options);
    try {
      demoFileDownloads(driver, gridUrl);
    } finally {
      driver.quit();
    }
  }

	private static void demoFileDownloads(RemoteWebDriver driver, URL gridUrl) throws Exception {
		driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
		// Download the two available files on the page
		driver.findElement(By.id("file-1")).click();
		driver.findElement(By.id("file-2")).click();

		// The download happens in a remote Node, which makes it difficult to know when the file
		// has been completely downloaded. For demonstration purposes, this example uses a
		// 10-second sleep which should be enough time for a file to be downloaded.
		// We strongly recommend to avoid hardcoded sleeps, and ideally, to modify your
		// application under test, so it offers a way to know when the file has been completely
		// downloaded.
		TimeUnit.SECONDS.sleep(10);

		//This is the endpoint which will provide us with list of files to download and also to
		//let us download a specific file.
		String downloadsEndpoint = String.format("/session/%s/se/files", driver.getSessionId());

		String fileToDownload;

		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To list all files that are were downloaded on the remote node for the current session
			// we trigger GET request.
			HttpRequest request = new HttpRequest(GET, downloadsEndpoint);
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			@SuppressWarnings("unchecked")
			List<String> names = (List<String>) value.get("names");
			// Let's say there were "n" files downloaded for the current session, we would like
			// to retrieve ONLY the first file.
			fileToDownload = names.get(0);
		}

		// Now, let's download the file
		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To retrieve a specific file from one or more files that were downloaded by the current session
			// on a remote node, we use a POST request.
			HttpRequest request = new HttpRequest(POST, downloadsEndpoint);
			request.setContent(asJson(ImmutableMap.of("name", fileToDownload)));
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			// The returned map would contain 2 keys,
			// filename - This represents the name of the file (same as what was provided by the test)
			// contents - Base64 encoded String which contains the zipped file.
			String zippedContents = value.get("contents").toString();
			// The file contents would always be a zip file and has to be unzipped.
			File downloadDir = Zip.unzipToTempDir(zippedContents, "download", "");
			// Read the file contents
			File downloadedFile = Optional.ofNullable(downloadDir.listFiles()).orElse(new File[]{})[0];
			String fileContent = String.join("", Files.readAllLines(downloadedFile.toPath()));
			System.out.println("The file which was "
					+ "downloaded in the node is now available in the directory: "
					+ downloadDir.getAbsolutePath() + " and has the contents: " + fileContent);
		}
	}


}
```

# 4.3 - Toml配置选项

```toml
[section1]
option1="value"

[section2]
option2=["value1","value2"]
option3=true
```

下面是一些使用Toml文件配置的 Grid组件示例, 该组件可以 从下面的方式开始:

```
java -jar selenium-server-<version>.jar <component> --config /path/to/file/<file-name>.toml
```

### 单机模式

单机服务器, 在端口4449上运行, 新会话请求超时500秒.

```toml
[server]
port = 4449

[sessionqueue]
session-request-timeout = 500
```

### 特定浏览器和最大会话数限制

默认情况下仅启用Firefox 和Chrome的单机服务器或节点.

```toml
[node]
drivers = ["chrome", "firefox"]
max-sessions = 3
```

### 配置和定制驱动程序

具有定制驱动程序的单机或节点服务器, 允许使用Firefox试用或者每日构建的功能, 并且有不同的浏览器版本.

```toml
[node]
detect-drivers = false
[[node.driver-configuration]]
max-sessions = 100
display-name = "Firefox Nightly"
stereotype = "{\"browserName\": \"firefox\", \"browserVersion\": \"93\", \"platformName\": \"MAC\", \"moz:firefoxOptions\": {\"binary\": \"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"
[[node.driver-configuration]]
display-name = "Chrome Beta"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"94\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta\"}}"
[[node.driver-configuration]]
display-name = "Chrome Dev"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"95\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev\"}}"
webdriver-executable = '/path/to/chromedriver/95/chromedriver'
```

### 带Docker的单机或节点

单机或节点服务器能够在Docker容器中运行每个新会话. 禁用驱动程序检测, 则最多有2个并发会话. 原型配置需要映射一个Docker映像, Docker的守护进程需要通过http/tcp公开. 此外, 可以通过 `devices` 属性定义在主机上可访问的哪些设备文件将在容器中可用. 有关 docker 设备映射如何工作的更多信息, 请参阅 [docker](https://docs.docker.com/engine/reference/commandline/run/#add-host-device-to-container---device) 文档.

```toml
[node]
detect-drivers = false
max-sessions = 2

[docker]
configs = [
    "selenium/standalone-chrome:93.0", "{\"browserName\": \"chrome\", \"browserVersion\": \"91\"}", 
    "selenium/standalone-firefox:92.0", "{\"browserName\": \"firefox\", \"browserVersion\": \"92\"}"
]
#Optionally define all device files that should be mapped to docker containers
#devices = [
#    "/dev/kvm:/dev/kvm"
#]
url = "http://localhost:2375"
video-image = "selenium/video:latest"
```

### 将命令中继到支持WebDriver的服务端点

连接到支持WebDriver外部服务 的Selenium Grid非常有用. 这种服务的一个例子可以是 云提供商或Appium服务器. 这样, Grid可以实现对本地不存在的平台和版本的更多覆盖.

下面是一个将Appium服务器连接到Grid的示例.

```toml
[node]
detect-drivers = false

[relay]
# Default Appium/Cloud server endpoint
url = "http://localhost:4723/wd/hub"
status-endpoint = "/status"
# Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status (e.g. HTTP/1.1, HTTP/2)
protocol-version = "HTTP/1.1"
# Stereotypes supported by the service. The initial number is "max-sessions", and will allocate 
# that many test slots to that particular configuration
configs = [
  "5", "{\"browserName\": \"chrome\", \"platformName\": \"android\", \"appium:platformVersion\": \"11\"}"
]
```

### 启用基本身份验证

通过配置包含用户名和密码的 路由器/集线器/单机的方式, 可以使用这样的基本身份验证保护Grid. 加载Grid UI或者开始一个新的会话时 需要此用户/密码组合.

```toml
[router]
username = "admin"
password = "myStrongPassword"
```

下面是一个Java示例, 演示如何使用配置的用户和密码启动会话.

```java
ClientConfig clientConfig = ClientConfig.defaultConfig()
  .baseUrl(new URL("http://localhost:4444"))
  .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"));
HttpCommandExecutor executor = new HttpCommandExecutor(clientConfig);
RemoteWebDriver driver = new RemoteWebDriver(executor, new ChromeOptions());
```

在其他语言中, 您可以使用 URL http\://admin:myStrongPassword\@localhost:4444

### 为匹配特定节点设置自定义功能

**重要提示:** 自定义功能需要在所有节点的配置中进行设置. 并且在每次会话请求中都必须包含这些功能.

```toml
[node]
detect-drivers = false

[[node.driver-configuration]]
display-name = "firefox"
stereotype = '{"browserName": "firefox", "platformName": "macOS", "browserVersion":"96", "networkname:applicationName":"node_1", "nodename:applicationName":"app_1" }'
max-sessions = 5
```

这里有一个 Java 示例, 展示了如何匹配那个节点

```java
FirefoxOptions options = new FirefoxOptions();
options.setCapability("networkname:applicationName", "node_1");
options.setCapability("nodename:applicationName", "app_1");
options.setBrowserVersion("96");
options.setPlatformName("macOS");
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

### 启用节点的托管下载功能.

节点可以被设置为自动管理下载. 这将导致节点会把特定会话中下载的所有文件保存到一个临时目录中, 之后可以从节点中获取这些文件.\
要启用此功能, 请使用以下配置:

```toml
[node]
enable-managed-downloads = true
```

有关完整示例, 请参阅[CLI章节](https://www.selenium.dev/zh-cn/documentation/grid/configuration/cli_options/#enabling-managed-downloads-by-the-node) .

# 5 - Grid架构

|               | Event Bus | Distributor | Node | Router | Session Map | Session Queue |
| ------------- | --------- | ----------- | ---- | ------ | ----------- | ------------- |
| Event Bus     | X         |             |      |        |             |               |
| Distributor   | ✅         | X           | ✅    |        |             | ✅             |
| Node          | ✅         |             | X    |        |             |               |
| Router        |           |             | ✅    | X      | ✅           |               |
| Session Map   |           |             |      |        | X           |               |
| Session Queue | ✅         |             |      |        |             | X             |

| Name               | Type    | Description                                                                                                                                                                                                                                  |
| ------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| availability       | string  | A string which is one of `up`, `draining`, or `down`. The important one is `draining`, which indicates that no new sessions should be sent to the Node, and once the last session on it closes, the Node will exit or restart.               |
| externalUrl        | string  | The URI that the other components in the Grid should connect to.                                                                                                                                                                             |
| lastSessionCreated | integer | The epoch timestamp of when the last session was created on this Node. The Distributor will attempt to send new sessions to the Node that has been idle longest if all other things are equal.                                               |
| maxSessionCount    | integer | Although a session count can be inferred by counting the number of available slots, this integer value is used to determine the maximum number of sessions that should be running simultaneously on the Node before it is considered “full”. |
| nodeId             | string  | A UUID used to identify this instance of the Node.                                                                                                                                                                                           |
| osInfo             | object  | An object with `arch`, `name`, and `version` fields. This is used by the Grid UI and the GraphQL queries.                                                                                                                                    |
| slots              | array   | An array of Slot objects (described below)                                                                                                                                                                                                   |
| version            | string  | The version of the Node (for Selenium, this will match the Selenium version number)                                                                                                                                                          |

It is recommended to put values in all fields.

### The Slot Object

The Slot object represents a single slot within a Node. A “slot” is where a single session may be run. It is possible that a Node will have more slots than it can run concurrently. For example, a node may be able to run up 10 sessions, but they could be any combination of Chrome, Edge, or Firefox; in this case, the Node would indicate a “max session count” of 10, and then also say it has 10 slots for Chrome, 10 for Edge, and 10 for Firefox.

| Name        | Type   | Description                                                                                                                                                                  |
| ----------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id          | string | UUID to refer to the slot                                                                                                                                                    |
| lastStarted | string | When the slot last had a session started, in ISO-8601 format                                                                                                                 |
| stereotype  | object | The minimal set of [capabilities](https://w3c.github.io/webdriver/#dfn-merging-capabilities) this slot will match against. A minimal example is `{"browserName": "firefox"}` |
| session     | object | The Session object (see below)                                                                                                                                               |

### The Session Object

This represents a running session within a slot

| Name         | Type   | Description                                                                                                                                                                  |
| ------------ | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| capabilities | object | The actual capabilities provided by the session. Will match the return value from the [new session](https://w3c.github.io/webdriver/#new-session) command                    |
| startTime    | string | The start time of the session in ISO-8601 format                                                                                                                             |
| stereotype   | object | The minimal set of [capabilities](https://w3c.github.io/webdriver/#dfn-merging-capabilities) this slot will match against. A minimal example is `{"browserName": "firefox"}` |
| uri          | string | The URI used by the Node to communicate with the session                                                                                                                     |

# 6 - 高级功能

要获得高级功能的所有详细信息, 了解其工作原理, 以及如何设置自己的功能, 请浏览以下部分.

# 6.1 - 可观测性

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar standalone --log-level FINE
```

2. Jaeger UI - OpenTelemetry provides the APIs and SDKs to instrument traces in the code. Whereas Jaeger is a tracing backend, that aids in collecting the tracing telemetry data and providing querying, filtering and visualizing features for the data.

Detailed instructions of visualizing traces using Jaeger UI can be obtained by running the command :

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar info tracing
```

[A very good example and scripts to run the server and send traces to Jaeger](https://github.com/manoj9788/tracing-selenium-grid)

## Leveraging event logs

Tracing has to be enabled for event logging as well, even if one does not wish to export traces to visualize them.\
**By default, tracing is enabled. No additional parameters need to be passed to see logs on the console.** All events within a span are logged at FINE level. Error events are logged at WARN level.

All event logs have the following fields :

| Field            | Field value     | Description                                                                                                                                                                            |
| ---------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Event time       | eventId         | Timestamp of the event record in epoch nanoseconds.                                                                                                                                    |
| Trace Id         | tracedId        | Each trace is uniquely identified by a trace id.                                                                                                                                       |
| Span Id          | spanId          | Each span within a trace is uniquely identified by a span id.                                                                                                                          |
| Span Kind        | spanKind        | Span kind is a property of span indicating the type of span. It helps in understanding the nature of the unit of work done by the Span.                                                |
| Event name       | eventName       | This maps to the log message.                                                                                                                                                          |
| Event attributes | eventAttributes | This forms the crux of the event logs, based on the operation executed, it has JSON formatted key-value pairs. This also includes a handler class attribute, to show the logger class. |

Sample log

```
FINE [LoggingOptions$1.lambda$export$1] - {
  "traceId": "fc8aef1d44b3cc8bc09eb8e581c4a8eb",
  "spanId": "b7d3b9865d3ddd45",
  "spanKind": "INTERNAL",
  "eventTime": 1597819675128886121,
  "eventName": "Session request execution complete",
  "attributes": {
    "http.status_code": 200,
    "http.handler_class": "org.openqa.selenium.grid.router.HandleSession",
    "http.url": "\u002fsession\u002fdd35257f104bb43fdfb06242953f4c85",
    "http.method": "DELETE",
    "session.id": "dd35257f104bb43fdfb06242953f4c85"
  }
}
```

In addition to the above fields, based on [OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/exceptions.md) error logs consist of :

| Field                | Field value          | Description                                                                                                                   |
| -------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Exception type       | exception.type       | The class name of the exception.                                                                                              |
| Exception message    | exception.message    | Reason for the exception.                                                                                                     |
| Exception stacktrace | exception.stacktrace | Prints the call stack at the point of time when the exception was thrown. Helps in understanding the origin of the exception. |

Sample error log

```
WARN [LoggingOptions$1.lambda$export$1] - {
  "traceId": "7efa5ea57e02f89cdf8de586fe09f564",
  "spanId": "914df6bc9a1f6e2b",
  "spanKind": "INTERNAL",
  "eventTime": 1597820253450580272,
  "eventName": "exception",
  "attributes": {
    "exception.type": "org.openqa.selenium.ScriptTimeoutException",
    "exception.message": "Unable to execute request: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist ..." (full message will be printed),
    "exception.stacktrace": "org.openqa.selenium.ScriptTimeoutException: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist\nBuild info: version: '4.0.0-alpha-7', revision: 'Unknown'\nSystem info: host: 'XYZ-MacBook-Pro.local', ip: 'fe80:0:0:0:10d5:b63a:bdc6:1aff%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.7'\nDriver info: driver.version: unknown ...." (full stack will be printed),
    "http.handler_class": "org.openqa.selenium.grid.distributor.remote.RemoteDistributor",
    "http.url": "\u002fsession",
    "http.method": "POST"
  }
}
```

# 6.2 - GraphQL查询支持

```shell
{
    session(id: "<session-id>") : {
        id,
        capabilities,
        startTime,
        uri,
        nodeId,
        nodeUri,
        sessionDurationMillis
        slot : {
            id,
            stereotype,
            lastStarted
        }
    }
    grid: {
        uri,
        totalSlots,
        nodeCount,
        maxSession,
        sessionCount,
        version,
        sessionQueueSize
    }
    sessionsInfo: {
        sessionQueueRequests,
        sessions: [
            {
                id,
                capabilities,
                startTime,
                uri,
                nodeId,
                nodeUri,
                sessionDurationMillis
                slot : {
                    id,
                    stereotype,
                    lastStarted
                }
            }
        ]
    }
    nodesInfo: {
        nodes : [
            {
                id,
                uri,
                status,
                maxSession,
                slotCount,
                sessions: [
                    {
                        id,
                        capabilities,
                        startTime,
                        uri,
                        nodeId,
                        nodeUri,
                        sessionDurationMillis
                        slot : {
                            id,
                            stereotype,
                            lastStarted
                        }
                    }
                ],
                sessionCount,
                stereotypes,
                version,
                osInfo: {
                    arch,
                    name,
                    version
                }
            }
        ]
    }
}
```

## 查询 GraphQL

查询GraphQL的最佳方法是使用`curl`请求. GraphQL允许您仅获取所需的数据, 仅此而已.

下面给出了一些GraphQL查询的示例. 您可以根据需要构建自己的查询.

### 查询网格中 `maxSession` 和 `sessionCount` 的数量:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ grid { maxSession, sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

通常在本地机器上 `<LINK_TO_GRAPHQL_ENDPOINT>` 会是 `http://localhost:4444/graphql`

### 查询全部会话、及节点以及网格的详情 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { uri, maxSession, sessionCount }, nodesInfo { nodes { id, uri, status, sessions { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } }, slotCount, sessionCount }} }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询以获取当前网格的会话总数 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询以获取网格中的最大会话数量 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { maxSession } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询以获取网格中所有节点的全部会话详情 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, capabilities, startTime, uri, nodeId, nodeId, sessionDurationMillis } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询以获取网格中每个节点中所有会话的插槽信息 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, slot { id, stereotype, lastStarted } } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询以获取给定会话的会话信息查询以获取给定会话的会话信息 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ session (id: \"<session-id>\") { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } } } "}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询网格中每个节点的功能 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { stereotypes } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询网格中每个节点的状态 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { status } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询每个节点和网格的 URI :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { uri } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the current requests in the New Session Queue:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessionQueueRequests } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the New Session Queue size :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionQueueSize } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

# 6.3 - Grid端点

## Grid

### Grid 状态

Grid状态提供Grid的当前状态. 它包含每个注册节点的详细信息. 对于每个节点, 状态包括有关节点可用性、会话和插槽的信息.

```shell
curl --request GET 'http://localhost:4444/status'
```

### 删除会话

删除会话会终止 WebDriver 会话、退出驱动程序并将其从活动会话映射中删除。任何使用删除的会话标识或重新使用驱动程序实例的请求都会出错。

```shell
curl --request DELETE 'http://localhost:4444/session/<session-id>'
```

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret> '
```

在完全分布式模式下, URL是分发器的地址。

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

如果在设置Grid时未配置注册密码, 则使用

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET;'
```

### 释放节点

节点释放命令用于优雅地关闭节点。在所有正在进行的会话结束后，会停止该节点。并且，它不会接受任何新的会话请求。

在 Standalone 模式下，分发器 URL 是独立服务器地址。

在 Hub-Node 模式下, 分发器 URL 是 Hub 服务器的地址。

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret> '
```

在完全分布式模式下, URL是分发服务器的地址。

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

如果在设置Grid时未配置注册密码, 则使用

```shell
curl --request POST 'http://<Router-URL>/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET;'
```

## 节点

本节中的端点适用于 Hub-Node 模式和节点独立运行的完全分布式网格模式。在一个节点的情况下, 默认节点的URL为 http\://localhost:5555 。 如果有多个节点,请使用 [Grid 状态](/zh-cn/documentation/grid/advanced_features/endpoints/#grid-%e7%8a%b6%e6%80%81) 获取所有节点的详细信息并查找节点地址。

### 状态

节点状态本质上是节点的健康检查。分发程序会定期 ping 节点状态，并相应地更新 Grid 模型。状态包括有关可用性、会话和插槽的信息。

```shell
curl --request GET 'http://localhost:5555/status'
```

### 释放

分发器将 [释放](/zh-cn/documentation/grid/advanced_features/endpoints/#%e9%87%8a%e6%94%be%e8%8a%82%e7%82%b9) 命令传递给由node-id标识的相应节点。要直接释放节点,请使用下面列出的curl命令。 两个端点都有效并产生相同的结果。释放会等待持续中的会话完成后才停止节点。

```shell
curl --request POST 'http://localhost:5555/se/grid/node/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

如果在设置Grid时未配置注册密码,则使用

```shell
curl --request POST 'http://<node-URL>/se/grid/node/drain' --header 'X-REGISTRATION-SECRET;'
```

### 检查会话所有者

要检查会话是否属于某一节点, 请使用下面列出的curl命令.

```shell
curl --request GET 'http://localhost:5555/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

如果在设置Grid时未配置注册密码, 则使用

```shell
curl --request GET 'http://<node-URL>/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

如果会话属于该节点, 则返回true, 否则返回false。

### 删除会话

删除会话会终止 WebDriver 会话、退出驱动程序并将其从活动会话映射中删除。任何使用删除的会话标识或重新使用驱动程序实例的请求都会出错。

```shell
curl --request DELETE 'http://localhost:5555/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

如果在设置Grid时未配置注册密码, 则使用

```shell
curl --request DELETE 'http://<node-URL>/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

## 新会话队列

### 清除新会话队列

新会话请求队列保存新会话请求。要清除队列，请使用下面列出的 curl 命令。清除队列会拒绝队列中的所有请求。对于每个此类请求，服务器都会向相应的客户端返回错误响应。清除命令的结果是被删除请求的总数。

在 Standalone 模式下, 队列URL是独立服务器的地址。 在 Hub-Node 模式下, 队列URL是集线器服务器的地址。

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

在完全分布式模式下, 队列URL是新会话队列服务器的地址。

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

如果在设置Grid时未配置注册密码, 则使用

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET;'
```

### 获取新会话队列请求

新会话请求队列保存新会话请求。 要获取队列中的当前请求, 请使用下面列出的curl命令。 响应会返回队列中的请求总数以及请求内容。

在 Standalone 模式下, 队列URL是独立服务器的地址。 在 Hub-Node 模式下, 队列URL是集线器服务器的地址。

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

在完全分布式模式下, 队列URL是新会话队列服务器的地址。

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

# 6.4 - 自定义Node

```bash
java -jar custom_node-server.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

```bash
java -jar selenium-server-4.6.0.jar \
--ext custom_node-1.0-SNAPSHOT.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

下面是一个示例：当Node有相关活动（会话创建、会话删除、WebDriver 命令执行等）时，仅在控制台打印一些消息。

自定义Node示例

```java
package org.seleniumhq.samples;

import java.net.URI;
import java.util.UUID;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.NoSuchSessionException;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.grid.config.Config;
import org.openqa.selenium.grid.data.CreateSessionRequest;
import org.openqa.selenium.grid.data.CreateSessionResponse;
import org.openqa.selenium.grid.data.NodeId;
import org.openqa.selenium.grid.data.NodeStatus;
import org.openqa.selenium.grid.data.Session;
import org.openqa.selenium.grid.log.LoggingOptions;
import org.openqa.selenium.grid.node.HealthCheck;
import org.openqa.selenium.grid.node.Node;
import org.openqa.selenium.grid.node.local.LocalNodeFactory;
import org.openqa.selenium.grid.security.Secret;
import org.openqa.selenium.grid.security.SecretOptions;
import org.openqa.selenium.grid.server.BaseServerOptions;
import org.openqa.selenium.internal.Either;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
import org.openqa.selenium.remote.tracing.Tracer;

public class DecoratedLoggingNode extends Node {

  private Node node;

  protected DecoratedLoggingNode(Tracer tracer, NodeId nodeId, URI uri, Secret registrationSecret, Duration sessionTimeout) {
    super(tracer, nodeId, uri, registrationSecret, sessionTimeout);
  }

  public static Node create(Config config) {
    LoggingOptions loggingOptions = new LoggingOptions(config);
    BaseServerOptions serverOptions = new BaseServerOptions(config);
    URI uri = serverOptions.getExternalUri();
    SecretOptions secretOptions = new SecretOptions(config);
    NodeOptions nodeOptions = new NodeOptions(config);
    Duration sessionTimeout = nodeOptions.getSessionTimeout();

    // Refer to the foot notes for additional context on this line.
    Node node = LocalNodeFactory.create(config);

    DecoratedLoggingNode wrapper = new DecoratedLoggingNode(loggingOptions.getTracer(),
        node.getId(),
        uri,
        secretOptions.getRegistrationSecret(),
        sessionTimeout);
    wrapper.node = node;
    return wrapper;
  }

  @Override
  public Either<WebDriverException, CreateSessionResponse> newSession(
      CreateSessionRequest sessionRequest) {
    System.out.println("Before newSession()");
    try {
      return this.node.newSession(sessionRequest);
    } finally {
      System.out.println("After newSession()");
    }
  }

  @Override
  public HttpResponse executeWebDriverCommand(HttpRequest req) {
    try {
      System.out.println("Before executeWebDriverCommand(): " + req.getUri());
      return node.executeWebDriverCommand(req);
    } finally {
      System.out.println("After executeWebDriverCommand()");
    }
  }

  @Override
  public Session getSession(SessionId id) throws NoSuchSessionException {
    try {
      System.out.println("Before getSession()");
      return node.getSession(id);
    } finally {
      System.out.println("After getSession()");
    }
  }

  @Override
  public HttpResponse uploadFile(HttpRequest req, SessionId id) {
    try {
      System.out.println("Before uploadFile()");
      return node.uploadFile(req, id);
    } finally {
      System.out.println("After uploadFile()");
    }
  }

  @Override
  public void stop(SessionId id) throws NoSuchSessionException {
    try {
      System.out.println("Before stop()");
      node.stop(id);
    } finally {
      System.out.println("After stop()");
    }
  }

  @Override
  public boolean isSessionOwner(SessionId id) {
    try {
      System.out.println("Before isSessionOwner()");
      return node.isSessionOwner(id);
    } finally {
      System.out.println("After isSessionOwner()");
    }
  }

  @Override
  public boolean isSupporting(Capabilities capabilities) {
    try {
      System.out.println("Before isSupporting");
      return node.isSupporting(capabilities);
    } finally {
      System.out.println("After isSupporting()");
    }
  }

  @Override
  public NodeStatus getStatus() {
    try {
      System.out.println("Before getStatus()");
      return node.getStatus();
    } finally {
      System.out.println("After getStatus()");
    }
  }

  @Override
  public HealthCheck getHealthCheck() {
    try {
      System.out.println("Before getHealthCheck()");
      return node.getHealthCheck();
    } finally {
      System.out.println("After getHealthCheck()");
    }
  }

  @Override
  public void drain() {
    try {
      System.out.println("Before drain()");
      node.drain();
    } finally {
      System.out.println("After drain()");
    }

  }

  @Override
  public boolean isReady() {
    try {
      System.out.println("Before isReady()");
      return node.isReady();
    } finally {
      System.out.println("After isReady()");
    }
  }
}
```

***注释：***

在上述示例中，`Node node = LocalNodeFactory.create(config);` 这一行显式创建了一个 `LocalNode`。

`org.openqa.selenium.grid.node.Node` 主要有两种*面向用户的实现*。

这些类是学习如何构建自定义 Node 以及了解 Node 内部机制的良好起点。

* `org.openqa.selenium.grid.node.local.LocalNode` - 用于表示长时间运行的 Node，也是默认实现。启动 `node` 时会自动接入。

  * 可通过 `LocalNodeFactory.create(config);` 创建，其中：

    * `LocalNodeFactory` 属于 `org.openqa.selenium.grid.node.local`
    * `Config` 属于 `org.openqa.selenium.grid.config`

* `org.openqa.selenium.grid.node.k8s.OneShotNode` - 这是一个特殊的参考实现，节点在服务完一个测试会话后会自动关闭。该类目前未包含在任何预构建的 maven 包中。

  * 你可以在 [这里](https://github.com/SeleniumHQ/selenium/blob/trunk/java/src/org/openqa/selenium/grid/node/k8s/OneShotNode.java) 查看源码。

  * 参考 [这里](https://github.com/SeleniumHQ/selenium/blob/trunk/deploys/k8s/README.md) 了解本地构建方法。

  * 可通过 `OneShotNode.create(config)` 创建，其中：

    * `OneShotNode` 属于 `org.openqa.selenium.grid.node.k8s`
    * `Config` 属于 `org.openqa.selenium.grid.config`

# 6.5 - External datastore

```sql
CREATE TABLE IF NOT EXISTS sessions_map(
    session_ids varchar(256),
    session_caps text,
    session_uri varchar(256),
    session_stereotype text,
    session_start varchar(256)
 );
```

* In the same directory as the `init.sql`, create a file named `docker-compose.yml` with its contents as below:

```yaml
version: '3.8'
services:
  db:
    image: postgres:9.6-bullseye
    restart: always
    environment:
      - POSTGRES_USER=seluser
      - POSTGRES_PASSWORD=seluser
      - POSTGRES_DB=selenium_sessions
    ports:
      - "5432:5432"
    volumes:
    - ./init.sql:/docker-entrypoint-initdb.d/init.sql
```

We can now start our database container by running:

```bash
docker-compose up -d
```

*Our database name is `selenium_sessions` with its username and password set to `seluser`*

If you are working with an already running PostGreSQL DB instance, then you just need to create a database named `selenium_sessions` and the table `sessions_map` using the above mentioned SQL statement.

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
implementation = "org.openqa.selenium.grid.sessionmap.jdbc.JdbcBackedSessionMap"
jdbc-url = "jdbc:postgresql://localhost:5432/selenium_sessions"
jdbc-user = "seluser"
jdbc-password = "seluser"
```

*Note:* If you plan to use an existing PostGreSQL DB instance, then replace `localhost:5432` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed Grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Sessions Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

```yaml
version: '3.8'
services:
  redis:
    image: redis:bullseye
    restart: always
    ports:
      - "6379:6379"
```

We can now start our Redis container by running:

```bash
docker-compose up -d
```

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
scheme = "redis"
implementation = "org.openqa.selenium.grid.sessionmap.redis.RedisBackedSessionMap"
hostname = "localhost"
port = 6379
```

*Note:* If you plan to use an existing Redis Cache instance, then replace `localhost` and `6379` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Session Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

* At this point the current directory should contain the following files:

  * `docker-compose.yml`
  * `sessions.toml`
  * `distributed.sh`

* You can now spawn the Grid by running `distributed.sh` shell script and quickly run a test. You will notice that the Grid now stores session information into the Redis instance. You can perhaps make use of a Redis GUI such as [TablePlus](https://tableplus.com/) to see them (Make sure that you have setup a debug point in your test, because the values will get deleted as soon as the test runs to completion).

In the line which spawns a `SessionMap` on a machine:

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/getting_started/first_script/
----

# Programe o seu primeiro script Selenium

```java
        WebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver = webdriver.Chrome()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L4)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L11)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver = Selenium::WebDriver.for :chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L3)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    driver = await new Builder().forBrowser(Browser.CHROME).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L8)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver = ChromeDriver()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L16)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.get("https://www.selenium.dev/selenium/web/web-form.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L6)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L13)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.get('https://www.selenium.dev/selenium/web/web-form.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L5)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L9)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.get("https://www.selenium.dev/selenium/web/web-form.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L18)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#16)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L8)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var title = driver.Title;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L15)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L7)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let title = await driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L11)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L20)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L18)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.implicitly_wait(0.5)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L10)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L17)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.manage.timeouts.implicit_wait = 500
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L9)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.manage().setTimeouts({implicit: 500});
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L14)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L23)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L20-L21)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L12-L13)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L19-L20)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L11-L12)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L16-L17)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L25-L26)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        textBox.sendKeys("Selenium");
        submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L23-L24)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
text_box.send_keys("Selenium")
submit_button.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L15-L16)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        textBox.SendKeys("Selenium");
        submitButton.Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
text_box.send_keys('Selenium')
submit_button.click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L14-L15)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await textBox.sendKeys('Selenium');
    await submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L19-L20)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        textBox.sendKeys("Selenium")
        submitButton.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L28-L29)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        WebElement message = driver.findElement(By.id("message"));
        message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-27)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
message = driver.find_element(by=By.ID, value="message")
text = message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L18-19)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-26)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
message = driver.find_element(id: 'message')
message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L17-18)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L22-23)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val message = driver.findElement(By.id("message"))
        val value = message.getText()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-32)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L21)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L28)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L20)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L28)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L35)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```md
mvn exec:java -D"exec.mainClass"="dev.selenium.getting_started.FirstScript" -D"exec.classpathScope"=test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/README.md#L60)

##### /examples/java/README.md

````md
# Running Selenium Java Tests
The following steps will guide you on how to 
run Selenium Java tests using a repository 
of `SeleniumHQ/seleniumhq.github.io` examples.

## Initial Setup

### Prerequisites

Ensure that Java Development Kit (JDK) and Maven 
are installed on your system. If they are not installed, 
you will need to download and install them. You can 
find detailed installation guides for both on their 
respective official sites.

### Clone the repository
First, we need to get the Selenium Java examples 
on your local machine. This can be done by 
cloning the `SeleniumHQ/seleniumhq.github.io` Git repository. 
Run the following command in your terminal:

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```
## Navigate to the java directory
After cloning the repository, navigate into the 
directory where the Selenium Java examples are 
located. Run the following command:

```bash
cd seleniumhq.github.io/examples/java
```

## Running the Tests
### Install dependencies
Before running the tests, we need to install all 
necessary dependencies. Maven, a software 
project management tool, can do this for us. 
Run the following command:

```bash
mvn test-compile
```

### Run all tests
To verify if everything is installed correctly and 
functioning properly, we should run all 
available tests. This can be done with the following command:

```bash
mvn test
```

Please be patient! If this is your first time running these tests, 
it might take a while to download and verify all necessary browser drivers.

## Execute a specific example
To run a specific Selenium Java example, use the following command:
```bash
mvn exec:java -D"exec.mainClass"="dev.selenium.getting_started.FirstScript" -D"exec.classpathScope"=test
```

Make sure to replace `dev.selenium.getting_started.FirstScript` with the path and name of the example you want to run.
````

````md
```
````

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/README.md#L35)

##### /examples/python/README.md

````md
# Running tests from Selenium Python examples

#### 1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

#### 2. Navigate to `python` directory

```
cd seleniumhq.github.io/examples/python
```

#### 3. Create a virtual environment

- On Windows:

```
py -m venv venv
venv\Scripts\activate
```

- On Linux/Mac:

```
python3 -m venv venv
source venv/bin/activate
```

#### 4. Install dependencies:

```
pip install -r requirements.txt
```

> for help, see: https://packaging.python.org/en/latest/tutorials/installing-packages

#### 5. Run tests

- Run all tests with the default Python interpreter:

```
pytest
```

- Run all tests with every installed/supported Python interpreter:

```
tox
```

> Please have some patience - If you are doing it for the first time, it will take a little while to download the browser drivers

- Run a specific example:

```
pytest path/to/test_script.py
```

> Make sure to replace `path/to/test_script.py` with the path and name of the example you want to run
````

```md
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/README.md#L55)

##### /examples/dotnet/README.md

````md

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

## Navigate to the .NET directory
### Change into the .NET examples directory:

```bash
cd seleniumhq.github.io/examples/dotnet/SeleniumDocs
```

## Running the Tests
### Restore dependencies
Install necessary dependencies using the .NET CLI:

```bash
dotnet restore
```

### Run all tests
To run all available tests:

```bash
dotnet test
```

### Run a Specific Test Method
To run a specific test method using its fully qualified name:

```bash
dotnet test --filter "FullyQualifiedName=Namespace.ClassName.MethodName"
```
For example:
```bash
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

You can also filter by test name only (if it's unique):
```bash
dotnet test --filter "Name=EightComponents"
```
````

```md
ruby example_script.rb
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/README.md#L36)

##### /examples/ruby/README.md

````md
# Running all tests from Selenium ruby example

Follow these steps to run all test example from selenium ruby

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `ruby` directory

```
cd seleniumhq.github.io/examples/ruby
```

3. Install dependencies using bundler

```
bundler install
```

4. Run all tests

```
bundle exec rspec
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a ruby script

Use this command to run a ruby script and follow the first script example

```
ruby example_script.rb
```
````

```md
node example_script.spec.js
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/README.md#L36)

##### /examples/javascript/README.md

````md
# Running all tests from Selenium javascript example

Follow these steps to run all test example from selenium javascript

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `javascript` directory

```
cd seleniumhq.github.io/examples/javascript
```

3. Install dependencies using node

```
npm install
```

4. Run all all tests

```
npm test
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a javascript test

Use this command to run a JavaScript and follow the first script example

```
node example_script.spec.js
```
````

[Add Example](/documentation/about/contributing/#creating-examples)

## Próximos Passos

Most Selenium users execute many sessions and need to organize them to minimize duplication and keep the code more maintainable. Read on to learn about how to put this code into context for your use case with [Using Selenium](https://www.selenium.dev/pt-br/documentation/webdriver/getting_started/using_selenium/).

Última modificação October 30, 2025: [Update "First Script" documentation with C# example from .NET README (#2478) (e55b319492d)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e55b319492d1e4062020fe6c23d46dae22b4b2aa)

## Development Partners

[](https://www.browserstack.com/automate?utm_campaign=open-source-sponsor\&utm_campaigncode=701OW000009sQwVYAU\&utm_medium=partnered\&utm_source=seleniumorg)

[](https://saucelabs.com/resources/topic-hub/selenium?utm_source=selenium\&utm_medium=website\&utm_campaign=selenium-sponsorship-fy25)

[](https://www.testmuai.com)

## Selenium Level Sponsors

[](https://brightdata.com/?utm_source=brand\&utm_campaign=brnd-mkt_partners_selenium)

[](https://applitools.com/)

[](https://www.thordata.com/?ls=waOicIkB\&lk=selenium)

## Support the Selenium Project

Learn more or view the full list of sponsors.

[Learn more**](/sponsors)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/bidi/cdp/
----

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/CdpTest.java#L22-L27)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/CdpTest.java

```java
package dev.selenium.bidi.cdp;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chromium.HasCdp;

import java.util.HashMap;
import java.util.Map;

public class CdpTest extends BaseTest {
  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
  }

  @Test
  public void setCookie() {
    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);

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }
}
```

```py
    cookie = {'name': 'cheese',
              'value': 'gouda',
              'domain': 'www.selenium.dev',
              'secure': True}

    driver.execute_cdp_cmd('Network.setCookie', cookie)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_cdp.py#L2-L7)

##### /examples/python/tests/bidi/cdp/test\_cdp.py

```py
def test_set_cookie(driver):
    cookie = {'name': 'cheese',
              'value': 'gouda',
              'domain': 'www.selenium.dev',
              'secure': True}

    driver.execute_cdp_cmd('Network.setCookie', cookie)

    driver.get('https://www.selenium.dev')
    cheese = driver.get_cookie(cookie['name'])

    assert cheese['value'] == 'gouda'
```

```cs
            var cookie = new Dictionary<string, object>
            {
                { "name", "cheese" },
                { "value", "gouda" },
                { "domain", "www.selenium.dev" },
                { "secure", true }
            };
            ((ChromeDriver)driver).ExecuteCdpCommand("Network.setCookie", cookie);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/CDPTest.cs#L14-L21)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/CDPTest.cs

```cs
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class CDPTest : BaseChromeTest
    {
        [TestMethod]
        public void SetCookie()
        {
            var cookie = new Dictionary<string, object>
            {
                { "name", "cheese" },
                { "value", "gouda" },
                { "domain", "www.selenium.dev" },
                { "secure", true }
            };
            ((ChromeDriver)driver).ExecuteCdpCommand("Network.setCookie", cookie);
            
            driver.Url = "https://www.selenium.dev";
            Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);

        }
    }
}
```

```rb
    driver.execute_cdp('Network.setCookie',
                       name: 'cheese',
                       value: 'gouda',
                       domain: 'www.selenium.dev',
                       secure: true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/cdp_spec.rb#L9-L13)

##### /examples/ruby/spec/bidi/cdp/cdp\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'sets cookie' do
    driver.execute_cdp('Network.setCookie',
                       name: 'cheese',
                       value: 'gouda',
                       domain: 'www.selenium.dev',
                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end
end
```

***

##### [Chrome DevTools Logging Features](/pt-br/documentation/webdriver/bidi/cdp/logging/)

Logging features using CDP.

##### [Chrome DevTools Network Features](/pt-br/documentation/webdriver/bidi/cdp/network/)

Network features using CDP.

##### [Chrome DevTools Script Features](/pt-br/documentation/webdriver/bidi/cdp/script/)

Script features using CDP.

Última modificação August 17, 2024: [add missing foreign language pages under cdp (#1864) (36b16c7407d)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/36b16c7407d344165bcc40f266806d74e9937edc)

----
url: https://www.selenium.dev/pt-br/documentation/grid/architecture/
----

# Arquitectura da Grid

|               | Event Bus | Distributor | Node | Router | Session Map | Session Queue |
| ------------- | --------- | ----------- | ---- | ------ | ----------- | ------------- |
| Event Bus     | X         |             |      |        |             |               |
| Distributor   | ✅         | X           | ✅    |        |             | ✅             |
| Node          | ✅         |             | X    |        |             |               |
| Router        |           |             | ✅    | X      | ✅           |               |
| Session Map   |           |             |      |        | X           |               |
| Session Queue | ✅         |             |      |        |             | X             |

| Nome               | Tipo    | Descrição                                                                                                                                                                                                                                         |
| ------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| availability       | string  | Uma string com `up`, `draining`, ou `down`. A mais importante é `draining`, que indica que não devem ser enviados novos pedidos de sessão para o Node e assim que a última sessão termine, o Node irá reiniciar ou concluir.                      |
| externalUrl        | string  | Uma URI que os outros componentes da Grid se devem ligar.                                                                                                                                                                                         |
| lastSessionCreated | integer | Um timestamp da última sessão que foi criada neste Node. O Distributor irá tentar enviar novos pedidos de sessão para o Node que esteja parado há mais tempo.                                                                                     |
| maxSessionCount    | integer | Embora seja possível inferir o número máximo de sessões a partir da lista de slots disponíveis, este número é usado para determinar qual é o máximo de sessões que este Node pode executar em simultâneo antes que se considere que está “cheio”. |
| nodeId             | string  | Um identificador UUID para esta instância do Node.                                                                                                                                                                                                |
| osInfo             | object  | Um objecto contendo os campos `arch`, `name`, e `version`. Isto é usado pela Grid UI e pelas queries GraphQL.                                                                                                                                     |
| slots              | array   | Um array de objectos Slot (descritos na secção seguinte)                                                                                                                                                                                          |
| version            | string  | A versão do Node (para Selenium, será igual à versão do Selenium)                                                                                                                                                                                 |

É recomendado que todos os campos tenham valores.

### O Objecto Slot

O objecto Slot representa um slot dentro de um Node. Um “slot” é onde uma sessão consegue ser executada. É possível que um Node tenha mais do que um Slot capaz de executar ao mesmo tempo. Por exemplo, um Node pode ser capaz de executar até 10 sessões em simultâneo, mas podem ser uma qualquer combinação de Chrome, Firefox ou Edge e neste caso, o Node irá indicar 10 como o número máximo de sessões, indicando que podem ser 10 Chrome, 10 Firefox e 10 Edge.

| Nome        | Tipo   | Descrição                                                                                                                                                                                 |
| ----------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id          | string | Um identificador UUID para este slot                                                                                                                                                      |
| lastStarted | string | timestamp no formato ISO-8601 contendo a data em que a última sessão iniciou                                                                                                              |
| stereotype  | object | Conjunto mínimo de [capacidades](https://w3c.github.io/webdriver/#dfn-merging-capabilities) que fazem match com este slot. O exemplo mínimo será por exemplo `{"browserName": "firefox"}` |
| session     | object | O objecto Session (descrito na secção seguinte)                                                                                                                                           |

### O Objecto Session

Representa uma sessão em execução dentro de um Slot

| Nome         | Tipo   | Descrição                                                                                                                                                                                 |
| ------------ | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| capabilities | object | A lista de capacidades fornecidas pela sessão. Irá coincidir com o valor obtido pelo comando [nova sessão](https://w3c.github.io/webdriver/#new-session)                                  |
| startTime    | string | timestamp no formato ISO-8601 contendo a data em que a última sessão iniciou                                                                                                              |
| stereotype   | object | Conjunto mínimo de [capacidades](https://w3c.github.io/webdriver/#dfn-merging-capabilities) que fazem match com este slot. O exemplo mínimo será por exemplo `{"browserName": "firefox"}` |
| uri          | string | A URI usada pelo Node para comunicar com a sessão                                                                                                                                         |

Última modificação December 1, 2022: [Translation of Grid Documentation to pt-br (#1251) (caf3eab1553)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/caf3eab155362c292eae780090242b216c5ee9a3)

----
url: https://www.selenium.dev/zh-cn/_print/documentation/webdriver/getting_started/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/webdriver/getting_started/).

# 入门指南

如果你是Selenium的新手, 我们有一些资源帮助你快速入门.

* 1: [安装Selenium类库](#pg-f2d5d4d74e106172503425b1902ea518)
* 2: [编写第一个Selenium脚本](#pg-a7b15bb46bba138301d398682bae6806)
* 3: [组织和执行Selenium代码](#pg-e57ea4968e3e75948be107b2e4e2f43a)

# 1 - 安装Selenium类库

```xml
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/pom.xml#L35-L38)

##### /examples/java/pom.xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>dev.selenium</groupId>
    <artifactId>selenium-examples</artifactId>
    <version>1.0.0</version>

    <properties>
        <surefire.parallel>1</surefire.parallel>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <selenium.version>4.41.0</selenium.version>
    </properties>

    <repositories>
        <repository>
            <name>Central Portal Snapshots</name>
            <id>central-portal-snapshots</id>
            <url>https://central.sonatype.com/repository/maven-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-grid</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>6.0.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.titusfortner</groupId>
            <artifactId>selenium-logger</artifactId>
            <version>2.4.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.5.5</version>
                <configuration>
                    <properties>
                        <configurationParameters>
                            junit.jupiter.execution.parallel.enabled = true
                            junit.jupiter.execution.parallel.mode.default = concurrent
                            junit.jupiter.execution.parallel.config.strategy = fixed
                            junit.jupiter.execution.parallel.config.fixed.parallelism = ${surefire.parallel}
                            junit.jupiter.execution.parallel.config.fixed.max-pool-size = ${surefire.parallel}
                        </configurationParameters>
                    </properties>
                    <rerunFailingTestsCount>3</rerunFailingTestsCount>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
```

### Gradle

具体的依赖位于项目中的 `build.gradle` 文件中的 `testImplementation`:

```gradle

dependencies {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/build.gradle#L13-L14)

##### /examples/java/build.gradle

```gradle
plugins {
    id 'java'
}

group 'dev.selenium'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

ext['seleniumVersion'] = System.getProperty('selenium.version', '4.41.0')

dependencies {
    testImplementation "org.seleniumhq.selenium:selenium-java:${seleniumVersion}"
    testImplementation "org.seleniumhq.selenium:selenium-grid:${seleniumVersion}"
    testImplementation platform("org.junit:junit-bom:6.0.2")
    testImplementation 'org.junit.jupiter:junit-jupiter-engine'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    testImplementation 'com.titusfortner:selenium-logger:2.4.0'
}

test {
    useJUnitPlatform()
}
```

该库所支持的Python版本最低版本可以在 `支持的Python版本` 章节中找到 [PyPi](https://pypi.org/project/selenium/)

这里提供了几种不同的方式来安装 Selenium .

### Pip

```shell
pip install selenium
```



### 下载

此外你可以从这里下载 [PyPI Built Distribution](https://pypi.org/project/selenium/#files) (selenium-x.x.x.-py3-none-any.whl) 并通过: *pip* 文件安装:

```shell
pip install selenium-x.x.x.-py3-none-any.whl
```



### 在项目中使用

为了在项目中使用它,需要将它添加到 `requirements.txt` 文件中:

```txt
selenium==4.41.0
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/requirements.txt#L1)

##### /examples/python/requirements.txt

```txt
selenium==4.41.0
pytest==9.0.3
trio==0.31.0
pytest-trio==0.8.0
pytest-rerunfailures==16.1
flake8==7.3.0
requests==2.33.0
tox==4.32.0
pytest-xdist==3.8.0
```

Selenium 所支持的所有平台的列表一览 见诸于 [Nuget](https://www.nuget.org/packages/Selenium.WebDriver)

该处阐述了一些安装Selenium的选项.

### 包管理器

```shell
Install-Package Selenium.WebDriver
```



### .NET CLI

```shell
dotnet add package Selenium.WebDriver
```



### CSProj

在 `csproj` 文件里, 具体的依赖 `PackageReference`(包参数) 位于 `ItemGroup` (项目组)中:

```csproj
      <PackageReference Include="Selenium.WebDriver" Version="4.41.0" />
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/SeleniumDocs.csproj#L14)

##### /examples/dotnet/SeleniumDocs/SeleniumDocs.csproj

```csproj
<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <GenerateProgramFile>false</GenerateProgramFile>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
      <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="7.7.1" />
      <PackageReference Include="MSTest.TestAdapter" Version="3.6.0" />
      <PackageReference Include="MSTest.TestFramework" Version="3.6.0" />
      <PackageReference Include="Selenium.Support" Version="4.41.0" />
      <PackageReference Include="Selenium.WebDriver" Version="4.41.0" />
    </ItemGroup>

    <ItemGroup>
      <Folder Include="LocalPackages" />
    </ItemGroup>

</Project>
```

### 其他附加思虑事项

更多的注意事项,适用于使用 Visual Studio Code (vscode) 和 C#

安装兼容的 .NET SDK 作为章节的先决条件 同时安装 vscode 的扩展 (Ctrl-Shift-X)以适配 C# 和 NuGet 可以遵照此处进行 [操作指南](https://docs.microsoft.com/en-us/dotnet/core/tutorials/with-visual-studio-code?pivots=dotnet-5-0) 创建 C# 控制台项目并运行 “Hello World”. 你也可以用命令行 `dotnet new NUnit` 创建NUnit初阶项目. 确保文件 `%appdata%\NuGet\nuget.config` 已经配置完成,就像某位开发者报告的问题一样,它可能因为某种因素被自动清空. 如果 `nuget.config` 是空的,或者未配置的,那么 .NET 创建的Selenium项目可能失败. 加入如下章节到文件 `nuget.config` 如果出现清空的情况:

```
<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />   
  </packageSources>
...
```

更多关于 `nuget.config` 的信息 [点击](https://docs.microsoft.com/en-us/nuget/reference/nuget-config-file). 你可能需要按照自己的需求配置 `nuget.config` .

现在,返回 vscode ,按下 Ctrl-Shift-P, 然后键入 “NuGet Add Package”, 并选择自己需要的 Selenium 包,例如 `Selenium.WebDriver`. 按下回车并选择版本. 现在你可以使用说明文档中关于 C# vscode下的案例了.

你可以查看 Selenium 对 Ruby 版本支持和最低支持. 具体位于 [rubygems.org](https://rubygems.org/gems/selenium-webdriver/)

Selenium 可以使用两种不同方法安装.

### 手动安装

```shell
gem install selenium-webdriver
```



### 加入项目的 gemfile

```gemfile
gem 'selenium-devtools', '= 0.147.0'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/Gemfile#L10)

##### /examples/ruby/Gemfile

```gemfile
# frozen_string_literal: true

source 'https://rubygems.org'

gem 'ffi', '~> 1.15', '>= 1.15.5' if Gem.win_platform? # Windows only
gem 'rake', '~> 13.0'
gem 'rspec', '~> 3.0'
gem 'rubocop', '~> 1.35'
gem 'rubocop-rspec', '~> 3.0'
gem 'selenium-devtools', '= 0.147.0'
gem 'selenium-webdriver', '= 4.43.0'
```

You can find the minimum required version of Node for any given version of Selenium in the 你可以在此查看 Selenium 对 Node 的版本支持情况 位于 `Node Support Policy` 中的相关章节 [npmjs](https://www.npmjs.com/package/selenium-webdriver)

Selenium is typically installed using npm.

### 本地安装

```shell
npm install selenium-webdriver
```



### 加入项目

在你的项目 `package.json`, 必须加入到 `dependencies`:

```json
        "mocha": "11.7.5"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/package.json#L14)

##### /examples/javascript/package.json

```json
{
    "name": "javascript-examples",
    "version": "1.0.0",
    "scripts": {
        "test": "npx mocha test/**/*.spec.js --timeout 120000 --parallel --retries 2"
    },
    "author": "The Selenium project",
    "license": "Apache-2.0",
    "dependencies": {
        "assert": "2.1.0",
        "selenium-webdriver": "4.41.0"
    },
    "devDependencies": {
        "mocha": "11.7.5"
    }
}
```

Use the Java bindings for Kotlin.

## 下一步

[创建你的第一个Selenium脚本](https://www.selenium.dev/zh-cn/documentation/webdriver/getting_started/first_script/)

# 2 - 编写第一个Selenium脚本

```java
        WebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver = webdriver.Chrome()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L4)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L11)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver = Selenium::WebDriver.for :chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L3)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    driver = await new Builder().forBrowser(Browser.CHROME).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L8)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver = ChromeDriver()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L16)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.get("https://www.selenium.dev/selenium/web/web-form.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L6)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L13)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.get('https://www.selenium.dev/selenium/web/web-form.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L5)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L9)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.get("https://www.selenium.dev/selenium/web/web-form.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L18)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#16)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L8)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var title = driver.Title;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L15)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L7)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let title = await driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L11)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L20)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L18)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.implicitly_wait(0.5)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L10)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L17)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.manage.timeouts.implicit_wait = 500
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L9)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.manage().setTimeouts({implicit: 500});
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L14)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L23)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L20-L21)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L12-L13)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L19-L20)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L11-L12)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L16-L17)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L25-L26)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        textBox.sendKeys("Selenium");
        submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L23-L24)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
text_box.send_keys("Selenium")
submit_button.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L15-L16)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        textBox.SendKeys("Selenium");
        submitButton.Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
text_box.send_keys('Selenium')
submit_button.click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L14-L15)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await textBox.sendKeys('Selenium');
    await submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L19-L20)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        textBox.sendKeys("Selenium")
        submitButton.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L28-L29)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        WebElement message = driver.findElement(By.id("message"));
        message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-27)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
message = driver.find_element(by=By.ID, value="message")
text = message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L18-19)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-26)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
message = driver.find_element(id: 'message')
message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L17-18)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L22-23)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val message = driver.findElement(By.id("message"))
        val value = message.getText()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-32)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L21)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L28)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L20)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L28)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L35)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```md
mvn exec:java -D"exec.mainClass"="dev.selenium.getting_started.FirstScript" -D"exec.classpathScope"=test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/README.md#L60)

##### /examples/java/README.md

````md
# Running Selenium Java Tests
The following steps will guide you on how to 
run Selenium Java tests using a repository 
of `SeleniumHQ/seleniumhq.github.io` examples.

## Initial Setup

### Prerequisites

Ensure that Java Development Kit (JDK) and Maven 
are installed on your system. If they are not installed, 
you will need to download and install them. You can 
find detailed installation guides for both on their 
respective official sites.

### Clone the repository
First, we need to get the Selenium Java examples 
on your local machine. This can be done by 
cloning the `SeleniumHQ/seleniumhq.github.io` Git repository. 
Run the following command in your terminal:

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```
## Navigate to the java directory
After cloning the repository, navigate into the 
directory where the Selenium Java examples are 
located. Run the following command:

```bash
cd seleniumhq.github.io/examples/java
```

## Running the Tests
### Install dependencies
Before running the tests, we need to install all 
necessary dependencies. Maven, a software 
project management tool, can do this for us. 
Run the following command:

```bash
mvn test-compile
```

### Run all tests
To verify if everything is installed correctly and 
functioning properly, we should run all 
available tests. This can be done with the following command:

```bash
mvn test
```

Please be patient! If this is your first time running these tests, 
it might take a while to download and verify all necessary browser drivers.

## Execute a specific example
To run a specific Selenium Java example, use the following command:
```bash
mvn exec:java -D"exec.mainClass"="dev.selenium.getting_started.FirstScript" -D"exec.classpathScope"=test
```

Make sure to replace `dev.selenium.getting_started.FirstScript` with the path and name of the example you want to run.
````

````md
```
````

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/README.md#L35)

##### /examples/python/README.md

````md
# Running tests from Selenium Python examples

#### 1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

#### 2. Navigate to `python` directory

```
cd seleniumhq.github.io/examples/python
```

#### 3. Create a virtual environment

- On Windows:

```
py -m venv venv
venv\Scripts\activate
```

- On Linux/Mac:

```
python3 -m venv venv
source venv/bin/activate
```

#### 4. Install dependencies:

```
pip install -r requirements.txt
```

> for help, see: https://packaging.python.org/en/latest/tutorials/installing-packages

#### 5. Run tests

- Run all tests with the default Python interpreter:

```
pytest
```

- Run all tests with every installed/supported Python interpreter:

```
tox
```

> Please have some patience - If you are doing it for the first time, it will take a little while to download the browser drivers

- Run a specific example:

```
pytest path/to/test_script.py
```

> Make sure to replace `path/to/test_script.py` with the path and name of the example you want to run
````

```md
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/README.md#L55)

##### /examples/dotnet/README.md

````md

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

## Navigate to the .NET directory
### Change into the .NET examples directory:

```bash
cd seleniumhq.github.io/examples/dotnet/SeleniumDocs
```

## Running the Tests
### Restore dependencies
Install necessary dependencies using the .NET CLI:

```bash
dotnet restore
```

### Run all tests
To run all available tests:

```bash
dotnet test
```

### Run a Specific Test Method
To run a specific test method using its fully qualified name:

```bash
dotnet test --filter "FullyQualifiedName=Namespace.ClassName.MethodName"
```
For example:
```bash
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

You can also filter by test name only (if it's unique):
```bash
dotnet test --filter "Name=EightComponents"
```
````

```md
ruby example_script.rb
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/README.md#L36)

##### /examples/ruby/README.md

````md
# Running all tests from Selenium ruby example

Follow these steps to run all test example from selenium ruby

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `ruby` directory

```
cd seleniumhq.github.io/examples/ruby
```

3. Install dependencies using bundler

```
bundler install
```

4. Run all tests

```
bundle exec rspec
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a ruby script

Use this command to run a ruby script and follow the first script example

```
ruby example_script.rb
```
````

```md
node example_script.spec.js
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/README.md#L36)

##### /examples/javascript/README.md

````md
# Running all tests from Selenium javascript example

Follow these steps to run all test example from selenium javascript

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `javascript` directory

```
cd seleniumhq.github.io/examples/javascript
```

3. Install dependencies using node

```
npm install
```

4. Run all all tests

```
npm test
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a javascript test

Use this command to run a JavaScript and follow the first script example

```
node example_script.spec.js
```
````

[Add Example](/documentation/about/contributing/#creating-examples)

## 接下来的步骤

大多数 Selenium 用户执行许多会话， 需要组织它们以最大限度地减少重复并维持代码更易于维护. 请继续阅读，了解如何将此代码放入您用例的上下文中 [使用 Selenium](https://www.selenium.dev/zh-cn/documentation/webdriver/getting_started/using_selenium/).

# 3 - 组织和执行Selenium代码

使用IDE和Test Runner库组织Selenium的执行

如果你不仅仅只是想执行一小撮的一次性脚本，你需要能组织并编排好你的代码。 本章会启发你如何真正地使用 Selenium 代码做高效的事情。

## 常见用法

大部分人使用 Selenium 执行针对 Web 应用的自动化测试，但是 Selenium 其实可以支持任何场景的浏览器自动化。

### 重复性任务

有时候你需要往网站记录日志或者下载一些东西，或者提交一个表单， 你可以在预设的时间创建一个 Selenium 脚本去执行一个服务。

### 网页爬虫

你是否期望从一个不提供 API 的网站收集数据？Selenium 可以满足你， 但是请确保你了解该网站的服务条例， 因为有些网站不允许你这样做，甚至有些网站会屏蔽 Selenium。

### 测试

使用 Selenium 做测试需要在 Selenium 执行操作后进行断言，所以一个好的断言类库是很有必要的。 至于组织测试用例结构的一些额外特性则需要[Test Runner](/zh-cn/documentation/webdriver/getting_started/using_selenium/#test-runner)来完成。

## IDEs

不管你要用 Selenium 来做什么，没有一个好的集成开发环境，你的工作肯定不会高效。以下是一些常见的 IDE 选择：

* [Eclipse](https://www.eclipse.org/)
* [IntelliJ IDEA](https://www.jetbrains.com/idea/)
* [PyCharm](https://www.jetbrains.com/pycharm/)
* [RubyMine](https://www.jetbrains.com/ruby/)
* [Rider](https://www.jetbrains.com/rider/)
* [WebStorm](https://www.jetbrains.com/webstorm/)
* [VS Code](https://code.visualstudio.com/)

## Test Runner

即使不使用 Selenium 做测试，如果你有高级用例，使用一个 test runner 去更好地组织你的代码是很有意义的。 学会使用 before/after hooks 和分组执行或者并行执行将会非常有用。

### 候选

有非常多不同的 test runner 可供选择。

这个教程中所有使用到 test runner 的代码示例都可以在我们的示例目录中找到（或者正在被迁移过去）， 而且这些示例在每一次发版都会被执行，以确保代码是正确的和最新的。 下面是一份包含对应链接的 test runner 清单，其中第一项是被这个仓库和本页所有用例所使用的。

*
*
*
*
*
*

- [JUnit](https://junit.org/junit5/) - 一个广泛使用的用于基于 Java 的 Selenium 测试的测试框架。
- [TestNG](https://testng.org/) - 提供诸如并行测试执行和参数化测试等额外功能。

* [pytest](https://pytest.org/) - 由于其简单性和强大的插件，它成为许多人的首选。
* [unittest](https://docs.python.org/3/library/unittest.html) - Python 的标准测试库

- [NUnit](https://nunit.org/) - .NET的流行单元测试框架
- [MS Test](https://docs.microsoft.com/en-us/visualstudio/test/getting-started-with-unit-testing?view=vs-2019) - 微软自己的单元测试框架

* [RSpec](https://rspec.info/) - Ruby中运行Selenium测试最广泛使用的测试库
* [Minitest](https://github.com/seattlerb/minitest) - 一个随Ruby标准库附带的轻量级测试框架

- [Jest](https://jestjs.io/) - 主要作为React的测试框架而闻名，但也可以用于Selenium测试
- [Mocha](https://mochajs.org/) -最常用的运行Selenium测试的JavaScript库。

* [Kotest](https://kotest.io/) - 一个灵活且全面的测试框架，专为 Kotlin 设计。
* [JUnit5](https://junit.org/junit5/) - 标准的 Java 测试框架，完全兼容 Kotlin。

### 安装

在[安装 Selenium 类库](https://www.selenium.dev/zh-cn/documentation/webdriver/getting_started/install_library/)一节中详细说明了需要哪些东西。 这里的代码只展示在我们的文档示例项目中用到的示例。

*
*
*
*
*
*

**Maven**

**Gradle**

To use it in a project, add it to the `requirements.txt` file:

in the project’s `csproj` file, specify the dependency as a `PackageReference` in `ItemGroup`:

Add to project’s gemfile

In your project’s `package.json`, add requirement to `dependencies`:

### 断言

*
*
*
*
*
*

```java
		String title = driver.getTitle();
		assertEquals("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L30-L31)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

```py
    title = driver.title
    assert title == "Web form"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L8-L9)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

```cs
            var title = driver.Title;
            Assert.AreEqual("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs#L19-L20)

##### /examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted
{
    [TestClass]
    public class UsingSeleniumTest
    {

        [TestMethod]
        public void EightComponents()
        {
            IWebDriver driver = new ChromeDriver();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

            var title = driver.Title;
            Assert.AreEqual("Web form", title);

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            var textBox = driver.FindElement(By.Name("my-text"));
            var submitButton = driver.FindElement(By.TagName("button"));
            
            textBox.SendKeys("Selenium");
            submitButton.Click();
            
            var message = driver.FindElement(By.Id("message"));
            var value = message.Text;
            Assert.AreEqual("Received!", value);
            
            driver.Quit();
        }
    }
}
```

```rb
    title = @driver.title
    expect(title).to eq('Web form')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb#L14-L15)

##### /examples/ruby/spec/getting\_started/using\_selenium\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

```js
    let title = await driver.getTitle();
    assert.equal("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L14-L15)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

```kt
        val title = driver.title
        assertEquals("Web form", title)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L20-21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt

    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

### Setting Up and Tearing Down

*
*
*
*
*
*

### Set Up

```java
	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L19-L22)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

### Tear Down

```java
	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L45-L48)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

### Set Up

```py
def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L25-L28)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

### Tear Down

```py
def teardown(driver):
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L30-31)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

### Set Up

```rb
  before do
    @driver = Selenium::WebDriver.for :chrome
  end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb#L7-L9)

##### /examples/ruby/spec/getting\_started/using\_selenium\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

### Tear Down

```rb
  config.after { @driver&.quit }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/spec_helper.rb#L30)

##### /examples/ruby/spec/spec\_helper.rb

```rb

    c.syntax = :expect
  end

  config.before do |example|
    bug_tracker = 'https://github.com/SeleniumHQ/seleniumhq.github.io/issues'
    guards = Selenium::WebDriver::Support::Guards.new(example,
                                                      bug_tracker: bug_tracker)
    guards.add_condition(:platform, Selenium::WebDriver::Platform.os)
    guards.add_condition(:ci, Selenium::WebDriver::Platform.ci)

    results = guards.disposition
    send(*results) if results
  end

  config.after { @driver&.quit }

  def start_session
    options = Selenium::WebDriver::Chrome::Options.new
    options.add_argument('disable-search-engine-choice-screen')
    options.add_argument('--no-sandbox')
    @driver = Selenium::WebDriver.for(:chrome, options: options)
  end

  def start_bidi_session
    options = Selenium::WebDriver::Chrome::Options.new(web_socket_url: true)
    @driver = Selenium::WebDriver.for :chrome, options: options
  end

  def start_firefox
    options = Selenium::WebDriver::Options.firefox(timeouts: {implicit: 1500})
    @driver = Selenium::WebDriver.for :firefox, options: options
  end
end
```

\### Set Up

```js
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L7-L9)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

\### Tear Down

```js
  after(async () => await driver.quit());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L30)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

### 执行

*
*
*
*
*
*

### Maven

```shell
mvn clean test
```

### Gradle

```shell
gradle clean test
```

````md
```
````

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/README.md#L35)

##### /examples/python/README.md

````md
# Running tests from Selenium Python examples

#### 1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

#### 2. Navigate to `python` directory

```
cd seleniumhq.github.io/examples/python
```

#### 3. Create a virtual environment

- On Windows:

```
py -m venv venv
venv\Scripts\activate
```

- On Linux/Mac:

```
python3 -m venv venv
source venv/bin/activate
```

#### 4. Install dependencies:

```
pip install -r requirements.txt
```

> for help, see: https://packaging.python.org/en/latest/tutorials/installing-packages

#### 5. Run tests

- Run all tests with the default Python interpreter:

```
pytest
```

- Run all tests with every installed/supported Python interpreter:

```
tox
```

> Please have some patience - If you are doing it for the first time, it will take a little while to download the browser drivers

- Run a specific example:

```
pytest path/to/test_script.py
```

> Make sure to replace `path/to/test_script.py` with the path and name of the example you want to run
````

```md
dotnet test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/README.md#L44)

##### /examples/dotnet/README.md

````md
# Running Selenium .NET (C#) Tests

The following steps will guide you on how to  
run Selenium .NET (C#) tests using the examples  
from the `SeleniumHQ/seleniumhq.github.io` repository.

## Initial Setup

### Prerequisites

Ensure you have the following installed:

- [.NET SDK (8.0 or later)](https://dotnet.microsoft.com/en-us/download)
- An IDE like [Visual Studio](https://visualstudio.microsoft.com/) or [Visual Studio Code](https://code.visualstudio.com/)
- [.NET CLI tools](https://learn.microsoft.com/en-us/dotnet/core/tools/)

### Clone the repository

Clone the Selenium documentation repository to your local machine:

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

## Navigate to the .NET directory
### Change into the .NET examples directory:

```bash
cd seleniumhq.github.io/examples/dotnet/SeleniumDocs
```

## Running the Tests
### Restore dependencies
Install necessary dependencies using the .NET CLI:

```bash
dotnet restore
```

### Run all tests
To run all available tests:

```bash
dotnet test
```

### Run a Specific Test Method
To run a specific test method using its fully qualified name:

```bash
dotnet test --filter "FullyQualifiedName=Namespace.ClassName.MethodName"
```
For example:
```bash
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

You can also filter by test name only (if it's unique):
```bash
dotnet test --filter "Name=EightComponents"
```
````

```md
bundle exec rspec
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/README.md#L26)

##### /examples/ruby/README.md

````md
# Running all tests from Selenium ruby example

Follow these steps to run all test example from selenium ruby

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `ruby` directory

```
cd seleniumhq.github.io/examples/ruby
```

3. Install dependencies using bundler

```
bundler install
```

4. Run all tests

```
bundle exec rspec
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a ruby script

Use this command to run a ruby script and follow the first script example

```
ruby example_script.rb
```
````

### Mocha

```shell
mocha runningTests.spec.js
```

### npx

```shell
npx mocha runningTests.spec.js
```

[Add Example](/documentation/about/contributing/#creating-examples)

### 示例

在[第一个脚本](https://www.selenium.dev/zh-cn/documentation/webdriver/getting_started/first_script/)一节中，我们了解了 Selenium 脚本的每一个组件。 这里是使用 test runner 重新组织那个脚本的一个示例：

*
*
*
*
*
*

```java
package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java)

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py)

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted
{
    [TestClass]
    public class UsingSeleniumTest
    {

        [TestMethod]
        public void EightComponents()
        {
            IWebDriver driver = new ChromeDriver();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

            var title = driver.Title;
            Assert.AreEqual("Web form", title);

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            var textBox = driver.FindElement(By.Name("my-text"));
            var submitButton = driver.FindElement(By.TagName("button"));
            
            textBox.SendKeys("Selenium");
            submitButton.Click();
            
            var message = driver.FindElement(By.Id("message"));
            var value = message.Text;
            Assert.AreEqual("Received!", value);
            
            driver.Quit();
        }
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs)

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb)

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js)

[Add Example](/documentation/about/contributing/#creating-examples)

## 下一步

使用你目前所学到的知识构建你自己的 Selenium 代码吧！

想要了解更多的功能特性， 请继续阅读我们接下来的[WebDriver 教程](https://www.selenium.dev/zh-cn/documentation/webdriver/)

----
url: https://www.selenium.dev/pt-br/documentation/grid/advanced_features/graphql_support/
----

# Suporte a buscas em GraphQL

```shell
{
    session(id: "<session-id>") : {
        id,
        capabilities,
        startTime,
        uri,
        nodeId,
        nodeUri,
        sessionDurationMillis
        slot : {
            id,
            stereotype,
            lastStarted
        }
    }
    grid: {
        uri,
        totalSlots,
        nodeCount,
        maxSession,
        sessionCount,
        version,
        sessionQueueSize
    }
    sessionsInfo: {
        sessionQueueRequests,
        sessions: [
            {
                id,
                capabilities,
                startTime,
                uri,
                nodeId,
                nodeUri,
                sessionDurationMillis
                slot : {
                    id,
                    stereotype,
                    lastStarted
                }
            }
        ]
    }
    nodesInfo: {
        nodes : [
            {
                id,
                uri,
                status,
                maxSession,
                slotCount,
                sessions: [
                    {
                        id,
                        capabilities,
                        startTime,
                        uri,
                        nodeId,
                        nodeUri,
                        sessionDurationMillis
                        slot : {
                            id,
                            stereotype,
                            lastStarted
                        }
                    }
                ],
                sessionCount,
                stereotypes,
                version,
                osInfo: {
                    arch,
                    name,
                    version
                }
            }
        ]
    }
}
```

## Consultando GraphQL

O melhor jeito de consultar GraphQL é utilizando requisições `curl`. GraphQL permite que você busque apenas os dados que você quer, nada mais, anda menos.

Alguns exemplos de buscas em GraphQL estão abaixo. Você pode montar as queries como quiser.

### Buscando o número total de slots (`maxSession`) e slots usados (`sessionCount`) na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ grid { maxSession, sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

Geralmente na máquina local o `<LINK_TO_GRAPHQL_ENDPOINT>` será `http://localhost:4444/graphql`

### Buscando todos os detalhes da Sessão, Nó e Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { uri, maxSession, sessionCount }, nodesInfo { nodes { id, uri, status, sessions { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } }, slotCount, sessionCount }} }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando o número de sessões atual na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando a contagem máxima de sessões na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { maxSession } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando todos os detalhes de todas as sessões de todos os nós na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, capabilities, startTime, uri, nodeId, nodeId, sessionDurationMillis } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando informações dos slots de todas as sessões de cada Nó na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, slot { id, stereotype, lastStarted } } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando informação da sessão para uma sessão específica:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ session (id: \"<session-id>\") { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } } } "}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando os recursos de cada nó na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { stereotypes } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando o status de cada Nó na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { status } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando a URI de cada Nó e da Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { uri } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the current requests in the New Session Queue:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessionQueueRequests } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the New Session Queue size :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionQueueSize } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

Última modificação January 24, 2022: [Properly parse quotes for GraphQl query's session id (#941) \[deploy site\] (548fa83a491)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/548fa83a491330341485e5667d5053743f8e313c)

----
url: https://www.selenium.dev/documentation/webdriver/getting_started/install_library/
----

# Install a Selenium library

```xml
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/pom.xml#L35-L38)

##### /examples/java/pom.xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>dev.selenium</groupId>
    <artifactId>selenium-examples</artifactId>
    <version>1.0.0</version>

    <properties>
        <surefire.parallel>1</surefire.parallel>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <selenium.version>4.41.0</selenium.version>
    </properties>

    <repositories>
        <repository>
            <name>Central Portal Snapshots</name>
            <id>central-portal-snapshots</id>
            <url>https://central.sonatype.com/repository/maven-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-grid</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>6.0.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.titusfortner</groupId>
            <artifactId>selenium-logger</artifactId>
            <version>2.4.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.5.5</version>
                <configuration>
                    <properties>
                        <configurationParameters>
                            junit.jupiter.execution.parallel.enabled = true
                            junit.jupiter.execution.parallel.mode.default = concurrent
                            junit.jupiter.execution.parallel.config.strategy = fixed
                            junit.jupiter.execution.parallel.config.fixed.parallelism = ${surefire.parallel}
                            junit.jupiter.execution.parallel.config.fixed.max-pool-size = ${surefire.parallel}
                        </configurationParameters>
                    </properties>
                    <rerunFailingTestsCount>3</rerunFailingTestsCount>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
```

### Gradle

Specify the dependency in the project `build.gradle` file as `testImplementation`:

```gradle

dependencies {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/build.gradle#L13-L14)

##### /examples/java/build.gradle

```gradle
plugins {
    id 'java'
}

group 'dev.selenium'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

ext['seleniumVersion'] = System.getProperty('selenium.version', '4.41.0')

dependencies {
    testImplementation "org.seleniumhq.selenium:selenium-java:${seleniumVersion}"
    testImplementation "org.seleniumhq.selenium:selenium-grid:${seleniumVersion}"
    testImplementation platform("org.junit:junit-bom:6.0.2")
    testImplementation 'org.junit.jupiter:junit-jupiter-engine'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    testImplementation 'com.titusfortner:selenium-logger:2.4.0'
}

test {
    useJUnitPlatform()
}
```

The minimum supported Python version for each Selenium version can be found in “Supported Python Versions” on [PyPi](https://pypi.org/project/selenium/).

There are a couple different ways to install Selenium.

### Pip

```shell
pip install selenium
```



### Download

Alternatively you can download the [PyPI Built Distribution](https://pypi.org/project/selenium/#files) (selenium-x.x.x.-py3-none-any.whl) and install it using *pip*:

```shell
pip install selenium-x.x.x.-py3-none-any.whl
```



### Require in project

To use it in a project, add it to the `requirements.txt` file:

```txt
selenium==4.41.0
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/requirements.txt#L1)

##### /examples/python/requirements.txt

```txt
selenium==4.41.0
pytest==9.0.3
trio==0.31.0
pytest-trio==0.8.0
pytest-rerunfailures==16.1
flake8==7.3.0
requests==2.33.0
tox==4.32.0
pytest-xdist==3.8.0
```

A list of all supported frameworks for each version of Selenium is available on [Nuget](https://www.nuget.org/packages/Selenium.WebDriver)

There are a few options for installing Selenium.

### Packet Manager

```shell
Install-Package Selenium.WebDriver
```



### .NET CLI

```shell
dotnet add package Selenium.WebDriver
```



### CSProj

in the project’s `csproj` file, specify the dependency as a `PackageReference` in `ItemGroup`:

```csproj
      <PackageReference Include="Selenium.WebDriver" Version="4.41.0" />
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/SeleniumDocs.csproj#L14)

##### /examples/dotnet/SeleniumDocs/SeleniumDocs.csproj

```csproj
<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <GenerateProgramFile>false</GenerateProgramFile>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
      <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="7.7.1" />
      <PackageReference Include="MSTest.TestAdapter" Version="3.6.0" />
      <PackageReference Include="MSTest.TestFramework" Version="3.6.0" />
      <PackageReference Include="Selenium.Support" Version="4.41.0" />
      <PackageReference Include="Selenium.WebDriver" Version="4.41.0" />
    </ItemGroup>

    <ItemGroup>
      <Folder Include="LocalPackages" />
    </ItemGroup>

</Project>
```

### Additional considerations

Further items of note for using Visual Studio Code (vscode) and C#

Install the compatible .NET SDK as per the section above. Also install the vscode extensions (Ctrl-Shift-X) for C# and NuGet. Follow the [instruction here](https://docs.microsoft.com/en-us/dotnet/core/tutorials/with-visual-studio-code?pivots=dotnet-5-0) to create and run the “Hello World” console project using C#. You may also create a NUnit starter project using the command line `dotnet new NUnit`. Make sure the file `%appdata%\NuGet\nuget.config` is configured properly as some developers reported that it will be empty due to some issues. If `nuget.config` is empty, or not configured properly, then .NET builds will fail for Selenium Projects. Add the following section to the file `nuget.config` if it is empty:

```
<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />   
  </packageSources>
...
```

For more info about `nuget.config` [click here](https://docs.microsoft.com/en-us/nuget/reference/nuget-config-file). You may have to customize `nuget.config` to meet you needs.

Now, go back to vscode, press Ctrl-Shift-P, and type “NuGet Add Package”, and enter the required Selenium packages such as `Selenium.WebDriver`. Press Enter and select the version. Now you can use the examples in the documentation related to C# with vscode.

You can see the minimum required version of Ruby for any given Selenium version on [rubygems.org](https://rubygems.org/gems/selenium-webdriver/)

Selenium can be installed two different ways.

### Install manually

```shell
gem install selenium-webdriver
```



### Add to project’s gemfile

```gemfile
gem 'selenium-devtools', '= 0.147.0'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/Gemfile#L10)

##### /examples/ruby/Gemfile

```gemfile
# frozen_string_literal: true

source 'https://rubygems.org'

gem 'ffi', '~> 1.15', '>= 1.15.5' if Gem.win_platform? # Windows only
gem 'rake', '~> 13.0'
gem 'rspec', '~> 3.0'
gem 'rubocop', '~> 1.35'
gem 'rubocop-rspec', '~> 3.0'
gem 'selenium-devtools', '= 0.147.0'
gem 'selenium-webdriver', '= 4.43.0'
```

You can find the minimum required version of Node for any given version of Selenium in the `Node Support Policy` section on [npmjs](https://www.npmjs.com/package/selenium-webdriver)

Selenium is typically installed using npm.

### Install locally

```shell
npm install selenium-webdriver
```



### Add to project

In your project’s `package.json`, add requirement to `dependencies`:

```json
        "mocha": "11.7.5"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/package.json#L14)

##### /examples/javascript/package.json

```json
{
    "name": "javascript-examples",
    "version": "1.0.0",
    "scripts": {
        "test": "npx mocha test/**/*.spec.js --timeout 120000 --parallel --retries 2"
    },
    "author": "The Selenium project",
    "license": "Apache-2.0",
    "dependencies": {
        "assert": "2.1.0",
        "selenium-webdriver": "4.41.0"
    },
    "devDependencies": {
        "mocha": "11.7.5"
    }
}
```

Use the Java bindings for Kotlin.

## Next Step

[Create your first Selenium script](https://www.selenium.dev/documentation/webdriver/getting_started/first_script/)

Last modified September 2, 2025: [fixed line number to show case selenium maven dependency (#2450) (845ea50bbac)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/845ea50bbac1131c18ea2735554c1611e5369777)

----
url: https://www.selenium.dev/documentation/about/style/
----

# Style guide for Selenium documentation

Conventions for contributions to the Selenium documentation and code examples

Read our [contributing documentation](https://www.selenium.dev/documentation/about/contributing/) for complete instructions on how to add content to this documentation.

## Alerts

Alerts have been added to direct potential contributors to where specific content is missing.

```html
{{< alert-content />}}
```

or

```html
{{< alert-content >}}
Additional information about what specific content is needed
{{< /alert-content >}}
```

```java
WebDriver driver = new ChromeDriver();
```

```python
driver = webdriver.Chrome()
```

```csharp
var driver = new ChromeDriver();
```

```ruby
driver = Selenium::WebDriver.for :chrome
```

```javascript
let driver = await new Builder().forBrowser('chrome').build();
```

```kotlin
val driver = ChromeDriver()
```

To generate the above tabs, this is what you need to write. Note that the `tabpane` includes `langEqualsHeader=true`. This auto-formats the code in each tab to match the header name, and ensures that all tabs on the page with a language are set to the same thing.

```
{{< tabpane langEqualsHeader=true >}}
  {{< tab header="Java" >}}
    WebDriver driver = new ChromeDriver();
  {{< /tab >}}
  {{< tab header="Python" >}}
    driver = webdriver.Chrome()
  {{< /tab >}}
  {{< tab header="CSharp" >}}
    var driver = new ChromeDriver();
  {{< /tab >}}
  {{< tab header="Ruby" >}}
    driver = Selenium::WebDriver.for :chrome
  {{< /tab >}}
  {{< tab header="JavaScript" >}}
    let driver = await new Builder().forBrowser('chrome').build();
  {{< /tab >}}
  {{< tab header="Kotlin" >}}
    val driver = ChromeDriver()
  {{< /tab >}}
{{< /tabpane >}}
```

#### Reference GitHub Examples

To ensure that all code is kept up to date, our goal is to write the code in the repo where it can be executed when Selenium versions are updated to ensure that everything is correct.

All code examples to be in our [example directories](https://github.com/SeleniumHQ/seleniumhq.github.io/tree/dev/examples).

This code can be automatically displayed in the documentation using the `gh-codeblock` shortcode. The shortcode automatically generates its own html, so we do not want it to auto-format with the language header. If all tabs are using this shortcode, set `text=true` in the `tabpane` and remove `langEqualsHeader=true`. If only some tabs are using this shortcode, keep `langEqualsHeader=true` in the `tabpane` and add `text=true` to the `tab`. Note that the `gh-codeblock` line can not be indented at all.

One great thing about using `gh-codeblock` is that it adds a link to the full example. This means you don’t have to include any additional context code, just the line(s) that are needed, and the user can navigate to the repo to see how to use it.

A basic comparison of code looks like:

```
{{< tabpane text=true >}}
{{< tab header="Java" >}}
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-L27" >}}
{{< /tab >}}
{{< tab header="Python" >}}
{{< gh-codeblock path="/examples/python/tests/getting_started/first_script.py#L18-L19" >}}
{{< /tab >}}
{{< tab header="CSharp" >}}
{{< gh-codeblock path="/examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-L26" >}}
{{< /tab >}}
{{< tab header="Ruby" >}}
{{< gh-codeblock path="/examples/ruby/spec/getting_started/first_script.rb#L17-L18" >}}
{{< /tab >}}
{{< tab header="JavaScript" >}}
{{< gh-codeblock path="/examples/javascript/test/getting_started/firstScript.spec.js#L22-L23" >}}
{{< /tab >}}
{{< tab header="Kotlin" >}}
{{< gh-codeblock path="/examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-L32" >}}
{{< /tab >}}
{{< /tabpane >}}
```

```java
        WebElement message = driver.findElement(By.id("message"));
        message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-L27)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
message = driver.find_element(by=By.ID, value="message")
text = message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L18-L19)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-L26)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
message = driver.find_element(id: 'message')
message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L17-L18)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L22-L23)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val message = driver.findElement(By.id("message"))
        val value = message.getText()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-L32)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

### Using Markdown in a Tab

If you want your example to include something other than code (default) or html (from `gh-codeblock`), you need to first set `text=true`, then change the Hugo syntax for the `tab`to use `%` instead of `<` and `>` with curly braces:

```
{{< tabpane text=true >}}
{{% tab header="Java" %}}
1. Start the driver
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12" >}}
2. Navigate to a page
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14" >}}
3. Quit the driver
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29" >}}
{{% /tab %}}
< ... >
{{< /tabpane >}}
```

This produces:

*

1. Start the driver

   ```java
           WebDriver driver = new ChromeDriver();
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

2. Navigate to a page

   ```java
           driver.get("https://www.selenium.dev/selenium/web/web-form.html");
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

3. Quit the driver

   ```java
           driver.quit();
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

This is preferred to writing code comments because those will not be translated. Only include the code that is needed for the documentation, and avoid over-explaining. Finally, remember not to indent plain text or it will rendered as a codeblock.

----
url: https://www.selenium.dev/ja/_print/documentation/test_practices/encouraged/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/test_practices/encouraged/).

# 推奨された行動

Seleniumプロジェクトからのテストに関するいくつかのガイドラインと推奨事項

* 1: [ページオブジェクトモデル](#pg-42bae4628f031de88c649b709ec0f8c6)
* 2: [ドメイン固有言語（DSL）](#pg-733a3a2cedeac8ca6de96d3d413edbd9)
* 3: [アプリケーション状態の生成](#pg-cfd646f6a4f65016394c853e4d80d659)
* 4: [モック外部サービス](#pg-62c8faa9fe4698bf3ed3466cbd528ff0)
* 5: [改善されたレポート](#pg-00238dd2c8fbe56f45215ed579d9e3ca)
* 6: [ロケータをうまく扱うTips](#pg-2cf63df95d95443722f314e0c8512887)
* 7: [状態を共有しない](#pg-40c3ab25efecc76d33c7f383e0826b87)
* 8: [テストの独立性](#pg-6d60e52a318221cb890ffeae48c949d5)
* 9: [Fluent APIの使用を検討する](#pg-29a52db54ab1f274413bf1630d2644e6)
* 10: [テストごとに新しいブラウザを起動する](#pg-58a1235b5fcacba8271f76d27a479aaa)

「ベストプラクティス」に関するメモ：このドキュメントでは、“ベストプラクティス"というフレーズを意図的に避けています。 すべての状況に有効なアプローチはありません。 “ガイドラインとレコメンデーション"というアイデアを好みます。 これらを一通り読み、特定の環境でどのアプローチが効果的かを慎重に決定することをお勧めします。

機能テストは、多くの理由で適切に行うのが困難です。 まるでアプリケーションの状態、複雑さ、および依存関係が、テストを十分に難しくしないと思えるほど、ブラウザ（特にクロスブラウザの非互換性）を扱うのは、良いテストの作成を難しくします。

Seleniumは、機能的なユーザーインタラクションを簡単にするツールを提供しますが、適切に設計されたテストスイートの作成には役立ちません。 この章では、機能的なWebページの自動化に取り組む方法に関するアドバイス、ガイドライン、および推奨事項を提供します。

この章では、長年にわたって成功を収めてきたSeleniumの多くのユーザーの間で人気のあるソフトウェア設計パターンを記録します。

# 1 - ページオブジェクトモデル

```java
/***
 * Tests login feature
 */
public class Login {

  public void testLogin() {
    // fill login data on sign-in page
    driver.findElement(By.name("user_name")).sendKeys("userName");
    driver.findElement(By.name("password")).sendKeys("my supersecret password");
    driver.findElement(By.name("sign-in")).click();

    // verify h1 tag is "Hello userName" after login
    driver.findElement(By.tagName("h1")).isDisplayed();
    assertThat(driver.findElement(By.tagName("h1")).getText(), is("Hello userName"));
  }
}
```

There are two problems with this approach.

* There is no separation between the test method and the AUT’s locators (IDs in this example); both are intertwined in a single method. If the AUT’s UI changes its identifiers, layout, or how a login is input and processed, the test itself must change.
* The ID-locators would be spread in multiple tests, in all tests that had to use this login page.

Applying the page object model, this example could be rewritten like this in the following example of a page object for a Sign-in page.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Sign-in page.
 */
public class SignInPage {
  protected WebDriver driver;

  // <input name="user_name" type="text" value="">
  private By usernameBy = By.name("user_name");
  // <input name="password" type="password" value="">
  private By passwordBy = By.name("password");
  // <input name="sign_in" type="submit" value="SignIn">
  private By signinBy = By.name("sign_in");

  public SignInPage(WebDriver driver){
    this.driver = driver;
     if (!driver.getTitle().equals("Sign In Page")) {
      throw new IllegalStateException("This is not Sign In Page," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Login as valid user
    *
    * @param userName
    * @param password
    * @return HomePage object
    */
  public HomePage loginValidUser(String userName, String password) {
    driver.findElement(usernameBy).sendKeys(userName);
    driver.findElement(passwordBy).sendKeys(password);
    driver.findElement(signinBy).click();
    return new HomePage(driver);
  }
}
```

and page object for a Home page could look like this.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Home Page
 */
public class HomePage {
  protected WebDriver driver;

  // <h1>Hello userName</h1>
  private By messageBy = By.tagName("h1");

  public HomePage(WebDriver driver){
    this.driver = driver;
    if (!driver.getTitle().equals("Home Page of logged in user")) {
      throw new IllegalStateException("This is not Home Page of logged in user," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Get message (h1 tag)
    *
    * @return String message text
    */
  public String getMessageText() {
    return driver.findElement(messageBy).getText();
  }

  public HomePage manageProfile() {
    // Page encapsulation to manage profile functionality
    return new HomePage(driver);
  }
  /* More methods offering the services represented by Home Page
  of Logged User. These methods in turn might return more Page Objects
  for example click on Compose mail button could return ComposeMail class object */
}
```

So now, the login test would use these two page objects as follows.

```java
/***
 * Tests login feature
 */
public class TestLogin {

  @Test
  public void testLogin() {
    SignInPage signInPage = new SignInPage(driver);
    HomePage homePage = signInPage.loginValidUser("userName", "password");
    assertThat(homePage.getMessageText(), is("Hello userName"));
  }

}
```

```html
<!-- Products Page -->
<div class="header_container">
    <span class="title">Products</span>
</div>

<div class="inventory_list">
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
</div>
```

Each product is a component of the Products page.

```html
<!-- Inventory Item -->
<div class="inventory_item">
    <div class="inventory_item_name">Backpack</div>
    <div class="pricebar">
        <div class="inventory_item_price">$29.99</div>
        <button id="add-to-cart-backpack">Add to cart</button>
    </div>
</div>
```

The Products page HAS-A list of products. This object relationship is called Composition. In simpler terms, something is *composed of* another thing.

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

// Page Object
public class ProductsPage extends BasePage {
    public ProductsPage(WebDriver driver) {
        super(driver);
        // No assertions, throws an exception if the element is not loaded
        new WebDriverWait(driver, Duration.ofSeconds(3))
            .until(d -> d.findElement(By.className​("header_container")));
    }

    // Returning a list of products is a service of the page
    public List<Product> getProducts() {
        return driver.findElements(By.className​("inventory_item"))
            .stream()
            .map(e -> new Product(e)) // Map WebElement to a product component
            .toList();
    }

    // Return a specific product using a boolean-valued function (predicate)
    // This is the behavioral Strategy Pattern from GoF
    public Product getProduct(Predicate<Product> condition) {
        return getProducts()
            .stream()
            .filter(condition) // Filter by product name or price
            .findFirst()
            .orElseThrow(() -> new RuntimeException("Product not found")); // Error thrown during actual test run
    }
}
```

The Product component object is used inside the Products page object.

```java
public abstract class BaseComponent {
    protected WebElement root;

    public BaseComponent(WebElement root) {
        this.root = root;
    }
}

// Page Component Object
public class Product extends BaseComponent {
    // The root element contains the entire component
    public Product(WebElement root) {
        super(root); // inventory_item
    }

    public String getName() {
        // Locating an element begins at the root of the component
        return root.findElement(By.className("inventory_item_name")).getText();
    }

    public BigDecimal getPrice() {
        return new BigDecimal(
                root.findElement(By.className("inventory_item_price"))
                    .getText()
                    .replace("$", "")
            ).setScale(2, RoundingMode.UNNECESSARY); // Sanitation and formatting
    }

    public void addToCart() {
        root.findElement(By.id("add-to-cart-backpack")).click();
    }
}
```

So now, the products test would use the page object and the page component object as follows.

```java
public class ProductsTest {
    @Test
    public void testProductInventory() {
        var productsPage = new ProductsPage(driver); // page object
        var products = productsPage.getProducts();
        assertEquals(6, products.size()); // expected, actual
    }
    
    @Test
    public void testProductPrices() {
        var productsPage = new ProductsPage(driver);

        // Pass a lambda expression (predicate) to filter the list of products
        // The predicate or "strategy" is the behavior passed as parameter
        var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); // page component object
        var bikeLight = productsPage.getProduct(p -> p.getName().equals("Bike Light"));

        assertEquals(new BigDecimal("29.99"), backpack.getPrice());
        assertEquals(new BigDecimal("9.99"), bikeLight.getPrice());
    }
}
```

```java
public class LoginPage {
    public HomePage loginAs(String username, String password) {
        // ... clever magic happens here
    }
    
    public LoginPage loginAsExpectingError(String username, String password) {
        //  ... failed login here, maybe because one or both of the username and password are wrong
    }
    
    public String getErrorMessage() {
        // So we can verify that the correct error is shown
    }
}
```

The code presented above shows an important point: the tests, not the Page Objects, should be responsible for making assertions about the state of a page. For example:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    inbox.assertMessageWithSubjectIsUnread("I like cheese");
    inbox.assertMessageWithSubjectIsNotUnread("I'm not fond of tofu");
}
```

could be re-written as:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    assertTrue(inbox.isMessageWithSubjectIsUnread("I like cheese"));
    assertFalse(inbox.isMessageWithSubjectIsUnread("I'm not fond of tofu"));
}
```

```java
public class LoginPage {
    private final WebDriver driver;

    public LoginPage(WebDriver driver) {
        this.driver = driver;

        // Check that we're on the right page.
        if (!"Login".equals(driver.getTitle())) {
            // Alternatively, we could navigate to the login page, perhaps logging out first
            throw new IllegalStateException("This is not the login page");
        }
    }

    // The login page contains several HTML elements that will be represented as WebElements.
    // The locators for these elements should only be defined once.
        By usernameLocator = By.id("username");
        By passwordLocator = By.id("passwd");
        By loginButtonLocator = By.id("login");

    // The login page allows the user to type their username into the username field
    public LoginPage typeUsername(String username) {
        // This is the only place that "knows" how to enter a username
        driver.findElement(usernameLocator).sendKeys(username);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to type their password into the password field
    public LoginPage typePassword(String password) {
        // This is the only place that "knows" how to enter a password
        driver.findElement(passwordLocator).sendKeys(password);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to submit the login form
    public HomePage submitLogin() {
        // This is the only place that submits the login form and expects the destination to be the home page.
        // A seperate method should be created for the instance of clicking login whilst expecting a login failure. 
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the login page ever
        // go somewhere else (for example, a legal disclaimer) then changing the method signature
        // for this method will mean that all tests that rely on this behaviour won't compile.
        return new HomePage(driver);	
    }

    // The login page allows the user to submit the login form knowing that an invalid username and / or password were entered
    public LoginPage submitLoginExpectingFailure() {
        // This is the only place that submits the login form and expects the destination to be the login page due to login failure.
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the user ever be navigated to the home page after submiting a login with credentials 
        // expected to fail login, the script will fail when it attempts to instantiate the LoginPage PageObject.
        return new LoginPage(driver);	
    }

    // Conceptually, the login page offers the user the service of being able to "log into"
    // the application using a user name and password. 
    public HomePage loginAs(String username, String password) {
        // The PageObject methods that enter username, password & submit login have already defined and should not be repeated here.
        typeUsername(username);
        typePassword(password);
        return submitLogin();
    }
}
```

# 2 - ドメイン固有言語（DSL）

```java
/**
 * Takes a username and password, fills out the fields, and clicks "login".
 * @return An instance of the AccountPage
 */
public AccountPage loginAsUser(String username, String password) {
  WebElement loginField = driver.findElement(By.id("loginField"));
  loginField.clear();
  loginField.sendKeys(username);

  // Fill out the password field. The locator we're using is "By.id", and we should
  // have it defined elsewhere in the class.
  WebElement passwordField = driver.findElement(By.id("password"));
  passwordField.clear();
  passwordField.sendKeys(password);

  // Click the login button, which happens to have the id "submit".
  driver.findElement(By.id("submit")).click();

  // Create and return a new instance of the AccountPage (via the built-in Selenium
  // PageFactory).
  return PageFactory.newInstance(AccountPage.class);
}
```

このメソッドは、テストコードから入力フィールド、ボタン、クリック、さらにはページの概念を完全に抽象化します。 このアプローチを使用すると、テスターはこのメソッドを呼び出すだけで済みます。 これにより、メンテナンスの利点が得られます。 ログインフィールドが変更された場合、テストではなく、このメソッドを変更するだけで済みます。

```java
public void loginTest() {
    loginAsUser("cbrown", "cl0wn3");

    // Now that we're logged in, do some other stuff--since we used a DSL to support
    // our testers, it's as easy as choosing from available methods.
    do.something();
    do.somethingElse();
    Assert.assertTrue("Something should have been done!", something.wasDone());

    // Note that we still haven't referred to a button or web control anywhere in this
    // script...
}
```

繰り返しになります。 主な目標の1つは、 テストが **UIの問題ではなく、手元の問題** に対処できるAPIを作成することです。 UIはユーザーにとって二次的な関心事です。ユーザーはUIを気にせず、ただ仕事をやりたいだけです。 テストスクリプトは、ユーザーがやりたいことと知りたいことの長々としたリストのように読む必要があります。 テストでは、UIがどのようにそれを実行するように要求するかについて、気にするべきではありません。

\***AUT**: Application under test（テスト対象アプリケーション）

# 3 - アプリケーション状態の生成

Seleniumはテストケースの準備に使用しないでください。 テストケースのすべての反復アクションと準備は、他の方法で行う必要があります。 たとえば、ほとんどのWeb UIには認証があります（ログインフォームなど）。 すべてのテストの前にWebブラウザーからのログインをなくすことで、テストの速度と安定性の両方が向上します。 AUT\* にアクセスするためのメソッドを作成する必要があります（APIを使用してログインし、Cookieを設定するなど）。 また、テスト用にデータをプリロードするメソッドの作成は、Seleniumを使用して実行しないほうがいいです。 前述のように、AUT\* のデータを作成するには、既存のAPIを活用する必要があります。

\***AUT**: Application under test（テスト対象アプリケーション）

# 4 - モック外部サービス

外部サービスへの依存を排除すると、テストの速度と安定性が大幅に向上します。

# 5 - 改善されたレポート

Seleniumは、実行されたテストケースのステータスをレポートするようには設計されていません。 単体テストフレームワークの組み込みのレポート機能を利用することは、良いスタートです。 ほとんどの単体テストフレームワークには、xUnitまたはHTML形式のレポートを生成できるレポートがあります。 xUnitレポートは、Jenkins、Travis、Bambooなどの継続的インテグレーション（CI）サーバーに結果をインポートするのに人気があります。 いくつかの言語のレポート出力に関する詳細情報へのリンクがあります。

[NUnit 3 Console Runner](//github.com/nunit/docs/wiki/Console-Runner)

[NUnit 3 Console Command Line](//github.com/nunit/docs/wiki/Console-Command-Line)

[xUnit getting test results in TeamCity](//xunit.net/docs/getting-test-results-in-teamcity)

[xUnit getting test results in CruiseControl.NET](//xunit.net/docs/getting-test-results-in-ccnet)

[xUnit getting test results in Azure DevOps](//xunit.net/docs/getting-test-results-in-azure-devops)

# 6 - ロケータをうまく扱うTips

# 7 - 状態を共有しない

いくつかの場所で言及されていますが、再度言及する価値があります。 テストが互いに分離されていることを確認してください。

* テストデータを共有しないでください。 アクションを実行する1つを選択する前に、それぞれが有効な注文をデータベースに照会するいくつかのテストを想像してください。 2つのテストで同じ順序を選択すると、予期しない動作が発生する可能性があります。

* 別のテストで取得される可能性のあるアプリケーション内の古いデータを削除します。 例: 無効な注文レコード

* テストごとに新しいWebDriverインスタンスを作成します。 これにより、テストの分離が保証され、並列化がより簡単になります。

  * If you choose [pytest](https://pytest.org/) as your test runner, this can be easily done by yielding your driver in a global fixture. This way each test gets its own driver instance, and you can ensure that drivers always quit after a test is finished (pass or fail).

# 8 - テストの独立性

各テストを独自のユニットとして記述します。 他のテストに依存しない方法でテストを記述してください。

公開後にモジュールとしてWebサイトに表示されるカスタムコンテンツを作成できるコンテンツ管理システム（CMS）があり、CMSとアプリケーション間の同期に時間がかかる場合があるとします。

モジュールをテストする間違った方法は、1つのテストでコンテンツが作成および公開され、別のテストでモジュールをチェックすることです。 コンテンツは公開後、他のテストですぐに利用できない可能性があるため、この方法はふさわしくありません。

代わりに、影響を受けるテスト内でオン/オフできるスタブコンテンツを作成し、それをモジュールの検証に使用できます。 ただし、コンテンツの作成については、別のテストを行うことができます。

# 9 - Fluent APIの使用を検討する

マーチン・ファウラーは[“Fluent API”](//www.martinfowler.com/bliki/FluentInterface.html)という用語を作り出しました。 Seleniumは既に、`FluentWait`クラスでこのようなものを実装しています。 これは、標準の`Wait`クラスの代替としてのものです。 ページオブジェクトでFluent APIデザインパターンを有効にしてから、次のようなコードスニペットを使用してGoogle検索ページを照会できます。

```java
driver.get( "http://www.google.com/webhp?hl=en&amp;tab=ww" );
GoogleSearchPage gsp = new GoogleSearchPage(driver);
gsp.setSearchString().clickSearchButton();
```

この流暢な動作を持つGoogleページオブジェクトクラスは次のようになります。

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

public class GoogleSearchPage extends BasePage {
    public GoogleSearchPage(WebDriver driver) {
        super(driver);
        // Generally do not assert within pages or components.
        // Effectively throws an exception if the lambda condition is not met.
        new WebDriverWait(driver, Duration.ofSeconds(3)).until(d -> d.findElement(By.id("logo")));
    }

    public GoogleSearchPage setSearchString(String sstr) {
        driver.findElement(By.id("gbqfq")).sendKeys(sstr);
        return this;
    }

    public void clickSearchButton() {
        driver.findElement(By.id("gbqfb")).click();
    }
}
```

# 10 - テストごとに新しいブラウザを起動する

クリーンな既知の状態から各テストを開始します。 理想的には、テストごとに新しい仮想マシンを起動します。 新しい仮想マシンの起動が実用的でない場合は、少なくともテストごとに新しいWebDriverを起動してください。 Firefoxの場合、既知のプロファイルでWebDriverを起動します。 Most browser drivers like GeckoDriver and ChromeDriver will start with a clean known state with a new user profile, by default.

```java
WebDriver driver = new FirefoxDriver();
```

----
url: https://www.selenium.dev/ja/documentation/webdriver/browsers/internet_explorer/
----

# IE特有の機能

```java
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#38-L41)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

```py
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L11-L14)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L35-L38)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

```rb
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L17-L20)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#46-L47)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

```py
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L21-L22)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L44-L45)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L24-L25)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
let driver = await new Builder()
.forBrowser('internet explorer')
.setIEOptions(options)
.build();
```

```kotlin
<p><a href=/documentation/about/contributing/#moving-examples>
<span class="selenium-badge-code" data-bs-toggle="tooltip" data-bs-placement="right"
      title="One or more of these examples need to be implemented in the examples directory; click for details in the contribution guide">Move Code</span></a></p>


val options = InternetExplorerOptions()
val driver = InternetExplorerDriver(options)
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.waitForUploadDialogUpTo(Duration.ofSeconds(2));
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L28-L29)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.FileUploadDialogTimeout = TimeSpan.FromMilliseconds(2000);
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.file_upload_dialog_timeout = 2000
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L29)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().fileUploadDialogTimeout(2000);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.waitForUploadDialogUpTo(Duration.ofSeconds(2))
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.destructivelyEnsureCleanSession();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ensure_clean_session = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L38-L39)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.EnsureCleanSession = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ensure_clean_session = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L35)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().ensureCleanSession(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.destructivelyEnsureCleanSession()
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.ignoreZoomSettings();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L48-L49)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.IgnoreZoomLevel = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ignore_zoom_level = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L41)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().ignoreZoomSetting(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.ignoreZoomSettings()
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.introduceFlakinessByIgnoringSecurityDomains();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L58-L59)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.IntroduceInstabilityByIgnoringProtectedModeSettings = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ignore_protected_mode_settings = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L47)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().introduceFlakinessByIgnoringProtectedModeSettings(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.introduceFlakinessByIgnoringSecurityDomains()
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.setCapability("silent", true);
WebDriver driver = new InternetExplorerDriver(options);
  
```

```py
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L68-L69)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
InternetExplorerOptions options = new InternetExplorerOptions();
options.AddAdditionalInternetExplorerOption("silent", true);
IWebDriver driver = new InternetExplorerDriver(options);
  
```

```rb
      @options.silent = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L53)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const {Builder,By, Capabilities} = require('selenium-webdriver');
let caps = Capabilities.ie();
caps.set('silent', true);

(async function example() {
    let driver = await new Builder()
        .forBrowser('internet explorer')
        .withCapabilities(caps)
        .build();
    try {
        await driver.get('http://www.google.com/ncr');
    }
    finally {
        await driver.quit();
    }
})();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.setCapability("silent", true)
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  
```

```java
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;

public class ieTest {
    public static void main(String[] args) {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.useCreateProcessApiToLaunchIe();
        options.addCommandSwitches("-k");
        InternetExplorerDriver driver = new InternetExplorerDriver(options);
        try {
            driver.get("https://google.com/ncr");
            Capabilities caps = driver.getCapabilities();
            System.out.println(caps);
        } finally {
            driver.quit();
        }
    }
}
  
```

```py
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L76-L79)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;

namespace ieTest {
 class Program {
  static void Main(string[] args) {
   InternetExplorerOptions options = new InternetExplorerOptions();
   options.ForceCreateProcessApi = true;
   options.BrowserCommandLineArguments = "-k";
   IWebDriver driver = new InternetExplorerDriver(options);
   driver.Url = "https://google.com/ncr";
  }
 }
}
  
```

```rb
      @options.add_argument('-k')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L58)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options();
options.addBrowserCommandSwitches('-k');
options.addBrowserCommandSwitches('-private');
options.forceCreateProcessApi(true);

driver = await env.builder()
          .setIeOptions(options)
          .build();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.useCreateProcessApiToLaunchIe()
    options.addCommandSwitches("-k")
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps);
    } finally {
        driver.quit()
    }
}
  
```

```java
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;

public class ieTest {
    public static void main(String[] args) {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.useCreateProcessApiToLaunchIe();
        InternetExplorerDriver driver = new InternetExplorerDriver(options);
        try {
            driver.get("https://google.com/ncr");
            Capabilities caps = driver.getCapabilities();
            System.out.println(caps);
        } finally {
            driver.quit();
        }
    }
}
  
```

```py
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L87-L90)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;

namespace ieTest {
 class Program {
  static void Main(string[] args) {
   InternetExplorerOptions options = new InternetExplorerOptions();
   options.ForceCreateProcessApi = true;
   IWebDriver driver = new InternetExplorerDriver(options);
   driver.Url = "https://google.com/ncr";
  }
 }
}
  
```

```rb
      @options.force_create_process_api = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L63)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options();
options.forceCreateProcessApi(true);

driver = await env.builder()
          .setIeOptions(options)
          .build();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.useCreateProcessApiToLaunchIe()
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}

  
```

```java
                .withLogFile(getLogLocation())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L53)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY`\
Property value: String representing path to log file

```py
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L97-L99)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L82)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
                .withLogOutput(System.out)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L67)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L109-L111)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L91)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L82)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGLEVEL_PROPERTY`\
Property value: String representation of `InternetExplorerDriverLogLevel.DEBUG.toString()` enum

```py
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L121-L123)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            if (_tempPath == null || !File.Exists(_tempPath))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L85)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '-log-level=WARN'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L102)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
                .withExtractPath(getTempDirectory())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L94)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

\*\*Note\*\*: Java also allows setting log level by System Property:\ Property key: \`InternetExplorerDriverService.IE\_DRIVER\_EXTRACT\_PATH\_PROPERTY\`\ Property value: String representing path to supporting files directory

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L133-L135)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L98)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << "–extract-path=#{root_directory}"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L112)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

----
url: https://www.selenium.dev/documentation/webdriver/support_features/listeners/
----

----
url: https://www.selenium.dev/documentation/selenium_manager/
----

```
edge can only be installed in Windows with administrator permissions
```

Therefore, administrator permissions are required to install Edge in Windows automatically through Selenium Manager, and Edge is eventually installed in the usual program files folder (e.g., `C:\Program Files (x86)\Microsoft\Edge`).

## Data collection

Selenium Manager will report anonymised usage [statistics](https://plausible.io/privacy-focused-web-analytics) to [Plausible](https://plausible.io/manager.selenium.dev). This allows the Selenium team to understand more about how Selenium is being used so that we can better focus our development efforts. The data being collected is:

| Data                                               | Purpose                                                                                                                                      |
| -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Selenium version                                   | This allows the Selenium developers to safely deprecate and remove features, as well as determine which new features may be available to you |
| Language binding                                   | Programming language used to execute Selenium scripts (Java, JavaScript, Python, .Net, Ruby)                                                 |
| OS and architecture Selenium Manager is running on | The Selenium developers can use this information to help prioritise bug reports, and to identify if there are systemic OS-related issues     |
| Browser and browser version                        | Helping for prioritising bug reports                                                                                                         |
| Rough geolocation                                  | Derived from the IP address you connect from. This is useful for determining where we need to focus our documentation efforts                |

Selenium Manager sends these data to Plausible once a day. This period is based on the TTL value (see [configuration](https://www.selenium.dev/documentation/selenium_manager/#configuration)).

### Opting out of data collection

**Data collection is on by default.** To disable it, set the `SE_AVOID_STATS` environment variable to `true`. You may also disable data collection in the configuration file (see below) by setting `avoid-stats = true`.

## Configuration

***TL;DR:*** *Selenium Manager should work silently and transparently for most users. Nevertheless, there are scenarios (e.g., to specify a custom cache path or setup globally a proxy) where custom configuration can be required.*

Selenium Manager is a CLI tool. Therefore, under the hood, the Selenium bindings call Selenium Manager by invoking shell commands. Like any other CLI tool, arguments can be used to specify specific capabilities in Selenium Manager. The different arguments supported by Selenium Manager can be checked by running the following command:

```
$ ./selenium-manager --help
```

| CLI argument                                | Configuration file                          | Env variable                               | Description                                                                                                                                                                                                                                                                             |
| ------------------------------------------- | ------------------------------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--browser BROWSER`                         | `browser = "BROWSER"`                       | `SE_BROWSER=BROWSER`                       | Browser name: `chrome`, `firefox`, `edge`, `iexplorer`, `safari`, `safaritp`, or `webview2`                                                                                                                                                                                             |
| `--driver <DRIVER>`                         | `driver = "DRIVER"`                         | `SE_DRIVER=DRIVER`                         | Driver name: `chromedriver`, `geckodriver`, `msedgedriver`, `IEDriverServer`, or `safaridriver`                                                                                                                                                                                         |
| `--browser-version <BROWSER_VERSION>`       | `browser-version = "BROWSER_VERSION"`       | `SE_BROWSER_VERSION=BROWSER_VERSION`       | Major browser version (e.g., `105`, `106`, etc. Also: `beta`, `dev`, `canary` -or `nightly`-, and `esr` -in Firefox- are accepted)                                                                                                                                                      |
| `--driver-version <DRIVER_VERSION>`         | `driver-version = "DRIVER_VERSION"`         | `SE_DRIVER_VERSION=DRIVER_VERSION`         | Driver version (e.g., `106.0.5249.61, 0.31.0`, etc.)                                                                                                                                                                                                                                    |
| `--browser-path <BROWSER_PATH>`             | `browser-path = "BROWSER_PATH"`             | `SE_BROWSER_PATH=BROWSER_PATH`             | Browser path (absolute) for browser version detection (e.g., `/usr/bin/google-chrome`, `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`, `C:\Program Files\Google\Chrome\Application\chrome.exe`)                                                                         |
| `--driver-mirror-url <DRIVER_MIRROR_URL>`   | `driver-mirror-url = "DRIVER_MIRROR_URL"`   | `SE_DRIVER_MIRROR_URL=DRIVER_MIRROR_URL`   | Mirror URL for driver repositories                                                                                                                                                                                                                                                      |
| `--browser-mirror-url <BROWSER_MIRROR_URL>` | `browser-mirror-url = "BROWSER_MIRROR_URL"` | `SE_BROWSER_MIRROR_URL=BROWSER_MIRROR_URL` | Mirror URL for browser repositories                                                                                                                                                                                                                                                     |
| `--output <OUTPUT>`                         | `output = "OUTPUT"`                         | `SE_OUTPUT=OUTPUT`                         | Output type: `LOGGER` (using `INFO`, `WARN`, etc.), `JSON` (custom JSON notation), `SHELL` (Unix-like), or `MIXED` (`INFO`, `WARN`, `DEBUG`, etc. to stderr and minimal `JSON` to stdout). Default: `LOGGER`                                                                            |
| `--os <OS>`                                 | `os = "OS"`                                 | `SE_OS=OS`                                 | Operating system for drivers and browsers (i.e., `windows`, `linux`, or `macos`)                                                                                                                                                                                                        |
| `--arch <ARCH>`                             | `arch = "ARCH"`                             | `SE_ARCH=ARCH`                             | System architecture for drivers and browsers (i.e., `x32`, `x64`, or `arm64`)                                                                                                                                                                                                           |
| `--proxy <PROXY>`                           | `proxy = "PROXY"`                           | `SE_PROXY=PROXY`                           | HTTP proxy for network connection (e.g., `myproxy:port`, `myuser:mypass@myproxy:port`)                                                                                                                                                                                                  |
| `--timeout <TIMEOUT>`                       | `timeout = TIMEOUT`                         | `SE_TIMEOUT=TIMEOUT`                       | Timeout for network requests (in seconds). Default: `300`                                                                                                                                                                                                                               |
| `--offline`                                 | `offline = true`                            | `SE_OFFLINE=true`                          | Offline mode (i.e., disabling network requests and downloads)                                                                                                                                                                                                                           |
| `--force-browser-download`                  | `force-browser-download = true`             | `SE_FORCE_BROWSER_DOWNLOAD=true`           | Force to download browser, e.g., when a browser is already installed in the system, but you want Selenium Manager to download and use it                                                                                                                                                |
| `--avoid-browser-download`                  | `avoid-browser-download = true`             | `SE_AVOID_BROWSER_DOWNLOAD=true`           | Avoid to download browser, e.g., when a browser is supposed to be downloaded by Selenium Manager, but you prefer to avoid it                                                                                                                                                            |
| `--skip-driver-in-path`                     | `skip-driver-in-path = true`                | `SE_SKIP_DRIVER_IN_PATH=true`              | Not using drivers found in the `PATH`                                                                                                                                                                                                                                                   |
| `--skip-browser-in-path`                    | `skip-browser-in-path = true`               | `SE_SKIP_BROWSER_IN_PATH=true`             | Not using browsers found in the `PATH`                                                                                                                                                                                                                                                  |
| `--debug`                                   | `debug = true`                              | `SE_DEBUG=true`                            | Display `DEBUG` messages                                                                                                                                                                                                                                                                |
| `--trace`                                   | `trace = true`                              | `SE_TRACE=true`                            | Display `TRACE` messages                                                                                                                                                                                                                                                                |
| `--cache-path <CACHE_PATH>`                 | `cache-path="CACHE_PATH"`                   | `SE_CACHE_PATH=CACHE_PATH`                 | Local folder used to store downloaded assets (drivers and browsers), local metadata, and configuration file. See next section for details. Default: `~/.cache/selenium`. For Windows paths in the TOML configuration file, double backslashes are required (e.g., `C:\\custom\\cache`). |
| `--ttl <TTL>`                               | `ttl = TTL`                                 | `SE_TTL=TTL`                               | Time-to-live in seconds. See next section for details. Default: `3600` (1 hour)                                                                                                                                                                                                         |
| `--language-binding <LANGUAGE>`             | `language-binding = "LANGUAGE"`             | `SE_LANGUAGE_BINDING=LANGUAGE`             | Language that invokes Selenium Manager (e.g., Java, JavaScript, Python, DotNet, Ruby)                                                                                                                                                                                                   |
| `--avoid-stats`                             | `avoid-stats = true`                        | `SE_AVOID_STATS=true`                      | Avoid sends usage statistics to plausible.io. Default: `false`                                                                                                                                                                                                                          |

```toml
browser = "chrome"                 # --browser BROWSER
driver = "chromedriver"             # --driver DRIVER
browser-version = "106"             # --browser-version BROWSER_VERSION
driver-version = "106.0.5249.61"    # --driver-version DRIVER_VERSION
browser-path = "/usr/bin/google-chrome"  # --browser-path BROWSER_PATH
driver-mirror-url = "https://custom-driver-mirror.com"  # --driver-mirror-url DRIVER_MIRROR_URL
browser-mirror-url = "https://custom-browser-mirror.com"  # --browser-mirror-url BROWSER_MIRROR_URL
output = "LOGGER"                   # --output OUTPUT
os = "linux"                        # --os OS
arch = "x64"                        # --arch ARCH
proxy = "myproxy:8080"              # --proxy PROXY
timeout = 300                       # --timeout TIMEOUT
offline = true                      # --offline
force-browser-download = true       # --force-browser-download
avoid-browser-download = false      # --avoid-browser-download
debug = true                        # --debug
trace = true                        # --trace
cache-path = "/custom/cache/path"    # --cache-path CACHE_PATH
ttl = 3600                          # --ttl TTL
language-binding = "Python"         # --language-binding LANGUAGE
avoid-stats = true                  # --avoid-stats
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/selenium_manager/example_se-config.toml#L1-L21)

##### /examples/python/tests/selenium\_manager/example\_se-config.toml

```toml
browser = "chrome"                 # --browser BROWSER
driver = "chromedriver"             # --driver DRIVER
browser-version = "106"             # --browser-version BROWSER_VERSION
driver-version = "106.0.5249.61"    # --driver-version DRIVER_VERSION
browser-path = "/usr/bin/google-chrome"  # --browser-path BROWSER_PATH
driver-mirror-url = "https://custom-driver-mirror.com"  # --driver-mirror-url DRIVER_MIRROR_URL
browser-mirror-url = "https://custom-browser-mirror.com"  # --browser-mirror-url BROWSER_MIRROR_URL
output = "LOGGER"                   # --output OUTPUT
os = "linux"                        # --os OS
arch = "x64"                        # --arch ARCH
proxy = "myproxy:8080"              # --proxy PROXY
timeout = 300                       # --timeout TIMEOUT
offline = true                      # --offline
force-browser-download = true       # --force-browser-download
avoid-browser-download = false      # --avoid-browser-download
debug = true                        # --debug
trace = true                        # --trace
cache-path = "/custom/cache/path"    # --cache-path CACHE_PATH
ttl = 3600                          # --ttl TTL
language-binding = "Python"         # --language-binding LANGUAGE
avoid-stats = true                  # --avoid-stats
```

```
$ ./selenium-manager --browser chrome --debug
DEBUG chromedriver not found in PATH
DEBUG chrome detected at C:\Program Files\Google\Chrome\Application\chrome.exe
DEBUG Detected browser: chrome 139.0.7258.67
DEBUG Discovering versions from https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json
DEBUG Required driver: chromedriver 139.0.7258.68
DEBUG Acquiring lock: C:\Users\boni\.cache\selenium\chromedriver\win64\139.0.7258.68\sm.lock
DEBUG Downloading chromedriver 139.0.7258.68 from https://storage.googleapis.com/chrome-for-testing-public/139.0.7258.68/win64/chromedriver-win64.zip
INFO  Driver path: C:\Users\boni\.cache\selenium\chromedriver\win64\139.0.7258.68\chromedriver.exe
INFO  Browser path: C:\Program Files\Google\Chrome\Application\chrome.exe
```

In this case, the local Chrome (in Windows) is detected by Selenium Manager. Then, using its version and the CfT endpoints, the proper chromedriver version (115, in this example) is downloaded to the local cache. Finally, Selenium Manager provides two results: i) the driver path (downloaded) and ii) the browser path (local).

Let’s consider another example. Now we want to use Chrome beta. Therefore, we invoke Selenium Manager specifying that version label as follows (notice that the CfT beta is discovered, downloaded, and stored in the local cache):

```
$ ./selenium-manager --browser chrome --browser-version beta --debug
DEBUG chromedriver not found in PATH
DEBUG chrome not found in PATH
DEBUG chrome beta not found in the system
DEBUG Discovering versions from https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json
DEBUG Required browser: chrome 140.0.7339.16
DEBUG Acquiring lock: C:\Users\boni\.cache\selenium\chrome\win64\140.0.7339.16\sm.lock
DEBUG Downloading chrome 140.0.7339.16 from https://storage.googleapis.com/chrome-for-testing-public/140.0.7339.16/win64/chrome-win64.zip
DEBUG chrome 140.0.7339.16 is available at C:\Users\boni\.cache\selenium\chrome\win64\140.0.7339.16\chrome.exe
DEBUG Discovering versions from https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json
DEBUG Required driver: chromedriver 140.0.7339.16
DEBUG Acquiring lock: C:\Users\boni\.cache\selenium\chromedriver\win64\140.0.7339.16\sm.lock
DEBUG Downloading chromedriver 140.0.7339.16 from https://storage.googleapis.com/chrome-for-testing-public/140.0.7339.16/win64/chromedriver-win64.zip
INFO  Driver path: C:\Users\boni\.cache\selenium\chromedriver\win64\140.0.7339.16\chromedriver.exe
INFO  Browser path: C:\Users\boni\.cache\selenium\chrome\win64\140.0.7339.16\chrome.exe
```

```java
    public void testSetupWithoutManager() {
        System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/selenium_manager/SeleniumManagerUsageDemo.java#L12-L17)

##### /examples/java/src/test/java/dev/selenium/selenium\_manager/SeleniumManagerUsageDemo.java

```java
package dev.selenium.selenium_manager;

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class SeleniumManagerUsageDemo {

    @Test
    @Disabled("This test is just for demo purposes and should not be run in CI")
    public void testSetupWithoutManager() {
        System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }

    @Test
    public void testSetupWithManager() {
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }

}
```

**Selenium Manager**

```java
    public void testSetupWithManager() {
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/selenium_manager/SeleniumManagerUsageDemo.java#L20-L24)

##### /examples/java/src/test/java/dev/selenium/selenium\_manager/SeleniumManagerUsageDemo.java

```java
package dev.selenium.selenium_manager;

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class SeleniumManagerUsageDemo {

    @Test
    @Disabled("This test is just for demo purposes and should not be run in CI")
    public void testSetupWithoutManager() {
        System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }

    @Test
    public void testSetupWithManager() {
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }

}
```

**Previously**

```py
def setup_without_selenium_manager():
    chrome_service = Service(executable_path='path/to/chrome.exe')
    driver = webdriver.Chrome(chrome_service)
    return driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/selenium_manager/usage.py#L5-L8)

##### /examples/python/tests/selenium\_manager/usage.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

def setup_without_selenium_manager():
    chrome_service = Service(executable_path='path/to/chrome.exe')
    driver = webdriver.Chrome(chrome_service)
    return driver
    
def setup_with_selenium_manager():
    driver = webdriver.Chrome()
    return driver
```

**Selenium Manager**

```py
def setup_with_selenium_manager():
    driver = webdriver.Chrome()
    return driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/selenium_manager/usage.py#L10-L12)

##### /examples/python/tests/selenium\_manager/usage.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

def setup_without_selenium_manager():
    chrome_service = Service(executable_path='path/to/chrome.exe')
    driver = webdriver.Chrome(chrome_service)
    return driver
    
def setup_with_selenium_manager():
    driver = webdriver.Chrome()
    return driver
```

```cs
        public void TestWithSeleniumManager()
        {
            // Before
            // using var driver = new ChromeDriver("path/to/chromedriver");

            // Now
            using var driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/documentation/selenium_manager/");
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/SeleniumManager/UsageTest.cs#L10-L18)

##### /examples/dotnet/SeleniumDocs/SeleniumManager/UsageTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.SeleniumManagerTest
{
    [TestClass]
    public class UsageTest
    {
        [TestMethod]
        public void TestWithSeleniumManager()
        {
            // Before
            // using var driver = new ChromeDriver("path/to/chromedriver");

            // Now
            using var driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/documentation/selenium_manager/");
        }
    }
}
```

**Previously**

```rb
def setup_without_selenium_manager
  service = Selenium::WebDriver::Chrome::Service.new(path: '/path/to/chromedriver')
  driver = Selenium::WebDriver.for(:chrome, service: service)
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/selenium_manager/usage.rb#L5-L10)

##### /examples/ruby/spec/selenium\_manager/usage.rb

```rb
# frozen_string_literal: true

require 'selenium-webdriver'

def setup_without_selenium_manager
  service = Selenium::WebDriver::Chrome::Service.new(path: '/path/to/chromedriver')
  driver = Selenium::WebDriver.for(:chrome, service: service)
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end

def setup_with_selenium_manager
  driver = Selenium::WebDriver.for(:chrome) # Selenium Manager handles the driver automatically
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end
```

**Selenium Manager**

```rb
def setup_with_selenium_manager
  driver = Selenium::WebDriver.for(:chrome) # Selenium Manager handles the driver automatically
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/selenium_manager/usage.rb#L12-L16)

##### /examples/ruby/spec/selenium\_manager/usage.rb

```rb
# frozen_string_literal: true

require 'selenium-webdriver'

def setup_without_selenium_manager
  service = Selenium::WebDriver::Chrome::Service.new(path: '/path/to/chromedriver')
  driver = Selenium::WebDriver.for(:chrome, service: service)
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end

def setup_with_selenium_manager
  driver = Selenium::WebDriver.for(:chrome) # Selenium Manager handles the driver automatically
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end
```

**Previously**

```js
  // it('Creates driver with Selenium Manager', async function () {
  //   let driverPath = '/path/to/chromedriver';
  //   let browserPath = '/path/to/chrome';

  //   options.setChromeBinaryPath(browserPath)

  //   let service = new Chrome.ServiceBuilder().setPath(driverPath)

  //   let driver = new Builder()
  //       .forBrowser(Browser.CHROME)
  //       .setChromeService(service)
  //       .build();

  //   await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  //   await driver.quit();
  // });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/selenium_manager/usage.spec.js#L16-L31)

##### /examples/javascript/test/selenium\_manager/usage.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options();

describe('Usage Test', function () {
  it('Creates driver wit Selenium Manager', async function () {

    let driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  // it('Creates driver with Selenium Manager', async function () {
  //   let driverPath = '/path/to/chromedriver';
  //   let browserPath = '/path/to/chrome';

  //   options.setChromeBinaryPath(browserPath)

  //   let service = new Chrome.ServiceBuilder().setPath(driverPath)

  //   let driver = new Builder()
  //       .forBrowser(Browser.CHROME)
  //       .setChromeService(service)
  //       .build();

  //   await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  //   await driver.quit();
  // });
});
```

**Selenium Manager**

```js
  it('Creates driver wit Selenium Manager', async function () {

    let driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/selenium_manager/usage.spec.js#L6-L14)

##### /examples/javascript/test/selenium\_manager/usage.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options();

describe('Usage Test', function () {
  it('Creates driver wit Selenium Manager', async function () {

    let driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  // it('Creates driver with Selenium Manager', async function () {
  //   let driverPath = '/path/to/chromedriver';
  //   let browserPath = '/path/to/chrome';

  //   options.setChromeBinaryPath(browserPath)

  //   let service = new Chrome.ServiceBuilder().setPath(driverPath)

  //   let driver = new Builder()
  //       .forBrowser(Browser.CHROME)
  //       .setChromeService(service)
  //       .build();

  //   await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  //   await driver.quit();
  // });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

## Selenium Grid

Selenium Manager allows you to configure the drivers automatically when setting up Selenium Grid. To that aim, you need to include the argument `--selenium-manager true` in the command to start Selenium Grid. For more details, visit the [Selenium Grid starting page](https://www.selenium.dev/documentation/grid/getting_started/).

Moreover, Selenium Manager also allows managing Selenium Grid releases automatically. For that, the argument `--grid` is used as follows:

```
$ ./selenium-manager --grid
```

After this command, Selenium Manager discovers the latest version of Selenium Grid, storing the `selenium-server.jar` in the local cache.

Optionally, the argument `--grid` allows to specify a Selenium Grid version (`--grid <GRID_VERSION>`).

## Known Limitations

### Connectivity issues

Selenium Manager requests remote endpoints (like Chrome for Testing (CfT), among others) to discover and download drivers and browsers from online repositories. When this operation is done in a corporate environment with a proxy or firewall, it might lead to connectivity problems like the following:

```
error sending request for url (https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json)
```

```
error trying to connect: dns error: failed to lookup address information
```

```
error trying to connect: An existing connection was forcibly closed by the remote host. (os error 10054)
```

```
libdbus-glib-1.so.2: cannot open shared object file: No such file or directory
Couldn't load XPCOM.
```

If that happens, the solution is to install that library, for instance, as follows:

```
sudo apt-get install libdbus-glib-1-2
```

A similar issue might happen when trying to execute Chrome for Testing in Linux:

```
error while loading shared libraries: libatk-1.0.so.0: cannot open shared object file: No such file or directory
```

In this case, the library to be installed is the following:

```
sudo apt-get install libatk-bridge2.0-0
```

Last modified August 17, 2025: [chore: fix typos (#2428) (b99b7e3c145)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/b99b7e3c145a6601f0b4313e9a8913fcf3324310)

----
url: https://www.selenium.dev/pt-br/documentation/legacy/selenium_3/grid_3/
----

# Grid 3

Selenium Grid 3 supported WebDriver without Selenium RC code. Grid 3 was completely rewritten for the new Grid 4.

[Grid 4](https://www.selenium.dev/pt-br/documentation/grid/)

*Selenium Grid* é um servidor proxy inteligente que permite que os testes Selenium encaminhem comandos para instâncias remotas do navegador da web. Seu objetivo é fornecer uma maneira fácil de executar testes em paralelo em várias máquinas.

Com Selenium Grid, um servidor atua como o hub que roteia comandos de teste formatados em JSON para um ou mais nós registrados. Os testes entram em contato com o hub para obter acesso a instâncias remotas do navegador. O hub tem uma lista de servidores registrados aos quais fornece acesso, e permite o controle dessas instâncias.

Selenium Grid nos permite executar testes em paralelo em várias máquinas, e gerenciar diferentes versões e configurações do navegador centralmente (em vez de em cada teste individual).

Selenium Grid não é uma bala de prata. Ele resolve um subconjunto de problemas comuns de delegação e distribuição, mas não irá, por exemplo, gerenciar sua infraestrutura, e pode não atender às suas necessidades específicas.

----
url: https://www.selenium.dev/pt-br/documentation/selenium_manager/
----

# Gerenciador do Selenium (Beta)

O Selenium Manager é uma ferramenta de linha de comando implementada em Rust que fornece gerenciamento automatizado de drivers e navegadores para o Selenium. As bibliotecas do Selenium usam essa ferramenta por padrão, portanto, você não precisa baixá-la, adicionar nada ao seu código ou realizar qualquer outra ação para utilizá-la.

## Motivation

***TL;DR:*** *Selenium Manager is the official driver manager of the Selenium project, and it is shipped out of the box with every Selenium release.*

Selenium uses the native support implemented by each browser to carry out the automation process. For this reason, Selenium users need to place a component called *driver* (chromedriver, geckodriver, msedgedriver, etc.) between the script using the Selenium API and the browser. For many years, managing these drivers was a manual process for Selenium users. This way, they had to download the required driver for a browser (chromedriver for Chrome, geckodriver for Firefox, etc.) and place it in the `PATH` or export the driver path as a system property (Java, JavaScript, etc.). But this process was cumbersome and led to maintainability issues.

Let’s consider an example. Imagine you manually downloaded the required chromedriver for driving your Chrome with Selenium. When you did this process, the stable version of Chrome was 113, so you downloaded chromedriver 113 and put it in your `PATH`. At that moment, your Selenium script executed correctly. But the *problem* is that Chrome is *evergreen*. This name refers to Chrome’s ability to upgrade automatically and silently to the next stable version when available. This feature is excellent for end-users but potentially dangerous for browser automation. Let’s go back to the example to discover it. Your local Chrome eventually updates to version 115. And that moment, your Selenium script is broken due to the incompatibility between the manually downloaded driver (113) and the Chrome version (115). Thus, your Selenium script fails with the following error message: *“session not created: This version of ChromeDriver only supports Chrome version 113”*.

This problem is the primary reason for the existence of the so-called *driver managers* (such as [WebDriverManager](https://bonigarcia.dev/webdrivermanager/) for Java, [webdriver-manager](https://pypi.org/project/webdriver-manager/) for Python, [webdriver-manager](https://www.npmjs.com/package/webdriver-manager) for JavaScript, [WebDriverManager.Net](https://github.com/rosolko/WebDriverManager.Net) for C#, and [webdrivers](https://github.com/titusfortner/webdrivers) for Ruby). All these projects were an inspiration and a clear sign that the community needed this feature to be built in Selenium. Thus, the Selenium project has created *Selenium Manager*, the official driver manager for Selenium, shipped out of the box with each Selenium release as of version 4.6.

## Usage

***TL;DR:*** *Selenium Manager is used by the Selenium bindings when the drivers (chromedriver, geckodriver, etc.) are unavailable.*

Driver management through Selenium Manager is *opt-in* for the Selenium bindings. Thus, users can continue managing their drivers manually (putting the driver in the `PATH` or using system properties) or rely on a third-party *driver manager* to do it automatically. Selenium Manager only operates as a fallback: if no driver is provided, Selenium Manager will come to the rescue.

Selenium Manager is a CLI (command line interface) tool implemented in Rust to allow cross-platform execution and compiled for Windows, Linux, and macOS. The Selenium Manager binaries are shipped with each Selenium release. This way, each Selenium binding language invokes Selenium Manager to carry out the automated driver and browser management explained in the following sections.

## Automated driver management

***TL;DR:*** *Selenium Manager automatically discovers, downloads, and caches the drivers required by Selenium when these drivers are unavailable.*

The primary feature of Selenium Manager is called *automated driver management*. Let’s consider an example to understand it. Suppose we want to driver Chrome with Selenium (see the doc about how to [start a session with Selenium](https://www.selenium.dev/documentation/webdriver/getting_started/first_script/#1-start-the-session)). Before the session begins, and when the driver is unavailable, Selenium Manager manages chromedriver for us. We use the term *management* for this feature (and not just *download*) since this process is broader and implies different steps:

1. Browser version discovery. Selenium Manager discovers the browser version (e.g., Chrome, Firefox, Edge) installed in the machine that executes Selenium. This step uses shell commands (e.g., `google-chrome --version`).
2. Driver version discovery. With the discovered browser version, the proper driver version is resolved. For this step, the online metadata/endpoints maintained by the browser vendors (e.g., [chromedriver](https://chromedriver.chromium.org/downloads), [geckodriver](https://github.com/mozilla/geckodriver/releases), or [msedgedriver](https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/)) are used.
3. Driver download. The driver URL is obtained with the resolved driver version; with that URL, the driver artifact is downloaded, uncompressed, and stored locally.
4. Driver cache. Uncompressed driver binaries are stored in a local cache folder (`~/.cache/selenium`). The next time the same driver is required, it will be used from there if the driver is already in the cache.

## Automated browser management

***TL;DR:*** *Selenium Manager automatically discovers, downloads, and caches the browsers driven with Selenium (Chrome, Firefox, and Edge) when these browsers are not installed in the local system.*

As of Selenium 4.11.0, Selenium Manager also implements *automated browser management*. With this feature, Selenium Manager allows us to discover, download, and cache the different browser releases, making them seamlessly available for Selenium. Internally, Selenium Manager uses an equivalent management procedure explained in the section before, but this time, for browser releases.

The browser automatically managed by Selenium Manager are:

* Chrome. Based on [Chrome for Testing (CfT)](https://googlechromelabs.github.io/chrome-for-testing/), as of Selenium 4.11.0.
* Firefox. Based on [public Firefox releases](https://ftp.mozilla.org/pub/firefox/releases/), as of Selenium 4.12.0.
* Edge. Based on [Edge downloads](https://www.microsoft.com/en-us/edge/download), as of Selenium 4.14.0.

Let’s consider again the typical example of driving Chrome with Selenium. And this time, suppose Chrome is not installed on the local machine when [starting a new session](https://www.selenium.dev/documentation/webdriver/getting_started/first_script/#1-start-the-session)). In that case, the current stable CfT release will be discovered, downloaded, and cached (in `~/.cache/selenium/chrome`) by Selenium Manager.

But there is more. In addition to the stable browser version, Selenium Manager also allows downloading older browser versions (in the case of CfT, starting in version 113, the first version published as CfT). To set a browser version with Selenium, we use a browser option called [browserVersion](https://www.selenium.dev/documentation/webdriver/drivers/options/#browserversion).

Let’s consider another simple example. Suppose we set `browserVersion` to `114` using [Chrome options](https://www.selenium.dev/documentation/webdriver/browsers/chrome/). In this case, Selenium Manager will check if Chrome 114 is already installed. If it is, it will be used. If not, Selenium Manager will manage (i.e., discover, download, and cache) CfT 114. And in either case, the chromedriver is also managed. Finally, Selenium will start Chrome to be driven programmatically, as usual.

But there is even more. In addition to fixed browser versions (e.g., `113`, `114`, `115`, etc.), we can use the following labels for `browserVersion`:

* `stable`: Current CfT version.
* `beta`: Next version to stable.
* `dev`: Version in development at this moment.
* `canary`: Nightly build for developers.
* `esr`: Extended Support Release (only for Firefox).

When these labels are specified, Selenium Manager first checks if a given browser is already installed (`beta`, `dev`, etc.), and when it is not detected, the browser is automatically managed.

### Edge in Windows

Automated Edge management by Selenium Manager in Windows is different from other browsers. Both Chrome and Firefox (and Edge in macOS and Linux) are downloaded automatically to the local cache (`~/.cache/selenium`) by Selenium Manager. Nevertheless, the same cannot be done for Edge in Windows. The reason is that the Edge installer for Windows is distributed as a Microsoft Installer (MSI) file, designed to be executed with administrator rights. This way, when Edge is attempted to be installed with Selenium Manager in Windows with a non-administrator session, a warning message will be displayed by Selenium Manager as follows:

```
edge can only be installed in Windows with administrator permissions
```

Therefore, administrator permissions are required to install Edge in Windows automatically through Selenium Manager, and Edge is eventually installed in the usual program files folder (e.g., `C:\Program Files (x86)\Microsoft\Edge`).

## Data collection

Selenium Manager will report anonymised usage [statistics](https://plausible.io/privacy-focused-web-analytics) to [Plausible](https://plausible.io/manager.selenium.dev). This allows the Selenium team to understand more about how Selenium is being used so that we can better focus our development efforts. The data being collected is:

| Data                                               | Purpose                                                                                                                                      |
| -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Selenium version                                   | This allows the Selenium developers to safely deprecate and remove features, as well as determine which new features may be available to you |
| Language binding                                   | Programming language used to execute Selenium scripts (Java, JavaScript, Python, .Net, Ruby)                                                 |
| OS and architecture Selenium Manager is running on | The Selenium developers can use this information to help prioritise bug reports, and to identify if there are systemic OS-related issues     |
| Browser and browser version                        | Helping for prioritising bug reports                                                                                                         |
| Rough geolocation                                  | Derived from the IP address you connect from. This is useful for determining where we need to focus our documentation efforts                |

Selenium Manager sends these data to Plausible once a day. This period is based on the TTL value (see [configuration](https://www.selenium.dev/documentation/selenium_manager/#configuration)).

### Opting out of data collection

**Data collection is on by default.** To disable it, set the `SE_AVOID_STATS` environment variable to `true`. You may also disable data collection in the configuration file (see below) by setting `avoid-stats = true`.

## Configuration

***TL;DR:*** *Selenium Manager should work silently and transparently for most users. Nevertheless, there are scenarios (e.g., to specify a custom cache path or setup globally a proxy) where custom configuration can be required.*

Selenium Manager is a CLI tool. Therefore, under the hood, the Selenium bindings call Selenium Manager by invoking shell commands. Like any other CLI tool, arguments can be used to specify specific capabilities in Selenium Manager. The different arguments supported by Selenium Manager can be checked by running the following command:

```
$ ./selenium-manager --help
```

| CLI argument                                | Configuration file                          | Env variable                               | Description                                                                                                                                                                                                                                                                             |
| ------------------------------------------- | ------------------------------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--browser BROWSER`                         | `browser = "BROWSER"`                       | `SE_BROWSER=BROWSER`                       | Browser name: `chrome`, `firefox`, `edge`, `iexplorer`, `safari`, `safaritp`, or `webview2`                                                                                                                                                                                             |
| `--driver <DRIVER>`                         | `driver = "DRIVER"`                         | `SE_DRIVER=DRIVER`                         | Driver name: `chromedriver`, `geckodriver`, `msedgedriver`, `IEDriverServer`, or `safaridriver`                                                                                                                                                                                         |
| `--browser-version <BROWSER_VERSION>`       | `browser-version = "BROWSER_VERSION"`       | `SE_BROWSER_VERSION=BROWSER_VERSION`       | Major browser version (e.g., `105`, `106`, etc. Also: `beta`, `dev`, `canary` -or `nightly`-, and `esr` -in Firefox- are accepted)                                                                                                                                                      |
| `--driver-version <DRIVER_VERSION>`         | `driver-version = "DRIVER_VERSION"`         | `SE_DRIVER_VERSION=DRIVER_VERSION`         | Driver version (e.g., `106.0.5249.61, 0.31.0`, etc.)                                                                                                                                                                                                                                    |
| `--browser-path <BROWSER_PATH>`             | `browser-path = "BROWSER_PATH"`             | `SE_BROWSER_PATH=BROWSER_PATH`             | Browser path (absolute) for browser version detection (e.g., `/usr/bin/google-chrome`, `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`, `C:\Program Files\Google\Chrome\Application\chrome.exe`)                                                                         |
| `--driver-mirror-url <DRIVER_MIRROR_URL>`   | `driver-mirror-url = "DRIVER_MIRROR_URL"`   | `SE_DRIVER_MIRROR_URL=DRIVER_MIRROR_URL`   | Mirror URL for driver repositories                                                                                                                                                                                                                                                      |
| `--browser-mirror-url <BROWSER_MIRROR_URL>` | `browser-mirror-url = "BROWSER_MIRROR_URL"` | `SE_BROWSER_MIRROR_URL=BROWSER_MIRROR_URL` | Mirror URL for browser repositories                                                                                                                                                                                                                                                     |
| `--output <OUTPUT>`                         | `output = "OUTPUT"`                         | `SE_OUTPUT=OUTPUT`                         | Output type: `LOGGER` (using `INFO`, `WARN`, etc.), `JSON` (custom JSON notation), `SHELL` (Unix-like), or `MIXED` (`INFO`, `WARN`, `DEBUG`, etc. to stderr and minimal `JSON` to stdout). Default: `LOGGER`                                                                            |
| `--os <OS>`                                 | `os = "OS"`                                 | `SE_OS=OS`                                 | Operating system for drivers and browsers (i.e., `windows`, `linux`, or `macos`)                                                                                                                                                                                                        |
| `--arch <ARCH>`                             | `arch = "ARCH"`                             | `SE_ARCH=ARCH`                             | System architecture for drivers and browsers (i.e., `x32`, `x64`, or `arm64`)                                                                                                                                                                                                           |
| `--proxy <PROXY>`                           | `proxy = "PROXY"`                           | `SE_PROXY=PROXY`                           | HTTP proxy for network connection (e.g., `myproxy:port`, `myuser:mypass@myproxy:port`)                                                                                                                                                                                                  |
| `--timeout <TIMEOUT>`                       | `timeout = TIMEOUT`                         | `SE_TIMEOUT=TIMEOUT`                       | Timeout for network requests (in seconds). Default: `300`                                                                                                                                                                                                                               |
| `--offline`                                 | `offline = true`                            | `SE_OFFLINE=true`                          | Offline mode (i.e., disabling network requests and downloads)                                                                                                                                                                                                                           |
| `--force-browser-download`                  | `force-browser-download = true`             | `SE_FORCE_BROWSER_DOWNLOAD=true`           | Force to download browser, e.g., when a browser is already installed in the system, but you want Selenium Manager to download and use it                                                                                                                                                |
| `--avoid-browser-download`                  | `avoid-browser-download = true`             | `SE_AVOID_BROWSER_DOWNLOAD=true`           | Avoid to download browser, e.g., when a browser is supposed to be downloaded by Selenium Manager, but you prefer to avoid it                                                                                                                                                            |
| `--skip-driver-in-path`                     | `skip-driver-in-path = true`                | `SE_SKIP_DRIVER_IN_PATH=true`              | Not using drivers found in the `PATH`                                                                                                                                                                                                                                                   |
| `--skip-browser-in-path`                    | `skip-browser-in-path = true`               | `SE_SKIP_BROWSER_IN_PATH=true`             | Not using browsers found in the `PATH`                                                                                                                                                                                                                                                  |
| `--debug`                                   | `debug = true`                              | `SE_DEBUG=true`                            | Display `DEBUG` messages                                                                                                                                                                                                                                                                |
| `--trace`                                   | `trace = true`                              | `SE_TRACE=true`                            | Display `TRACE` messages                                                                                                                                                                                                                                                                |
| `--cache-path <CACHE_PATH>`                 | `cache-path="CACHE_PATH"`                   | `SE_CACHE_PATH=CACHE_PATH`                 | Local folder used to store downloaded assets (drivers and browsers), local metadata, and configuration file. See next section for details. Default: `~/.cache/selenium`. For Windows paths in the TOML configuration file, double backslashes are required (e.g., `C:\\custom\\cache`). |
| `--ttl <TTL>`                               | `ttl = TTL`                                 | `SE_TTL=TTL`                               | Time-to-live in seconds. See next section for details. Default: `3600` (1 hour)                                                                                                                                                                                                         |
| `--language-binding <LANGUAGE>`             | `language-binding = "LANGUAGE"`             | `SE_LANGUAGE_BINDING=LANGUAGE`             | Language that invokes Selenium Manager (e.g., Java, JavaScript, Python, DotNet, Ruby)                                                                                                                                                                                                   |
| `--avoid-stats`                             | `avoid-stats = true`                        | `SE_AVOID_STATS=true`                      | Avoid sends usage statistics to plausible.io. Default: `false`                                                                                                                                                                                                                          |

```toml
browser = "chrome"                 # --browser BROWSER
driver = "chromedriver"             # --driver DRIVER
browser-version = "106"             # --browser-version BROWSER_VERSION
driver-version = "106.0.5249.61"    # --driver-version DRIVER_VERSION
browser-path = "/usr/bin/google-chrome"  # --browser-path BROWSER_PATH
driver-mirror-url = "https://custom-driver-mirror.com"  # --driver-mirror-url DRIVER_MIRROR_URL
browser-mirror-url = "https://custom-browser-mirror.com"  # --browser-mirror-url BROWSER_MIRROR_URL
output = "LOGGER"                   # --output OUTPUT
os = "linux"                        # --os OS
arch = "x64"                        # --arch ARCH
proxy = "myproxy:8080"              # --proxy PROXY
timeout = 300                       # --timeout TIMEOUT
offline = true                      # --offline
force-browser-download = true       # --force-browser-download
avoid-browser-download = false      # --avoid-browser-download
debug = true                        # --debug
trace = true                        # --trace
cache-path = "/custom/cache/path"    # --cache-path CACHE_PATH
ttl = 3600                          # --ttl TTL
language-binding = "Python"         # --language-binding LANGUAGE
avoid-stats = true                  # --avoid-stats
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/selenium_manager/example_se-config.toml#L1-L21)

##### /examples/python/tests/selenium\_manager/example\_se-config.toml

```toml
browser = "chrome"                 # --browser BROWSER
driver = "chromedriver"             # --driver DRIVER
browser-version = "106"             # --browser-version BROWSER_VERSION
driver-version = "106.0.5249.61"    # --driver-version DRIVER_VERSION
browser-path = "/usr/bin/google-chrome"  # --browser-path BROWSER_PATH
driver-mirror-url = "https://custom-driver-mirror.com"  # --driver-mirror-url DRIVER_MIRROR_URL
browser-mirror-url = "https://custom-browser-mirror.com"  # --browser-mirror-url BROWSER_MIRROR_URL
output = "LOGGER"                   # --output OUTPUT
os = "linux"                        # --os OS
arch = "x64"                        # --arch ARCH
proxy = "myproxy:8080"              # --proxy PROXY
timeout = 300                       # --timeout TIMEOUT
offline = true                      # --offline
force-browser-download = true       # --force-browser-download
avoid-browser-download = false      # --avoid-browser-download
debug = true                        # --debug
trace = true                        # --trace
cache-path = "/custom/cache/path"    # --cache-path CACHE_PATH
ttl = 3600                          # --ttl TTL
language-binding = "Python"         # --language-binding LANGUAGE
avoid-stats = true                  # --avoid-stats
```

```
$ ./selenium-manager --browser chrome --debug
DEBUG chromedriver not found in PATH
DEBUG chrome detected at C:\Program Files\Google\Chrome\Application\chrome.exe
DEBUG Detected browser: chrome 139.0.7258.67
DEBUG Discovering versions from https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json
DEBUG Required driver: chromedriver 139.0.7258.68
DEBUG Acquiring lock: C:\Users\boni\.cache\selenium\chromedriver\win64\139.0.7258.68\sm.lock
DEBUG Downloading chromedriver 139.0.7258.68 from https://storage.googleapis.com/chrome-for-testing-public/139.0.7258.68/win64/chromedriver-win64.zip
INFO  Driver path: C:\Users\boni\.cache\selenium\chromedriver\win64\139.0.7258.68\chromedriver.exe
INFO  Browser path: C:\Program Files\Google\Chrome\Application\chrome.exe
```

In this case, the local Chrome (in Windows) is detected by Selenium Manager. Then, using its version and the CfT endpoints, the proper chromedriver version (115, in this example) is downloaded to the local cache. Finally, Selenium Manager provides two results: i) the driver path (downloaded) and ii) the browser path (local).

Let’s consider another example. Now we want to use Chrome beta. Therefore, we invoke Selenium Manager specifying that version label as follows (notice that the CfT beta is discovered, downloaded, and stored in the local cache):

```
$ ./selenium-manager --browser chrome --browser-version beta --debug
DEBUG chromedriver not found in PATH
DEBUG chrome not found in PATH
DEBUG chrome beta not found in the system
DEBUG Discovering versions from https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json
DEBUG Required browser: chrome 140.0.7339.16
DEBUG Acquiring lock: C:\Users\boni\.cache\selenium\chrome\win64\140.0.7339.16\sm.lock
DEBUG Downloading chrome 140.0.7339.16 from https://storage.googleapis.com/chrome-for-testing-public/140.0.7339.16/win64/chrome-win64.zip
DEBUG chrome 140.0.7339.16 is available at C:\Users\boni\.cache\selenium\chrome\win64\140.0.7339.16\chrome.exe
DEBUG Discovering versions from https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json
DEBUG Required driver: chromedriver 140.0.7339.16
DEBUG Acquiring lock: C:\Users\boni\.cache\selenium\chromedriver\win64\140.0.7339.16\sm.lock
DEBUG Downloading chromedriver 140.0.7339.16 from https://storage.googleapis.com/chrome-for-testing-public/140.0.7339.16/win64/chromedriver-win64.zip
INFO  Driver path: C:\Users\boni\.cache\selenium\chromedriver\win64\140.0.7339.16\chromedriver.exe
INFO  Browser path: C:\Users\boni\.cache\selenium\chrome\win64\140.0.7339.16\chrome.exe
```

```java
    public void testSetupWithoutManager() {
        System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/selenium_manager/SeleniumManagerUsageDemo.java#L12-L17)

##### /examples/java/src/test/java/dev/selenium/selenium\_manager/SeleniumManagerUsageDemo.java

```java
package dev.selenium.selenium_manager;

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class SeleniumManagerUsageDemo {

    @Test
    @Disabled("This test is just for demo purposes and should not be run in CI")
    public void testSetupWithoutManager() {
        System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }

    @Test
    public void testSetupWithManager() {
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }

}
```

**Selenium Manager**

```java
    public void testSetupWithManager() {
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/selenium_manager/SeleniumManagerUsageDemo.java#L20-L24)

##### /examples/java/src/test/java/dev/selenium/selenium\_manager/SeleniumManagerUsageDemo.java

```java
package dev.selenium.selenium_manager;

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class SeleniumManagerUsageDemo {

    @Test
    @Disabled("This test is just for demo purposes and should not be run in CI")
    public void testSetupWithoutManager() {
        System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }

    @Test
    public void testSetupWithManager() {
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }

}
```

**Previously**

```py
def setup_without_selenium_manager():
    chrome_service = Service(executable_path='path/to/chrome.exe')
    driver = webdriver.Chrome(chrome_service)
    return driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/selenium_manager/usage.py#L5-L8)

##### /examples/python/tests/selenium\_manager/usage.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

def setup_without_selenium_manager():
    chrome_service = Service(executable_path='path/to/chrome.exe')
    driver = webdriver.Chrome(chrome_service)
    return driver
    
def setup_with_selenium_manager():
    driver = webdriver.Chrome()
    return driver
```

**Selenium Manager**

```py
def setup_with_selenium_manager():
    driver = webdriver.Chrome()
    return driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/selenium_manager/usage.py#L10-L12)

##### /examples/python/tests/selenium\_manager/usage.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

def setup_without_selenium_manager():
    chrome_service = Service(executable_path='path/to/chrome.exe')
    driver = webdriver.Chrome(chrome_service)
    return driver
    
def setup_with_selenium_manager():
    driver = webdriver.Chrome()
    return driver
```

```cs
        public void TestWithSeleniumManager()
        {
            // Before
            // using var driver = new ChromeDriver("path/to/chromedriver");

            // Now
            using var driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/documentation/selenium_manager/");
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/SeleniumManager/UsageTest.cs#L10-L18)

##### /examples/dotnet/SeleniumDocs/SeleniumManager/UsageTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.SeleniumManagerTest
{
    [TestClass]
    public class UsageTest
    {
        [TestMethod]
        public void TestWithSeleniumManager()
        {
            // Before
            // using var driver = new ChromeDriver("path/to/chromedriver");

            // Now
            using var driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/documentation/selenium_manager/");
        }
    }
}
```

**Previously**

```rb
def setup_without_selenium_manager
  service = Selenium::WebDriver::Chrome::Service.new(path: '/path/to/chromedriver')
  driver = Selenium::WebDriver.for(:chrome, service: service)
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/selenium_manager/usage.rb#L5-L10)

##### /examples/ruby/spec/selenium\_manager/usage.rb

```rb
# frozen_string_literal: true

require 'selenium-webdriver'

def setup_without_selenium_manager
  service = Selenium::WebDriver::Chrome::Service.new(path: '/path/to/chromedriver')
  driver = Selenium::WebDriver.for(:chrome, service: service)
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end

def setup_with_selenium_manager
  driver = Selenium::WebDriver.for(:chrome) # Selenium Manager handles the driver automatically
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end
```

**Selenium Manager**

```rb
def setup_with_selenium_manager
  driver = Selenium::WebDriver.for(:chrome) # Selenium Manager handles the driver automatically
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/selenium_manager/usage.rb#L12-L16)

##### /examples/ruby/spec/selenium\_manager/usage.rb

```rb
# frozen_string_literal: true

require 'selenium-webdriver'

def setup_without_selenium_manager
  service = Selenium::WebDriver::Chrome::Service.new(path: '/path/to/chromedriver')
  driver = Selenium::WebDriver.for(:chrome, service: service)
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end

def setup_with_selenium_manager
  driver = Selenium::WebDriver.for(:chrome) # Selenium Manager handles the driver automatically
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end
```

**Previously**

```js
  // it('Creates driver with Selenium Manager', async function () {
  //   let driverPath = '/path/to/chromedriver';
  //   let browserPath = '/path/to/chrome';

  //   options.setChromeBinaryPath(browserPath)

  //   let service = new Chrome.ServiceBuilder().setPath(driverPath)

  //   let driver = new Builder()
  //       .forBrowser(Browser.CHROME)
  //       .setChromeService(service)
  //       .build();

  //   await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  //   await driver.quit();
  // });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/selenium_manager/usage.spec.js#L16-L31)

##### /examples/javascript/test/selenium\_manager/usage.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options();

describe('Usage Test', function () {
  it('Creates driver wit Selenium Manager', async function () {

    let driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  // it('Creates driver with Selenium Manager', async function () {
  //   let driverPath = '/path/to/chromedriver';
  //   let browserPath = '/path/to/chrome';

  //   options.setChromeBinaryPath(browserPath)

  //   let service = new Chrome.ServiceBuilder().setPath(driverPath)

  //   let driver = new Builder()
  //       .forBrowser(Browser.CHROME)
  //       .setChromeService(service)
  //       .build();

  //   await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  //   await driver.quit();
  // });
});
```

**Selenium Manager**

```js
  it('Creates driver wit Selenium Manager', async function () {

    let driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/selenium_manager/usage.spec.js#L6-L14)

##### /examples/javascript/test/selenium\_manager/usage.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options();

describe('Usage Test', function () {
  it('Creates driver wit Selenium Manager', async function () {

    let driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  // it('Creates driver with Selenium Manager', async function () {
  //   let driverPath = '/path/to/chromedriver';
  //   let browserPath = '/path/to/chrome';

  //   options.setChromeBinaryPath(browserPath)

  //   let service = new Chrome.ServiceBuilder().setPath(driverPath)

  //   let driver = new Builder()
  //       .forBrowser(Browser.CHROME)
  //       .setChromeService(service)
  //       .build();

  //   await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  //   await driver.quit();
  // });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

## Selenium Grid

Selenium Manager allows you to configure the drivers automatically when setting up Selenium Grid. To that aim, you need to include the argument `--selenium-manager true` in the command to start Selenium Grid. For more details, visit the [Selenium Grid starting page](https://www.selenium.dev/documentation/grid/getting_started/).

Moreover, Selenium Manager also allows managing Selenium Grid releases automatically. For that, the argument `--grid` is used as follows:

```
$ ./selenium-manager --grid
```

After this command, Selenium Manager discovers the latest version of Selenium Grid, storing the `selenium-server.jar` in the local cache.

Optionally, the argument `--grid` allows to specify a Selenium Grid version (`--grid <GRID_VERSION>`).

## Known Limitations

### Connectivity issues

Selenium Manager requests remote endpoints (like Chrome for Testing (CfT), among others) to discover and download drivers and browsers from online repositories. When this operation is done in a corporate environment with a proxy or firewall, it might lead to connectivity problems like the following:

```
error sending request for url (https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json)
```

```
error trying to connect: dns error: failed to lookup address information
```

```
error trying to connect: An existing connection was forcibly closed by the remote host. (os error 10054)
```

```
libdbus-glib-1.so.2: cannot open shared object file: No such file or directory
Couldn't load XPCOM.
```

If that happens, the solution is to install that library, for instance, as follows:

```
sudo apt-get install libdbus-glib-1-2
```

A similar issue might happen when trying to execute Chrome for Testing in Linux:

```
error while loading shared libraries: libatk-1.0.so.0: cannot open shared object file: No such file or directory
```

In this case, the library to be installed is the following:

```
sudo apt-get install libatk-bridge2.0-0
```

Última modificação August 17, 2025: [chore: fix typos (#2428) (b99b7e3c145)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/b99b7e3c145a6601f0b4313e9a8913fcf3324310)

----
url: https://www.selenium.dev/ja/documentation/webdriver/troubleshooting/logging/
----

# Logging Selenium commands

```java
    public void logging() throws IOException {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Java Logging is not exactly straightforward, and if you are just looking for an easy way to look at the important Selenium logs, take a look at the [Selenium Logger project](https://github.com/titusfortner/selenium-logger#selenium-logger)

Python logs are typically created per module. You can match all submodules by referencing the top level module. So to work with all loggers in selenium module, you can do this:

```py
    logger = logging.getLogger('selenium')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L5)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

You must also create and add a log handler (`StreamHandler`, `FileHandler`, etc).

To save logs to a file, you can do this:

```py
log_path = '/path/to/log'
handler = logging.FileHandler(log_path)
logger.addHandler(handler)
```

To display logs in the console, you can do this:

```py
handler = logging.StreamHandler()
logger.addHandler(handler)
```

.NET logger is managed with a static class, so all access to logging is managed simply by referencing `Log` from the `OpenQA.Selenium.Internal.Logging` namespace.

If you want to see as much debugging as possible in all the classes, you can turn on debugging globally in Ruby by setting `$DEBUG = true`.

For more fine-tuned control, Ruby Selenium created its own Logger class to wrap the default `Logger` class. This implementation provides some interesting additional features. Obtain the logger directly from the `#logger`class method on the `Selenium::WebDriver` module:

```rb
    logger = Selenium::WebDriver.logger
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L11)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

```javascript
const logging = require('selenium-webdriver/lib/logging')
logger = logging.getLogger('webdriver')
```

```java
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L32-L35)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Python has 6 logger levels: `CRITICAL`, `ERROR`, `WARNING`, `INFO`, `DEBUG`, and `NOTSET`. The default is `WARNING`

To change the level of the logger:

```py
    logger.setLevel(logging.DEBUG)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L7)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

Things get complicated when you use PyTest, though. By default, PyTest hides logging unless the test fails. You need to set 3 things to get PyTest to display logs on passing tests.

To always output logs with PyTest you need to run with additional arguments. First, `-s` to prevent PyTest from capturing the console. Second, `-p no:logging`, which allows you to override the default PyTest logging settings so logs can be displayed regardless of errors.

So you need to set these flags in your IDE, or run PyTest on command line like:

```bash
pytest -s -p no:logging
```

Finally, since you turned off logging in the arguments above, you now need to add configuration to turn it back on:

```py
logging.basicConfig(level=logging.WARN)
```

.NET has 6 logger levels: `Error`, `Warn`, `Info`, `Debug`, `Trace` and `None`. The default level is `Warn`.

To change the level of the logger:

```cs
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L18)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

Ruby logger has 5 logger levels: `:debug`, `:info`, `:warn`, `:error`, `:fatal`. As of Selenium v4.9.1, The default is `:info`.

To change the level of the logger:

```rb
    logger.level = :debug
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L13)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

JavaScript has 9 logger levels: `OFF`, `SEVERE`, `WARNING`, `INFO`, `DEBUG`, `FINE`, `FINER`, `FINEST`, `ALL`. The default is `OFF`.

To change the level of the logger:

```javascript
logger.setLevel(logging.Level.INFO)
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
WARNING: this is a warning
```

Python logs actionable content at logger level — `WARNING` Details about deprecations are logged at this level.

Example:

```text
WARNING  selenium:test_logging.py:23 this is a warning
```

.NET logs actionable content at logger level `Warn`.

Example:

```text
11:04:40.986 WARN LoggingTest: this is a warning
```

Ruby logs actionable content at logger level — `:warn`. Details about deprecations are logged at this level.

For example:

```text
2023-05-08 20:53:13 WARN Selenium [:example_id] this is a warning 
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
INFO: this is useful information
```

Python logs useful information at logger level — `INFO`

Example:

```text
INFO     selenium:test_logging.py:22 this is useful information
```

.NET logs useful information at logger level `Info`.

Example:

```text
11:04:40.986 INFO LoggingTest: this is useful information
```

Ruby logs useful information at logger level — `:info`.

Example:

```text
2023-05-08 20:53:13 INFO Selenium [:example_id] this is useful information 
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
FINE: this is detailed debug information
```

Python logs debugging details at logger level — `DEBUG`

Example:

```text
DEBUG    selenium:test_logging.py:24 this is detailed debug information
```

.NET logs most debug content at logger level `Debug`.

Example:

```text
11:04:40.986 DEBUG LoggingTest: this is detailed debug information
```

Ruby only provides one level for debugging, so all details are at logger level — `:debug`.

Example:

```text
2023-05-08 20:53:13 DEBUG Selenium [:example_id] this is detailed debug information 
```

```java

      Path output = artifactsDir().resolve("selenium.xml");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L37-L38)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

By default all logs are sent to `sys.stderr`. To direct output somewhere else, you need to add a handler with either a `StreamHandler` or a `FileHandler`:

```py
    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L9-L10)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

By default all logs are sent to `System.Console.Error` output. To direct output somewhere else, you need to add a handler with a `FileLogHandler`:

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L20)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

By default, logs are sent to the console in `stdout`.\
To store the logs in a file:

```rb
    logger.output = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L15)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

JavaScript does not currently support sending output to a file.

To send logs to console output:

```javascript
logging.installConsoleHandler()
```

```java
        logger.addHandler(handler);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L40-L41)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Because logging is managed by module, instead of working with just "selenium", you can specify different levels for different modules:

```py
    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L12-L13)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

.NET logging is managed on a per class level, set the level you want to use on a per-class basis:

```cs

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

Ruby’s logger allows you to opt in (“allow”) or opt out (“ignore”) of log messages based on their IDs. Everything that Selenium logs includes an ID. You can also turn on or off all deprecation notices by using `:deprecations`.

These methods accept one or more symbols or an array of symbols:

```rb
    logger.ignore(:jwp_caps, :logger_info)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L17)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

or

```rb
    logger.allow(%i[selenium_manager example_id])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L18)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

最終更新 August 13, 2025: [\[dotnet\] Change default internal log level to Warn (#2409) (22fad037ea6)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/22fad037ea6c457abc65c64d37d6c299bde40a4d)

----
url: https://www.selenium.dev/ja/documentation/test_practices/encouraged/locators/
----

# ロケータをうまく扱うTips

最終更新 October 19, 2022: [translate 'Tips on working with locators' into japanese (#1203) \[deploy site\] (ad91f14e14d)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/ad91f14e14d970526a449931de59056732400f05)

----
url: https://www.selenium.dev/ja/documentation/grid/advanced_features/
----

# 高度な機能

高度な機能のすべての詳細を取得し、それがどのように機能するか、および独自の設定方法を理解するには、次のセクションを参照してください。

***

##### [可観測性](/ja/documentation/grid/advanced_features/observability/)

##### [GraphQLクエリのサポート](/ja/documentation/grid/advanced_features/graphql_support/)

##### [Grid エンドポイント](/ja/documentation/grid/advanced_features/endpoints/)

##### [Customizing a Node](/ja/documentation/grid/advanced_features/customize_node/)

##### [External datastore](/ja/documentation/grid/advanced_features/external_datastore/)

----
url: https://www.selenium.dev/pt-br/documentation/overview/
----

# Resumo

Será Selenium a ferramenta para você? Veja um resumo dos componentes do projecto.

***

##### [Entendendo os componentes](/pt-br/documentation/overview/components/)

##### [Detalhes](/pt-br/documentation/overview/details/)

Selenium é um projeto abrangente para uma gama de ferramentas e bibliotecas que permitem e suportam a automação de navegadores da web.

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/encouraged/improved_reporting/
----

# Relatórios melhorados

O Selenium não foi projetado para relatar sobre o status de casos de teste. Aproveitar os recursos de relatórios integrados de frameworks de teste unitários é um bom começo. A maioria dos frameworks de teste unitários podem gerar relatórios formatados em xUnit ou HTML. Relatórios xUnit são populares para importar resultados para um servidor de integração contínua (CI) como Jenkins, Travis, Bamboo, etc. Aqui estão alguns links para obter mais informações sobre resultados de relatórios em vários idiomas.

[NUnit 3 Console Runner](//github.com/nunit/docs/wiki/Console-Runner)

[NUnit 3 Console Command Line](//github.com/nunit/docs/wiki/Console-Command-Line)

[xUnit getting test results in TeamCity](//xunit.net/docs/getting-test-results-in-teamcity)

[xUnit getting test results in CruiseControl.NET](//xunit.net/docs/getting-test-results-in-ccnet)

[xUnit getting test results in Azure DevOps](//xunit.net/docs/getting-test-results-in-azure-devops)

----
url: https://www.selenium.dev/documentation/legacy/selenium_ide/html_runner/
----

# HTML runner

```shell
[user@localhost ~]$ cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

[user@localhost ~]$ rpm -qa | egrep -i "xvfb|java-1.8|firefox"
xorg-x11-server-Xvfb-1.19.3-11.el7.x86_64
firefox-52.4.0-1.el7.centos.x86_64
java-1.8.0-openjdk-1.8.0.151-1.b12.el7_4.x86_64
java-1.8.0-openjdk-headless-1.8.0.151-1.b12.el7_4.x86_64
```

Test Suite example:

```html
[user@localhost ~]$ cat testsuite.html
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
  <title>Test Suite</title>
</head>
<body>
<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium"><tbody>
<tr><td><b>Test Suite</b></td></tr>
<tr><td><a href="YOUR-TEST-SCENARIO.html">YOUR-TEST-SCENARIO</a></td></tr>
</tbody></table>
</body>
</html>
```

## How to run selenium-html-runner headless

Now, the most important part, an example of how to run the selenium-html-runner! Your experience might vary depending on software combinations - geckodriver/FF/html-runner releases.

```shell
xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
```

```shell
[user@localhost ~]$ xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "*firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
Multi-window mode is longer used as an option and will be ignored.
1510061109691   geckodriver     INFO    geckodriver 0.18.0
1510061109708   geckodriver     INFO    Listening on 127.0.0.1:2885
1510061110162   geckodriver::marionette INFO    Starting browser /usr/bin/firefox with args ["-marionette"]
1510061111084   Marionette      INFO    Listening on port 43229
1510061111187   Marionette      WARN    TLS certificate errors will be ignored for this session
Nov 07, 2017 1:25:12 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
2017-11-07 13:25:12.714:INFO::main: Logging initialized @3915ms to org.seleniumhq.jetty9.util.log.StdErrLog
2017-11-07 13:25:12.804:INFO:osjs.Server:main: jetty-9.4.z-SNAPSHOT
2017-11-07 13:25:12.822:INFO:osjsh.ContextHandler:main: Started o.s.j.s.h.ContextHandler@87a85e1{/tests,null,AVAILABLE}
2017-11-07 13:25:12.843:INFO:osjs.AbstractConnector:main: Started ServerConnector@52102734{HTTP/1.1,[http/1.1]}{0.0.0.0:31892}
2017-11-07 13:25:12.843:INFO:osjs.Server:main: Started @4045ms
Nov 07, 2017 1:25:13 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |open | /auth_mellon.php |  |
Nov 07, 2017 1:25:14 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |waitForPageToLoad | 3000 |  |
.
.
.etc

<td>result:</td>
<td>PASS</td>
```

----
url: https://www.selenium.dev/zh-cn/documentation/legacy/selenium_2/
----

# Selenium 2

Selenium 2 是以实现了WebDriver代码重写的Selenium 1.

***

##### [从RC迁移到WebDriver](/zh-cn/documentation/legacy/selenium_2/upgrading/)

##### [远程WebDriver服务器](/zh-cn/documentation/legacy/selenium_2/remote_server/)

----
url: https://www.selenium.dev/ja/documentation/grid/getting_started/
----

# Gridを始める

Selenium Gridの導入方法

## クイックスタート

1. 事前条件

   * Java 11 もしくはそれ以上がインストールされていること

   * ブラウザーがインストールされていること

   * ブラウザードライバー

     * [Selenium Manager](https://www.selenium.dev/ja/documentation/selenium_manager/) will configure the drivers automatically if you add `--selenium-manager true`.
     * [`PATH` が通っているインストール済みのもの](https://www.selenium.dev/ja/documentation/webdriver/troubleshooting/errors/driver_location/#use-the-path-environment-variable)

```shell
java -jar selenium-server-<version>.jar standalone
```

```shell
java -jar selenium-server-<version>.jar hub
```

デフォルトでは、サーバーは<http://localhost:4444>にて `RemoteWebDriver` リクエストを待ち受けます。

#### ノード

**ノード**は起動時にシステムの[パス](https://www.selenium.dev/ja/documentation/webdriver/troubleshooting/errors/driver_location/#use-the-path-environment-variable) が通っている利用可能なドライバーを検出します。

次のコマンドは**ノード**が**ハブ**と同じマシン上で動作していることを前提としています。

```shell
java -jar selenium-server-<version>.jar node
```

##### 同一マシン上での複数ノード

ノード 1

```shell
java -jar selenium-server-<version>.jar node --port 5555
```

ノード 2

```shell
java -jar selenium-server-<version>.jar node --port 6666
```

##### 異なるマシンでノードとハブを動かす

**ハブ**と**ノード**は HTTP と[**イベントバス**](https://www.selenium.dev/ja/documentation/grid/components/#event-bus)を介して通信します (**イベントバス**は**ハブ**の一部として存在します)。 **ノード**は**イベントバス**を通じてメッセージを送信し、登録処理を開始します。 **ハブ**がメッセージを受け取り、**ノード**の存在を確かめるため HTTP を使って**ノード**にアクセスします。

**ハブ**がデフォルトのポートを使用していれば、 `--hub` フラグで**ノード**を登録することができます。

```shell
java -jar selenium-server-<version>.jar node --hub http://<hub-ip>:4444
```

**ハブ**がデフォルトのポートを使用していない場合、`--publish-events` と `--subscribe-events` のフラグが必要です。

例えば**ハブ**が `8886` `8887` `8888` ポートを利用している場合、

```shell
java -jar selenium-server-<version>.jar hub --publish-events tcp://<hub-ip>:8886 --subscribe-events tcp://<hub-ip>:8887 --port 8888
```

**ノード**はこれらのポートを登録する際に使用します。

```shell
java -jar selenium-server-<version>.jar node --publish-events tcp://<hub-ip>:8886 --subscribe-events tcp://<hub-ip>:8887
```

### 分散

分散 Grid を利用すると、各コンポーネントは別々に起動され異なるマシン上で動作します。

コンポーネント間で通信をするために、全てのポートを適切に公開することが重要です。

1. **イベントバス**は Grid コンポーネント間での内部通信を可能にします。

デフォルトポートは `4442`, `4443`, `5557` です。

```shell
java -jar selenium-server-<version>.jar event-bus --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --port 5557
```

2. **新規セッションキュー**は新規セッションリクエストをキューに積み、ディストリビューターがリクエストを取得できるようにします。

デフォルトポートは `5559` です。

```shell
java -jar selenium-server-<version>.jar sessionqueue --port 5559
```

3. **セッションマップ**はセッション ID とそのセッションが実行中の**ノード**のマップを持ちます。

デフォルトの**セッションマップ**のポートは `5556` です。 **セッションマップ**は**イベントバス**と通信します。

```shell
java -jar selenium-server-<version>.jar sessions --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --port 5556
```

4. **ディストリビューター**は**新規セッションキュー**に新規セッションリクエストを問い合わせ、 capabilities がマッチする**ノード**にアサインします。**ノード**は、**ハブ&ノード**構成の Grid における**ハブ**の登録と同じように、**ディストリビューター**に登録します。

デフォルトの**ディストリビューター**のポートは `5553` です。 **ディストリビューター**は**新規セッションキュー**、**セッションマップ**、**イベントバス**、**ノード**と通信します。

```shell
java -jar selenium-server-<version>.jar distributor --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --sessions http://<sessions-ip>:5556 --sessionqueue http://<new-session-queue-ip>:5559 --port 5553 --bind-bus false
```

5. **ルーター**は**新規セッションリクエスト**をキューに、既存セッションのリクエストをそのセッションが実行中の**ノード**に転送します。

デフォルトの**ルーター**のポートは `4444` です。 **ルーター**は**新規セッションキュー**、**セッションマップ**、**ディストリビューター**と通信します。

```shell
java -jar selenium-server-<version>.jar router --sessions http://<sessions-ip>:5556 --distributor http://<distributor-ip>:5553 --sessionqueue http://<new-session-queue-ip>:5559 --port 4444
```

6. ノード

デフォルトの**ノード**のポートは `5555` です。

```shell
java -jar selenium-server-<version>.jar node --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443
```

## テストメタデータ

テストにメタデータを追加して、[GraphQL](https://www.selenium.dev/ja/documentation/grid/advanced_features/graphql_support/) 経由で使用するか、Selenium Grid UI 経由でその一部( `se:name` など) を可視化します。

メタデータは capability に`se:`プリフィックスをつけることで追加できます。 Java での簡単な例を紹介します。

```java
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setCapability("browserVersion", "100");
chromeOptions.setCapability("platformName", "Windows");
// Showing a test name instead of the session id in the Grid UI
chromeOptions.setCapability("se:name", "My simple test");
// Other type of metadata can be seen in the Grid UI by clicking on the
// session info or via GraphQL
chromeOptions.setCapability("se:sampleMetadata", "Sample metadata value");
WebDriver driver = new RemoteWebDriver(new URL("http://gridUrl:4444"), chromeOptions);
driver.get("http://www.google.com");
driver.quit();
```

```bash
java -Dwebdriver.http.factory=jdk-http-client -jar selenium-server-<version>.jar --ext selenium-http-jdk-client-<version>.jar standalone
```

`selenium-http-jdk-client`をダウンロードする別の方法として[Coursier](https://get-coursier.io/docs/cli-installation)を使う方法があります。

```bash
java -Dwebdriver.http.factory=jdk-http-client -jar selenium-server-<version>.jar --ext $(coursier fetch -p org.seleniumhq.selenium:selenium-http-jdk-client:<version>) standalone
```

最終更新 August 1, 2025: [\[deploy site\] fixing bug 2402, detectify link removal (#2407) (0b29bc6e614)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/0b29bc6e6148f4e99aab014c39ae33e5fefe7222)

----
url: https://www.selenium.dev/zh-cn/documentation/legacy/selenium_ide/
----

# Legacy Selenium IDE

```html
<tr>
    <td>Command</td>
    <td>target (locator)</td>
    <td>Value</td>
</tr>
```

|            |              |       |
| ---------- | ------------ | ----- |
| verifyText | //div//a\[2] | Login |

The parameters are not always required; it depends on the command. In some cases both are required, in others one parameter is required, and in still others the command may take no parameters at all. Here are a couple more examples:

|                   |             |                         |
| ----------------- | ----------- | ----------------------- |
| goBackAndWait     |             |                         |
| verifyTextPresent |             | Welcome to My Home Page |
| type              | id=phone    | (555) 666-7066          |
| type              | id=address1 | ${myVariableAddress}    |

```html
<table>
    <tr><td>open</td><td>/download/</td><td></td></tr>
    <tr><td>assertTitle</td><td></td><td>Downloads</td></tr>
    <tr><td>verifyText</td><td>//h2</td><td>Downloads</td></tr>
</table>
```

Rendered as a table in a browser this would look like the following:

|             |            |           |
| ----------- | ---------- | --------- |
| open        | /download/ |           |
| assertTitle |            | Downloads |
| verifyText  | //h2       | Downloads |

The Selenese HTML syntax can be used to write and run tests without requiring knowledge of a programming language. With a basic knowledge of selenese and Selenium-IDE you can quickly produce and run testcases.

## Test Suites

A test suite is a collection of tests. Often one will run all the tests in a test suite as one continuous batch-job.

When using Selenium-IDE, test suites also can be defined using a simple HTML file. The syntax again is simple. An HTML table defines a list of tests where each row defines the filesystem path to each test. An example tells it all.

```html
<html>
<head>
<title>Test Suite Function Tests - Priority 1</title>
</head>
<body>
<table>
  <tr><td><b>Suite Of Tests</b></td></tr>
  <tr><td><a href="./Login.html">Login</a></td></tr>
  <tr><td><a href="./SearchValues.html">Test Searching for Values</a></td></tr>
  <tr><td><a href="./SaveValues.html">Test Save</a></td></tr>
</table>
</body>
</html>
```

| Command     | Target     | Value        |
| ----------- | ---------- | ------------ |
| open        | /download/ |              |
| assertTitle |            | Downloads    |
| verifyText  | //h2       | Downloads    |
| assertTable | 1.2.1      | Selenium IDE |
| verifyTable | 1.2.2      | June 3, 2008 |
| verifyTable | 1.2.3      | 1.0 beta 2   |

The above example first opens a page and then “asserts” that the correct page is loaded by comparing the title with the expected value. Only if this passes will the following command run and “verify” that the text is present in the expected location. The test case then “asserts” the first column in the second row of the first table contains the expected value, and only if this passed will the remaining cells in that row be “verified”.

### **verifyTextPresent**

The command `verifyTextPresent` is used to verify specific text exists somewhere on the page. It takes a single argument–the text pattern to be verified. For example:

| Command           | Target             | Value |
| ----------------- | ------------------ | ----- |
| verifyTextPresent | Marketing Analysis |       |

This would cause Selenium to search for, and verify, that the text string “Marketing Analysis” appears somewhere on the page currently being tested. Use verifyTextPresent when you are interested in only the text itself being present on the page. Do not use this when you also need to test where the text occurs on the page.

### **verifyElementPresent**

Use this command when you must test for the presence of a specific UI element, rather than its content. This verification does not check the text, only the HTML tag. One common use is to check for the presence of an image.

| Command              | Target      | Value |
| -------------------- | ----------- | ----- |
| verifyElementPresent | //div/p/img |       |

This command verifies that an image, specified by the existence of an HTML tag, is present on the page, and that it follows a

tag and a

tag. The first (and only) parameter is a locator for telling the Selenese command how to find the element. Locators are explained in the next section.

`verifyElementPresent` can be used to check the existence of any HTML tag within the page. You can check the existence of links, paragraphs, divisions

, etc. Here are a few more examples.

| Command              | Target                        | Value |
| -------------------- | ----------------------------- | ----- |
| verifyElementPresent | //div/p                       |       |
| verifyElementPresent | //div/a                       |       |
| verifyElementPresent | id=Login                      |       |
| verifyElementPresent | link=Go to Marketing Research |       |
| verifyElementPresent | //a\[2]                       |       |
| verifyElementPresent | //head/title                  |       |

These examples illustrate the variety of ways a UI element may be tested. Again, locators are explained in the next section.

### **verifyText**

Use `verifyText` when both the text and its UI element must be tested. verifyText must use a locator. If you choose an *XPath* or *DOM* locator, you can verify that specific text appears at a specific location on the page relative to other UI components on the page.

| Command    | Target              | Value                                                               |
| ---------- | ------------------- | ------------------------------------------------------------------- |
| verifyText | //table/tr/td/div/p | This is my text and it occurs right after the div inside the table. |

## Locating Elements

For many Selenium commands, a target is required. This target identifies an element in the content of the web application, and consists of the location strategy followed by the location in the format `locatorType=location`. The locator type can be omitted in many cases. The various locator types are explained below with examples for each.

### Locating by Identifier

This is probably the most common method of locating elements and is the catch-all default when no recognized locator type is used. With this strategy, the first element with the id attribute value matching the location will be used. If no element has a matching id attribute, then the first element with a name attribute matching the location will be used.

For instance, your page source could have id and name attributes as follows:

```html
  <html>
   <body>
    <form id="loginForm">
     <input name="username" type="text" />
     <input name="password" type="password" />
     <input name="continue" type="submit" value="Login" />
    </form>
   </body>
  <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
    </body>
   <html>
```

* `id=loginForm` (3)

### Locating by Name

The name locator type will locate the first element with a matching name attribute. If multiple elements have the same value for a name attribute, then you can use filters to further refine your location strategy. The default filter type is value (matching the value attribute).

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
  <html>
   <body>
    <p>Are you sure you want to do this?</p>
    <a href="continue.html">Continue</a> 
    <a href="cancel.html">Cancel</a>
  </body>
  <html>
```

* `link=Continue` (4)
* `link=Cancel` (5)

### Locating by DOM

The Document Object Model represents an HTML document and can be accessed using JavaScript. This location strategy takes JavaScript that evaluates to an element on the page, which can be simply the element’s location using the hierarchical dotted notation.

Since only `dom` locators start with “document”, it is not necessary to include the `dom=` label when specifying a DOM locator.

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input class="required" name="username" type="text" />
      <input class="required passfield" name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | glob:\*Film\*Television\*             |       |

The actual title of the page reached by clicking on the link was “De Anza Film And Television Department - Menu”. By using a pattern rather than the exact text, the `verifyTitle` will pass as long as the two words “Film” and “Television” appear (in that order) anywhere in the page’s title. For example, if the page’s owner should shorten the title to just “Film & Television Department,” the test would still pass. Using a pattern for both a link and a simple test that the link worked (such as the `verifyTitle` above does) can greatly reduce the maintenance for such test cases.

#### Regular Expression Patterns

*Regular expression* patterns are the most powerful of the three types of patterns that Selenese supports. Regular expressions are also supported by most high-level programming languages, many text editors, and a host of tools, including the Linux/Unix command-line utilities **grep**, **sed**, and **awk**. In Selenese, regular expression patterns allow a user to perform many tasks that would be very difficult otherwise. For example, suppose your test needed to ensure that a particular table cell contained nothing but a number. `regexp: [0-9]+` is a simple pattern that will match a decimal number of any length.

Whereas Selenese globbing patterns support only the **\*** and **\[ ]** (character class) features, Selenese regular expression patterns offer the same wide array of special characters that exist in JavaScript. Below are a subset of those special characters:

| PATTERN | MATCH                                                                            |
| ------- | -------------------------------------------------------------------------------- |
| .       | any single character                                                             |
| \[ ]    | character class: any single character that appears inside the brackets           |
| \*      | quantifier: 0 or more of the preceding character (or group)                      |
| +       | quantifier: 1 or more of the preceding character (or group)                      |
| ?       | quantifier: 0 or 1 of the preceding character (or group)                         |
| {1,5}   | quantifier: 1 through 5 of the preceding character (or group)                    |
| \|      | alternation: the character/group on the left or the character/group on the right |
| ( )     | grouping: often used with alternation and/or quantifier                          |

Regular expression patterns in Selenese need to be prefixed with either `regexp:` or `regexpi:`. The former is case-sensitive; the latter is case-insensitive.

A few examples will help clarify how regular expression patterns can be used with Selenese commands. The first one uses what is probably the most commonly used regular expression pattern–**.\*** (“dot star”). This two-character sequence can be translated as “0 or more occurrences of any character” or more simply, “anything or nothing.” It is the equivalent of the one-character globbing pattern **\*** (a single asterisk).

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | regexp:.\*Film.\*Television.\*        |       |

The example above is functionally equivalent to the earlier example that used globbing patterns for this same test. The only differences are the prefix (**regexp:** instead of **glob:**) and the “anything or nothing” pattern (**.\*** instead of just **\***).

The more complex example below tests that the Yahoo! Weather page for Anchorage, Alaska contains info on the sunrise time:

| Command           | Target                                            | Value |
| ----------------- | ------------------------------------------------- | ----- |
| open              | <http://weather.yahoo.com/forecast/USAK0012.html> |       |
| verifyTextPresent | regexp:Sunrise: \*\[0-9]{1,2}:\[0-9]{2} \[ap]m    |       |

Let’s examine the regular expression above one part at a time:

|              |                                                      |
| ------------ | ---------------------------------------------------- |
| `Sunrise: *` | The string **Sunrise:** followed by 0 or more spaces |
| `[0-9]{1,2}` | 1 or 2 digits (for the hour of the day)              |
| `:`          | The character **:** (no special characters involved) |
| `[0-9]{2}`   | 2 digits (for the minutes) followed by a space       |
| `[ap]m`      | “a” or “p” followed by “m” (am or pm)                |

#### Exact Patterns

The **exact** type of Selenium pattern is of marginal usefulness. It uses no special characters at all. So, if you needed to look for an actual asterisk character (which is special for both globbing and regular expression patterns), the **exact** pattern would be one way to do that. For example, if you wanted to select an item labeled “Real \*” from a dropdown, the following code might work or it might not. The asterisk in the `glob:Real *` pattern will match anything or nothing. So, if there was an earlier select option labeled “Real Numbers,” it would be the option selected rather than the “Real \*” option.

| Command | Target   | Value        |
| ------- | -------- | ------------ |
| select  | //select | glob:Real \* |

In order to ensure that the “Real \*” item would be selected, the `exact:` prefix could be used to create an **exact** pattern as shown below:

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| select  | //select | exact:Real \* |

But the same effect could be achieved via escaping the asterisk in a regular expression pattern:

| Command | Target   | Value            |
| ------- | -------- | ---------------- |
| select  | //select | regexp:Real \\\* |

| Command | Target            | Value |
| ------- | ----------------- | ----- |
| store   | <paul@mysite.org> |       |

Later in your script, you’ll want to use the stored value of your variable. To access the value of a variable, enclose the variable in curly brackets ({}) and precede it with a dollar sign like this.

| Command    | Target  | Value         |
| ---------- | ------- | ------------- |
| verifyText | //div/p | \\${userName} |

A common use of variables is for storing input for an input field.

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| type    | id=login | \\${userName} |

| Command         | Target                                         | Value       |
| --------------- | ---------------------------------------------- | ----------- |
| store           | 10                                             | hits        |
| storeXpathCount | //blockquote                                   | blockquotes |
| storeEval       | storedVars\[‘hits’].storedVars\[‘blockquotes’] | paragraphs  |

This next example illustrates how a JavaScript snippet can include calls to methods, in this case the JavaScript String object’s `toUpperCase` method and `toLowerCase` method.

| Command   | Target                            | Value |
| --------- | --------------------------------- | ----- |
| store     | Edith Wharton                     | name  |
| storeEval | storedVars\[’name’].toUpperCase() | uc    |
| storeEval | storedVars\[’name’].toUpperCase() | lc    |

#### JavaScript Usage with Non-Script Parameters

JavaScript can also be used to help generate values for parameters, even when the parameter is not specified to be of type **script**.\
However, in this case, special syntax is required–the *entire* parameter value must be prefixed by `javascript{` with a trailing `}`, which encloses the JavaScript snippet, as in `javascript{*yourCodeHere*}`. Below is an example in which the `type` command’s second parameter `value` is generated via JavaScript code using this special syntax:

| Command | Target            | Value                                                 |
| ------- | ----------------- | ----------------------------------------------------- |
| store   | league of nations | searchString                                          |
| type    | q                 | javascript{storedVars\[‘searchString’].toUpperCase()} |

## *echo* - The Selenese Print Command

Selenese has a simple command that allows you to print text to your test’s output. This is useful for providing informational progress notes in your test which display on the console as your test is running. These notes also can be used to provide context within your test result reports, which can be useful for finding where a defect exists on a page in the event your test finds a problem. Finally, echo statements can be used to print the contents of Selenium variables.

| Command | Target                    | Value |
| ------- | ------------------------- | ----- |
| echo    | Testing page footer now.  |       |
| echo    | Username is \\${userName} |       |

## Alerts, Popups, and Multiple Windows

Suppose that you are testing a page that looks like this.

```html
  <!DOCTYPE HTML>
  <html>
  <head>
    <script type="text/javascript">
      function output(resultText){
        document.getElementById('output').childNodes[0].nodeValue=resultText;
      }

      function show_confirm(){
        var confirmation=confirm("Chose an option.");
        if (confirmation==true){
          output("Confirmed.");
        }
        else{
          output("Rejected!");
        }
      }
      
      function show_alert(){
        alert("I'm blocking!");
        output("Alert is gone.");
      }
      function show_prompt(){
        var response = prompt("What's the best web QA tool?","Selenium");
        output(response);
      }
      function open_window(windowName){
        window.open("newWindow.html",windowName);
      }
      </script>
  </head>
  <body>

    <input type="button" id="btnConfirm" onclick="show_confirm()" value="Show confirm box" />
    <input type="button" id="btnAlert" onclick="show_alert()" value="Show alert" />
    <input type="button" id="btnPrompt" onclick="show_prompt()" value="Show prompt" />
    <a href="newWindow.html" id="lnkNewWindow" target="_blank">New Window Link</a>
    <input type="button" id="btnNewNamelessWindow" onclick="open_window()" value="Open Nameless Window" />
    <input type="button" id="btnNewNamedWindow" onclick="open_window('Mike')" value="Open Named Window" />

    <br />
    <span id="output">
    </span>
  </body>
  </html>
```

The user must respond to alert/confirm boxes, as well as moving focus to newly opened popup windows. Fortunately, Selenium can cover JavaScript pop-ups.

But before we begin covering alerts/confirms/prompts in individual detail, it is helpful to understand the commonality between them. Alerts, confirmation boxes and prompts all have variations of the following

| Command                   | Description                                                           |
| ------------------------- | --------------------------------------------------------------------- |
| assertFoo(pattern)        | throws error if pattern doesn’t match the text of the pop-up          |
| assertFooPresent          | throws error if pop-up is not available                               |
| assertFooNotPresent       | throws error if any pop-up is present                                 |
| storeFoo(variable)        | stores the text of the pop-up in a variable                           |
| storeFooPresent(variable) | stores the text of the pop-up in a variable and returns true or false |

When running under Selenium, JavaScript pop-ups will not appear. This is because the function calls are actually being overridden at runtime by Selenium’s own JavaScript. However, just because you cannot see the pop-up doesn’t mean you don’t have to deal with it. To handle a pop-up, you must call its `assertFoo(pattern)` function. If you fail to assert the presence of a pop-up your next command will be blocked and you will get an error similar to the following `[error] Error: There was an unexpected Confirmation! [Chose an option.]`

### Alerts

Let’s start with alerts because they are the simplest pop-up to handle. To begin, open the HTML sample above in a browser and click on the “Show alert” button. You’ll notice that after you close the alert the text “Alert is gone.” is displayed on the page. Now run through the same steps with Selenium IDE recording, and verify the text is added after you close the alert. Your test will look something like this:

| Command           | Target         | Value |
| ----------------- | -------------- | ----- |
| open              | /              |       |
| click             | btnAlert       |       |
| assertAlert       | I’m blocking!  |       |
| verifyTextPresent | Alert is gone. |       |

You may be thinking “That’s odd, I never tried to assert that alert.” But this is Selenium-IDE handling and closing the alert for you. If you remove that step and replay the test you will get the following error `[error] Error: There was an unexpected Alert! [I'm blocking!]`. You must include an assertion of the alert to acknowledge its presence.

If you just want to assert that an alert is present but either don’t know or don’t care what text it contains, you can use `assertAlertPresent`. This will return true or false, with false halting the test.

### Confirmations

Confirmations behave in much the same way as alerts, with `assertConfirmation` and `assertConfirmationPresent` offering the same characteristics as their alert counterparts. However, by default Selenium will select OK when a confirmation pops up. Try recording clicking on the “Show confirm box” button in the sample page, but click on the “Cancel” button in the popup, then assert the output text. Your test may look something like this:

| Command                        | Target            | Value |
| ------------------------------ | ----------------- | ----- |
| open                           | /                 |       |
| click                          | btnConfirm        |       |
| chooseCancelOnNextConfirmation |                   |       |
| assertConfirmation             | Choose an option. |       |
| verifyTextPresent              | Rejected          |       |

The `chooseCancelOnNextConfirmation` function tells Selenium that all following confirmation should return false. It can be reset by calling chooseOkOnNextConfirmation.

You may notice that you cannot replay this test, because Selenium complains that there is an unhandled confirmation. This is because the order of events Selenium-IDE records causes the click and chooseCancelOnNextConfirmation to be put in the wrong order (it makes sense if you think about it, Selenium can’t know that you’re cancelling before you open a confirmation) Simply switch these two commands and your test will run fine.

### Prompts

Prompts behave in much the same way as alerts, with `assertPrompt` and `assertPromptPresent` offering the same characteristics as their alert counterparts. By default, Selenium will wait for you to input data when the prompt pops up. Try recording clicking on the “Show prompt” button in the sample page and enter “Selenium” into the prompt. Your test may look something like this:

| Command            | Target                       | Value |
| ------------------ | ---------------------------- | ----- |
| open               | /                            |       |
| answerOnNextPrompt | Selenium!                    |       |
| click              | id=btnPrompt                 |       |
| assertPrompt       | What’s the best web QA tool? |       |
| verifyTextPresent  | Selenium!                    |       |

```html
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Sample Selenium Test Suite</title>
    </head>
    <body>
        <table cellpadding="1" cellspacing="1" border="1">
            <thead>
                <tr><td>Test Cases for De Anza A-Z Directory Links</td></tr>
            </thead>
        <tbody>
            <tr><td><a href="./a.html">A Links</a></td></tr>
            <tr><td><a href="./b.html">B Links</a></td></tr>
            <tr><td><a href="./c.html">C Links</a></td></tr>
            <tr><td><a href="./d.html">D Links</a></td></tr>
        </tbody>
        </table>
    </body>
</html>
```

***

*error loading test case: no command found*

You’ve used **File=>Open** to try to open a test suite file. Use **File=>Open Test Suite** instead.

An enhancement request has been raised to improve this error message. See [issue 1010](http://code.google.com/p/selenium/issues/detail?id=1010).

***

This type of **error** may indicate a timing problem, i.e., the element specified by a locator in your command wasn’t fully loaded when the command was executed. Try putting a **pause 5000** before the command to determine whether the problem is indeed related to timing. If so, investigate using an appropriate **waitFor\*** or **\*AndWait** command before the failing command.

***

Whenever your attempt to use variable substitution fails as is the case for the **open** command above, it indicates that you haven’t actually created the variable whose value you’re trying to access. This is sometimes due to putting the variable in the **Value** field when it should be in the **Target** field or vice versa. In the example above, the two parameters for the **store** command have been erroneously placed in the reverse order of what is required. For any Selenese command, the first required parameter must go in the **Target** field, and the second required parameter (if one exists) must go in the **Value** field.

***

*error loading test case: \[Exception… “Component returned failure code: 0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND) \[nsIFileInputStream.init]” nresult: “0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND)” location: “JS frame :: chrome://selenium-ide/content/file-utils.js :: anonymous :: line 48” data: no]*

One of the test cases in your test suite cannot be found. Make sure that the test case is indeed located where the test suite indicates it is located. Also, make sure that your actual test case files have the .html extension both in their filenames, and in the test suite file where they are referenced.

An enhancement request has been raised to improve this error message. See [issue 1011](http://code.google.com/p/selenium/issues/detail?id=1011).

***

Your extension file’s contents have not been read by Selenium-IDE. Be sure you have specified the proper pathname to the extensions file via **Options=>Options=>General** in the **Selenium Core extensions** field. Also, Selenium-IDE must be restarted after any change to either an extensions file *or* to the contents of the **Selenium Core extensions** field.

***

##### [HTML runner](/zh-cn/documentation/legacy/selenium_ide/html_runner/)

Execute HTML Selenium IDE exports from command line

----
url: https://www.selenium.dev/ja/documentation/test_practices/encouraged/generating_application_state/
----

# アプリケーション状態の生成

Seleniumはテストケースの準備に使用しないでください。 テストケースのすべての反復アクションと準備は、他の方法で行う必要があります。 たとえば、ほとんどのWeb UIには認証があります（ログインフォームなど）。 すべてのテストの前にWebブラウザーからのログインをなくすことで、テストの速度と安定性の両方が向上します。 AUT\* にアクセスするためのメソッドを作成する必要があります（APIを使用してログインし、Cookieを設定するなど）。 また、テスト用にデータをプリロードするメソッドの作成は、Seleniumを使用して実行しないほうがいいです。 前述のように、AUT\* のデータを作成するには、既存のAPIを活用する必要があります。

----
url: https://www.selenium.dev/zh-cn/_print/documentation/webdriver/troubleshooting/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/webdriver/troubleshooting/).

# 故障排除协助

如何管理 WebDriver 的问题.

* 1: [理解常见的异常](#pg-fdcbcf8272e5dd9155ba97624972a018)
* * 1.1: [Unable to Locate Driver Error](#pg-65b4566cad18a000d8a33a1e9db619c8)
  2: [记录 Selenium 命令](#pg-50a81a53af8a6ba57435d202700731ad)
* 3: [升级到Selenium 4](#pg-655a423a43b0685360421fd820dd23d6)

Selenium错误的根本原因并不总是很明显.

1. 最常见的Selenium相关错误, 是源自未及时同步的结果. 请阅读 [等待策略](https://www.selenium.dev/zh-cn/documentation/webdriver/waits/). 当遇到一个问题, 如果不确定是否因为同步策略, 您可以尝试*暂时*硬编码一个较大的休眠时间, 您将明确添加显式等待是否有帮助.

2. 请注意, 报告给项目的许多错误, 实际上是由Selenium向其发送命令的基础驱动程序所引起的. 您可以通过执行 [浏览器](https://www.selenium.dev/zh-cn/documentation/webdriver/browsers/) 中的 多个命令来解决驱动程序问题.

3. 如果您对如何执行有疑惑, 请查看 [支持选项](/support/) 获取帮助的方法.

4. 如果您认为您发现了Selenium代码的问题, 请在Github上提交 [问题报告](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=I-defect%2Cneeds-triaging\&template=bug-report.yml\&title=%5B%F0%9F%90%9B+Bug%5D%3A+).

# 1 - 理解常见的异常

# 1.1 - Unable to Locate Driver Error

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.bash_profile
source ~/.bash_profile
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Terminal and execute:

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.zshenv
source ~/.zshenv
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Command Prompt and execute:

```shell
echo %PATH%
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
setx PATH "%PATH%;C:\WebDriver\bin"
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver.exe --version
```

| 浏览器               | 支持的操作系统                     | 维护者              | 下载                                                                    | 问题追溯                                                             |
| ----------------- | --------------------------- | ---------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------- |
| Chromium/Chrome   | Windows/macOS/Linux         | Google           | [下载](//chromedriver.chromium.org/downloads)                           | [Issues](//bugs.chromium.org/p/chromedriver/issues/list)         |
| Firefox           | Windows/macOS/Linux         | Mozilla          | [下载](//github.com/mozilla/geckodriver/releases)                       | [Issues](//github.com/mozilla/geckodriver/issues)                |
| Edge              | Windows/macOS/Linux         | Microsoft        | [下载](//developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/) | [Issues](https://github.com/MicrosoftDocs/edge-developer/issues) |
| Internet Explorer | Windows                     | Selenium Project | [下载](/downloads)                                                      | [Issues](//github.com/SeleniumHQ/selenium/labels/D-IE)           |
| Safari            | macOS High Sierra and newer | Apple            | 内置                                                                    | [Issues](//bugreport.apple.com/logon)                            |

备注：Opera驱动不再适用于Selenium的最新功能，目前官方不支持。

# 2 - 记录 Selenium 命令

```java
    public void logging() throws IOException {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Java日志并不简单直接, 如果您只是在寻找一种简单的方法 查看重要的Selenium日志, 请参阅 [Selenium Logger 项目](https://github.com/titusfortner/selenium-logger#selenium-logger)

Python logs are typically created per module. You can match all submodules by referencing the top level module. So to work with all loggers in selenium module, you can do this:

```py
    logger = logging.getLogger('selenium')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L5)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

You must also create and add a log handler (`StreamHandler`, `FileHandler`, etc).

To save logs to a file, you can do this:

```py
log_path = '/path/to/log'
handler = logging.FileHandler(log_path)
logger.addHandler(handler)
```

To display logs in the console, you can do this:

```py
handler = logging.StreamHandler()
logger.addHandler(handler)
```

.NET logger is managed with a static class, so all access to logging is managed simply by referencing `Log` from the `OpenQA.Selenium.Internal.Logging` namespace.

If you want to see as much debugging as possible in all the classes, you can turn on debugging globally in Ruby by setting `$DEBUG = true`.

For more fine-tuned control, Ruby Selenium created its own Logger class to wrap the default `Logger` class. This implementation provides some interesting additional features. Obtain the logger directly from the `#logger`class method on the `Selenium::WebDriver` module:

```rb
    logger = Selenium::WebDriver.logger
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L11)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

```javascript
const logging = require('selenium-webdriver/lib/logging')
logger = logging.getLogger('webdriver')
```

```java
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L32-L35)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Python has 6 logger levels: `CRITICAL`, `ERROR`, `WARNING`, `INFO`, `DEBUG`, and `NOTSET`. The default is `WARNING`

To change the level of the logger:

```py
    logger.setLevel(logging.DEBUG)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L7)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

Things get complicated when you use PyTest, though. By default, PyTest hides logging unless the test fails. You need to set 3 things to get PyTest to display logs on passing tests.

To always output logs with PyTest you need to run with additional arguments. First, `-s` to prevent PyTest from capturing the console. Second, `-p no:logging`, which allows you to override the default PyTest logging settings so logs can be displayed regardless of errors.

So you need to set these flags in your IDE, or run PyTest on command line like:

```bash
pytest -s -p no:logging
```

Finally, since you turned off logging in the arguments above, you now need to add configuration to turn it back on:

```py
logging.basicConfig(level=logging.WARN)
```

.NET has 6 logger levels: `Error`, `Warn`, `Info`, `Debug`, `Trace` and `None`. The default level is `Warn`.

To change the level of the logger:

```cs
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L18)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

Ruby logger has 5 logger levels: `:debug`, `:info`, `:warn`, `:error`, `:fatal`. As of Selenium v4.9.1, The default is `:info`.

To change the level of the logger:

```rb
    logger.level = :debug
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L13)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

JavaScript has 9 logger levels: `OFF`, `SEVERE`, `WARNING`, `INFO`, `DEBUG`, `FINE`, `FINER`, `FINEST`, `ALL`. The default is `OFF`.

To change the level of the logger:

```javascript
logger.setLevel(logging.Level.INFO)
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
WARNING: this is a warning
```

Python logs actionable content at logger level — `WARNING` Details about deprecations are logged at this level.

Example:

```text
WARNING  selenium:test_logging.py:23 this is a warning
```

.NET logs actionable content at logger level `Warn`.

Example:

```text
11:04:40.986 WARN LoggingTest: this is a warning
```

Ruby logs actionable content at logger level — `:warn`. Details about deprecations are logged at this level.

For example:

```text
2023-05-08 20:53:13 WARN Selenium [:example_id] this is a warning 
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
INFO: this is useful information
```

Python logs useful information at logger level — `INFO`

Example:

```text
INFO     selenium:test_logging.py:22 this is useful information
```

.NET logs useful information at logger level `Info`.

Example:

```text
11:04:40.986 INFO LoggingTest: this is useful information
```

Ruby logs useful information at logger level — `:info`.

Example:

```text
2023-05-08 20:53:13 INFO Selenium [:example_id] this is useful information 
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
FINE: this is detailed debug information
```

Python logs debugging details at logger level — `DEBUG`

Example:

```text
DEBUG    selenium:test_logging.py:24 this is detailed debug information
```

.NET logs most debug content at logger level `Debug`.

Example:

```text
11:04:40.986 DEBUG LoggingTest: this is detailed debug information
```

Ruby only provides one level for debugging, so all details are at logger level — `:debug`.

Example:

```text
2023-05-08 20:53:13 DEBUG Selenium [:example_id] this is detailed debug information 
```

```java

      Path output = artifactsDir().resolve("selenium.xml");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L37-L38)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

By default all logs are sent to `sys.stderr`. To direct output somewhere else, you need to add a handler with either a `StreamHandler` or a `FileHandler`:

```py
    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L9-L10)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

By default all logs are sent to `System.Console.Error` output. To direct output somewhere else, you need to add a handler with a `FileLogHandler`:

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L20)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

By default, logs are sent to the console in `stdout`.\
To store the logs in a file:

```rb
    logger.output = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L15)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

JavaScript does not currently support sending output to a file.

To send logs to console output:

```javascript
logging.installConsoleHandler()
```

```java
        logger.addHandler(handler);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L40-L41)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Because logging is managed by module, instead of working with just "selenium", you can specify different levels for different modules:

```py
    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L12-L13)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

.NET logging is managed on a per class level, set the level you want to use on a per-class basis:

```cs

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

Ruby’s logger allows you to opt in (“allow”) or opt out (“ignore”) of log messages based on their IDs. Everything that Selenium logs includes an ID. You can also turn on or off all deprecation notices by using `:deprecations`.

These methods accept one or more symbols or an array of symbols:

```rb
    logger.ignore(:jwp_caps, :logger_info)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L17)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

or

```rb
    logger.allow(%i[selenium_manager example_id])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L18)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

# 3 - 升级到Selenium 4

```java
DesiredCapabilities caps = DesiredCapabilities.firefox();
caps.setCapability("platform", "Windows 10");
caps.setCapability("version", "92");
caps.setCapability("build", myTestBuild);
caps.setCapability("name", myTestName);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), caps);
```

```javascript
caps = {};
caps['browserName'] = 'Firefox';
caps['platform'] = 'Windows 10';
caps['version'] = '92';
caps['build'] = myTestBuild;
caps['name'] = myTestName;
```

```csharp
DesiredCapabilities caps = new DesiredCapabilities();
caps.SetCapability("browserName", "firefox");
caps.SetCapability("platform", "Windows 10");
caps.SetCapability("version", "92");
caps.SetCapability("build", myTestBuild);
caps.SetCapability("name", myTestName);
var driver = new RemoteWebDriver(new Uri(CloudURL), caps);
```

```rb
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L123-L130)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```python
caps = {}
caps['browserName'] = 'firefox'
caps['platform'] = 'Windows 10'
caps['version'] = '92'
caps['build'] = my_test_build
caps['name'] = my_test_name
driver = webdriver.Remote(cloud_url, desired_capabilities=caps)
```

```java
FirefoxOptions browserOptions = new FirefoxOptions();
browserOptions.setPlatformName("Windows 10");
browserOptions.setBrowserVersion("92");
Map<String, Object> cloudOptions = new HashMap<>();
cloudOptions.put("build", myTestBuild);
cloudOptions.put("name", myTestName);
browserOptions.setCapability("cloud:options", cloudOptions);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), browserOptions);
```

```javascript
capabilities = {
  browserName: 'firefox',
  browserVersion: '92',
  platformName: 'Windows 10',
  'cloud:options': {
     build: myTestBuild,
     name: myTestName,
  }
}
```

```csharp
var browserOptions = new FirefoxOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "92";
var cloudOptions = new Dictionary<string, object>();
cloudOptions.Add("build", myTestBuild);
cloudOptions.Add("name", myTestName);
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);
var driver = new RemoteWebDriver(new Uri(CloudURL), browserOptions);
```

```rb
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L38-L47)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```python
from selenium.webdriver.firefox.options import Options as FirefoxOptions
options = FirefoxOptions()
options.browser_version = '92'
options.platform_name = 'Windows 10'
cloud_options = {}
cloud_options['build'] = my_test_build
cloud_options['name'] = my_test_name
options.set_capability('cloud:options', cloud_options)
driver = webdriver.Remote(cloud_url, options=options)
```

### 在 Java 中查找元素工具方法

在 Java 绑定(`FindsBy` 接口)中 查找元素的工具方法已被删除 因为它们仅供内部使用.\
以下代码示例更好地解释了这一点.

使用 `findElement*` 查找单个元素

Before

```java

driver.findElementByClassName("className");
driver.findElementByCssSelector(".className");
driver.findElementById("elementId");
driver.findElementByLinkText("linkText");
driver.findElementByName("elementName");
driver.findElementByPartialLinkText("partialText");
driver.findElementByTagName("elementTagName");
driver.findElementByXPath("xPath");
```

After

```java

driver.findElement(By.className("className"));
driver.findElement(By.cssSelector(".className"));
driver.findElement(By.id("elementId"));
driver.findElement(By.linkText("linkText"));
driver.findElement(By.name("elementName"));
driver.findElement(By.partialLinkText("partialText"));
driver.findElement(By.tagName("elementTagName"));
driver.findElement(By.xpath("xPath"));
```

使用 `findElements*` 查找多个元素

Before

```java

driver.findElementsByClassName("className");
driver.findElementsByCssSelector(".className");
driver.findElementsById("elementId");
driver.findElementsByLinkText("linkText");
driver.findElementsByName("elementName");
driver.findElementsByPartialLinkText("partialText");
driver.findElementsByTagName("elementTagName");
driver.findElementsByXPath("xPath");
```

After

```java

driver.findElements(By.className("className"));
driver.findElements(By.cssSelector(".className"));
driver.findElements(By.id("elementId"));
driver.findElements(By.linkText("linkText"));
driver.findElements(By.name("elementName"));
driver.findElements(By.partialLinkText("partialText"));
driver.findElements(By.tagName("elementTagName"));
driver.findElements(By.xpath("xPath"));
```

```xml

<dependencies>
  <!-- more dependencies ... -->
  <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.141.59</version>
  </dependency>
  <!-- more dependencies ... -->
</dependencies>
```

After

```xml

<dependencies>
    <!-- more dependencies ... -->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.4.0</version>
    </dependency>
    <!-- more dependencies ... -->
</dependencies>
```

进行更改后, 您可以在`pom.xml` 文件的同一目录中 执行 `mvn clean compile` .

#### Gradle

Before

```jsonpath

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter: junit-jupiter-api: 5.7.0'
    testRuntimeOnly 'org.junit.jupiter: junit-jupiter-engine: 5.7.0'
    implementation group:  'org.seleniumhq.selenium', name:  'selenium-java', version:  '3.141.59'
}
test {
    useJUnitPlatform()
}
```

After

```jsonpath

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter: junit-jupiter-api: 5.7.0'
    testRuntimeOnly 'org.junit.jupiter: junit-jupiter-engine: 5.7.0'
    implementation group:  'org.seleniumhq.selenium', name:  'selenium-java', version:  '4.4.0'
}
test {
    useJUnitPlatform()
}
```

进行更改后, 您可以在 build.gradle 文件所在的同一目录中 执行`./gradlew clean build` .

要检查所有 Java 版本, 您可以前往 [MVNRepository](https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java) .

### C\#

在 C# 中获取 Selenium 4 更新的 地方是 [NuGet](https://www.nuget.org/) .\
在下面包 [`Selenium.WebDriver`](https://www.nuget.org/packages/Selenium.WebDriver/4.4.0) 你可以获得更新到最新版本的说明.\
在 Visual Studio 内部, 您可以通过 NuGet 包管理器执行：

```shell
PM> Install-Package Selenium.WebDriver -Version 4.4.0
```

### Python

使用 Python 的最重要变化是所需的最低版本. Selenium 4 将至少需要 Python 3.7 或更高版本.\
更多详细信息可以在 [Python 包索引](https://pypi.org/project/selenium/4.4.3/) .\
基于命令行做升级的话, 你可以执行:

```shell
pip install selenium==4.4.3
```

### Ruby

Selenium 4 的更新细节 可以在RubyGems中的gem发现 [selenium-webdriver](https://rubygems.org/gems/selenium-webdriver/versions/4.4.0) .\
要安装最新版本, 您可以执行:

```shell
gem install selenium-webdriver
```

将以下内容添加到你的Gemfile:

```shell
gem 'selenium-webdriver', '~> 4.4.0'
```

### JavaScript

可以在 Node 包管理器中找到 selenium-webdriver 包, [npmjs](https://www.npmjs.com) .\
Selenium 4 可以在 [这里](https://www.npmjs.com/package/selenium-webdriver/v/4.4.0) 找到.\
要安装, 你可以执行:

```shell
npm install selenium-webdriver
```

或者, 更新你的 package.json 并运行 `npm install` :

```json
{
  "name":  "selenium-tests",
  "version":  "1.0.0",
  "dependencies":  {
    "selenium-webdriver":  "^4.4.0"
  }
}
```

## 潜在错误和弃用消息

这是一组代码示例, 它们将有助于克服 您升级到 Selenium 4 后 可能会遇到的弃用消息.

### Java

#### 等待和超时

Timeout 中接收到的参数 已经从期望 `(long time, TimeUnit unit)` 切换到期待 `(Duration duration)` .

Before

```java

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(2, TimeUnit.MINUTES);
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
```

After

```java

driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().timeouts().scriptTimeout(Duration.ofMinutes(2));
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
```

等待现在也期望不同的参数. `WebDriverWait` 现在期待一个 `Duration` 而不是以秒和毫秒为单位的 `long` 超时. `FluentWait` 的工具方法 `withTimeout` 和 `pollingEvery` 已经从期望 `(long time, TimeUnit unit)` 切换到 期待`(Duration duration)` .

Before

```java

new WebDriverWait(driver, 3)
.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(30, TimeUnit.SECONDS)
  .pollingEvery(5, TimeUnit.SECONDS)
  .ignoring(NoSuchElementException.class);
```

After

```java

new WebDriverWait(driver, Duration.ofSeconds(3))
  .until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

  Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(Duration.ofSeconds(30))
  .pollingEvery(Duration.ofSeconds(5))
  .ignoring(NoSuchElementException.class);
```

#### 合并capabilities不再改变调用对象

曾经可以将一组不同的capabilities合并到另一组中, 并且改变调用对象.\
现在, 需要分配合并操作的结果.

Before

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options.merge(capabilities);

//作为结果, `options` 对象被修改
```

After

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options = options.merge(capabilities);

// `merge` 调用的结果需要分配给一个对象.
```

#### Firefox 遗留模式

在 GeckoDriver 出现之前, Selenium 项目有一个驱动程序实现来自动化 Firefox(版本 <48).\
但是, 不再需要此实现, 因为在最新版本的 Firefox 中它不起作用.\
为避免升级到 Selenium 4 时出现重大问题, `setLegacy`选项将显示为已弃用.\
建议停止使用旧的实现 并且只依赖 GeckoDriver.\
以下代码将显示在升级之后弃用的 `setLegacy` 行.

```java
FirefoxOptions options = new FirefoxOptions();
options.setLegacy(true);
```

#### `BrowserType`

`BrowserType` 接口已经存在很长时间了, 但是其已变为弃用 且推荐使用新的 `Browser` 接口.

Before

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", BrowserType.FIREFOX);
```

After

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", Browser.FIREFOX);
```

### C\#

#### `AddAdditionalCapability` 已弃用

推荐使用`AddAdditionalOption`替代.\
以下为一个示例:

Before

```cs

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalCapability("cloud: options", cloudOptions, true);
```

After

```cs

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalOption("cloud: options", cloudOptions);
```

### Python

#### `executable_path 已弃用, 请传递一个服务对象`

在Selenium 4中,\
您需要从服务对象设置驱动程序的 `可执行路径` , 以防止出现弃用警告. (或者不要设置路径, 而是确保所需的驱动程序位于系统路径上.)

Before

```python

from selenium import webdriver
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(
    executable_path=CHROMEDRIVER_PATH, 
    options=options
)
```

After

```python

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
options = webdriver.ChromeOptions()
service = ChromeService(executable_path=CHROMEDRIVER_PATH)
driver = webdriver.Chrome(service=service, options=options)
```

## 总结

我们已经过了升级到 Selenium 4 时要考虑的主要变化. 涵盖为升级准备测试代码时要涵盖的不同方面, 包括关于如何避免 使用Selenium新版本时 可能出现的潜在问题的建议.\
最后, 我们还介绍了一系列您可能会遇到的升级问题, 分享这些问题的潜在修复方案.

*本文最初发布于 <https://saucelabs.com/resources/articles/how-to-upgrade-to-selenium-4>*

----
url: https://www.selenium.dev/zh-cn/documentation/legacy/
----

# Legacy

在此部分，您可以找到与Selenium的旧组件有关的所有文档. 这样做纯粹是出于历史原因，而不是鼓励使用已废弃的组件.

***

##### [Selenium RC (Selenium 1)](/zh-cn/documentation/legacy/selenium_1/)

原始版本的Selenium

##### [Selenium 2](/zh-cn/documentation/legacy/selenium_2/)

Selenium 2 是以实现了WebDriver代码重写的Selenium 1.

##### [Selenium 3](/zh-cn/documentation/legacy/selenium_3/)

Selenium 3是摒除了Selenium RC代码的WebDriver实现. 其已被实现了W3C WebDriver规范的Selenium 4所替代.

##### [Legacy Selenium IDE](/zh-cn/documentation/legacy/selenium_ide/)

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/discouraged/test_dependency/
----

# 测试依赖

关于自动化测试的一个常见想法和误解是关于特定的测试顺序. 您的测试应该能够以**任何**顺序运行，而不是依赖于完成其他测试才能成功.

----
url: https://www.selenium.dev/zh-cn/documentation/overview/details/
----

# 深度介绍

最后修改 September 10, 2024: [Transparent png favicons (#1937)\[deploy site\] (03705be0833)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/03705be0833a1820cbaf73ab1119adf400549ac8)

----
url: https://www.selenium.dev/ja/documentation/webdriver/troubleshooting/errors/
----

# Understanding Common Errors

***

##### [Unable to Locate Driver Error](/ja/documentation/webdriver/troubleshooting/errors/driver_location/)

Troubleshooting missing path to driver executable.

最終更新 May 12, 2026: [docs: add Selenium Wait Generator to NoSuchElementException solutions (#2627) (a25fe46dcbf)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/a25fe46dcbfe2b07ccb95ec80923b9d94eadd12b)

----
url: https://www.selenium.dev/_print/documentation/webdriver/drivers/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/webdriver/drivers/).

# Driver Sessions

* 1: [Browser Options](#pg-839805e2dec21aeac2a04c521100ccd7)
* 2: [HTTP Client Configuration](#pg-caf19cbae376c115a241fb50a00ac32d)
* 3: [Driver Service Class](#pg-2470d9267dc6423408f8ea1a6aee0f65)
* 4: [Remote WebDriver](#pg-4a80931b53e2f3757757cbfb76831863)

```java
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L23)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L9)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            driver = new ChromeDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BaseTest.cs#L48)

##### /examples/dotnet/SeleniumDocs/BaseTest.cs

```cs
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs
{
    public class BaseTest
    {
        protected IWebDriver driver;
        protected Uri GridUrl;
        private Process _webserverProcess;
        private const string ServerJarName = "selenium-server-4.44.0.jar";
        private static readonly string BaseDirectory = AppContext.BaseDirectory;
        private const string RelativePathToGrid = "../../../../../";
        private readonly string _examplesDirectory = Path.GetFullPath(Path.Combine(BaseDirectory, RelativePathToGrid));

        [TestCleanup]
        public void Cleanup()
        {
            driver?.Quit();

            if (_webserverProcess != null)
            {
                StopServer();
            }
        }

        protected void StartDriver(string browserVersion = null)
        {
            ChromeOptions options = new ChromeOptions();
            if (browserVersion != null)
            {
                options.BrowserVersion = browserVersion;
                string userDataDir = System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetRandomFileName());
                System.IO.Directory.CreateDirectory(userDataDir);
                options.AddArgument($"--user-data-dir={userDataDir}");
                options.AddArgument("--no-sandbox");
                options.AddArgument("--disable-dev-shm-usage");
            }
            driver = new ChromeDriver(options);
        }

        protected async Task StartServer()
        {
            if (_webserverProcess == null || _webserverProcess.HasExited)
            {
                _webserverProcess = new Process();
                _webserverProcess.StartInfo.FileName =
                    RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "java.exe" : "java";
                string port = GetFreeTcpPort().ToString();
                GridUrl = new Uri("http://localhost:" + port + "/wd/hub");
                _webserverProcess.StartInfo.Arguments = " -jar " + ServerJarName +
                                                        " standalone --port " + port +
                                                        " --selenium-manager true --enable-managed-downloads true";
                _webserverProcess.StartInfo.WorkingDirectory = _examplesDirectory;
                _webserverProcess.Start();
                await EnsureGridIsRunningAsync();
            }
        }

        private void StopServer()
        {
            if (_webserverProcess != null && !_webserverProcess.HasExited)
            {
                _webserverProcess.Kill();
                _webserverProcess.Dispose();
                _webserverProcess = null;
            }
        }

        private static int GetFreeTcpPort()
        {
            TcpListener l = new TcpListener(IPAddress.Loopback, 0);
            l.Start();
            int port = ((IPEndPoint)l.LocalEndpoint).Port;
            l.Stop();
            return port;
        }

        private async Task EnsureGridIsRunningAsync()
        {
            DateTime timeout = DateTime.Now.Add(TimeSpan.FromSeconds(240));
            bool isRunning = false;
            HttpClient client = new HttpClient();

            while (!isRunning && DateTime.Now < timeout)
            {
                try
                {
                    HttpResponseMessage response = await client.GetAsync(GridUrl + "/status");
                    if (response.IsSuccessStatusCode)
                    {
                        isRunning = true;
                    }
                    else
                    {
                        await Task.Delay(1000);
                    }
                }
                catch (HttpRequestException)
                {
                    await Task.Delay(1000);
                }
            }

            if (!isRunning)
            {
                throw new TimeoutException("Could not confirm the remote selenium server is running within 30 seconds");
            }
        }
    }
}
```

```rb
      driver = Selenium::WebDriver.for :chrome, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L14)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options)
      .setChromeService(service)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/drivers/service.spec.js#L46-L50)

##### /examples/javascript/test/drivers/service.spec.js

```js
const fs = require('fs');
const os = require('os');
const path = require('path');
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const {getBinaryPaths} = require("selenium-webdriver/common/driverFinder");

describe('Service Test', function () {
  let driver;
  let userDataDir;
  let service;
  let options;

  afterEach(async function () {
    if (driver) {
      await driver.quit();
      driver = null;
    }
    if (userDataDir) {
      fs.rmSync(userDataDir, { recursive: true, force: true });
      userDataDir = null;
    }
  });

  it('Default service', async function () {
    service = new Chrome.ServiceBuilder();
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });

  it('Set Driver Location', async function () {
    options = new Chrome.Options();
    options.setBrowserVersion("stable");
    let paths = getBinaryPaths(options);
    let driverPath = paths.driverPath;
    let browserPath = paths.browserPath;
    options.setChromeBinaryPath(browserPath);
    userDataDir = fs.mkdtempSync(path.join(os.tmpdir(), 'chrome-profile-'));
    options.addArguments(`--user-data-dir=${userDataDir}`);
    options.addArguments('--no-sandbox');
    options.addArguments('--disable-dev-shm-usage');
    service = new Chrome.ServiceBuilder(driverPath);
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });

  it('Set port', async function () {
    service = new Chrome.ServiceBuilder().setPort(1234);
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
        driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L11)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L28)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L16)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L28)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L35)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

# 1 - Browser Options

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L73-74)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L79-80)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L11)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L80-82)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L86-88)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options.browser_version = 'latest'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L40)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## pageLoadStrategy

Three types of page load strategies are available.

The page load strategy queries the [document.readyState](//developer.mozilla.org/en-US/docs/Web/API/Document/readyState) as described in the table below:

| Strategy | Ready State | Notes                                                                     |
| -------- | ----------- | ------------------------------------------------------------------------- |
| normal   | complete    | Used by default, waits for all resources to download                      |
| eager    | interactive | DOM access is ready, but other resources like images may still be loading |
| none     | Any         | Does not block WebDriver at all                                           |

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L21-L23)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L7-9)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L13-14)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L11-L12)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L28-L34)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L34-L36)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L15-L17)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L29-30)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L20-L21)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L8-L14)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L47-L49)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L23-L25)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
        public void SetPageLoadStrategyNone()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L41-42)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L29-L30)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L18-L24)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L88-L90)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L94-96)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L38-L39)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L60-L61)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L101-103)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L51-L52)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L38-L41)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L96-L98)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L30-32)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L114-L115)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L111-L113)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L37-39)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L105-L106)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L126-L128)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L44-46)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L96-L97)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L141-L142)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L51-53)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L60-L61)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L151-L152)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L58-60)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L69-L70)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L163-L164)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L65-67)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L78-L79)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class ProxyTest {
  public static void main(String[] args) {
    Proxy proxy = new Proxy();
    proxy.setHttpProxy("<HOST:PORT>");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("proxy", proxy);
    WebDriver driver = new ChromeDriver(options);
    driver.get("https://www.google.com/");
    driver.manage().window().maximize();
    driver.quit();
  }
}
```

```py
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L72-74)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

public class ProxyTest{
public static void Main() {
ChromeOptions options = new ChromeOptions();
Proxy proxy = new Proxy();
proxy.Kind = ProxyKind.Manual;
proxy.IsAutoDetect = false;
proxy.SslProxy = "<HOST:PORT>";
options.Proxy = proxy;
options.AddArgument("ignore-certificate-errors");
IWebDriver driver = new ChromeDriver(options);
driver.Navigate().GoToUrl("https://www.selenium.dev/");
}
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L87-L88)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```javascript
let webdriver = require('selenium-webdriver');
let chrome = require('selenium-webdriver/chrome');
let proxy = require('selenium-webdriver/proxy');
let opts = new chrome.Options();

(async function example() {
opts.setProxy(proxy.manual({http: '<HOST:PORT>'}));
let driver = new webdriver.Builder()
.forBrowser('chrome')
.setChromeOptions(opts)
.build();
try {
await driver.get("https://selenium.dev");
}
finally {
await driver.quit();
}
}());
```

```kotlin
import org.openqa.selenium.Proxy
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

class proxyTest {
fun main() {

        val proxy = Proxy()
        proxy.setHttpProxy("<HOST:PORT>")
        val options = ChromeOptions()
        options.setCapability("proxy", proxy)
        val driver: WebDriver = ChromeDriver(options)
        driver["https://www.google.com/"]
        driver.manage().window().maximize()
        driver.quit()
    }
}
```

# 2 - HTTP Client Configuration

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import org.openqa.selenium.remote.http.ClientConfig;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import java.io.FileInputStream;
import java.net.URL;
import java.nio.file.Path;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.time.Duration;

import org.openqa.selenium.UsernameAndPassword;

import static java.net.http.HttpClient.Version.HTTP_1_1;

public class HttpClientTest extends BaseTest {
    URL gridUrl;

    @BeforeEach
    public void startGrid() {
        gridUrl = startStandaloneGridAdvanced();
    }

    @Test
    public void remoteWebDriverWithClientConfig() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createSSLContextWithCA(Path.of("src/test/resources/tls.crt").toAbsolutePath().toString()))
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
    }

    @Test
    public void remoteWebDriverIgnoreSSL() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createIgnoreSSLContext())
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
    }

    @Test
    public void remoteWebDriverWithEmbedAuthUrl() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createSSLContextWithCA(Path.of("src/test/resources/tls.crt").toAbsolutePath().toString()))
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(embedAuthToUrl(gridUrl, "admin", "myStrongPassword"))
                .config(clientConfig)
                .build();
    }

    private URL embedAuthToUrl(URL url, String username, String password) throws Exception {
        String userInfo = username + ":" + password;
        String urlWithAuth = url.getProtocol() + "://" + userInfo + "@" + url.getHost() + ":" + url.getPort() + url.getPath();
        return new URL(urlWithAuth);
    }

    public static SSLContext createSSLContextWithCA(String caCertPath) throws Exception {
        FileInputStream fis = new FileInputStream(caCertPath);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate caCert = (X509Certificate) cf.generateCertificate(fis);
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, null);
        keyStore.setCertificateEntry("caCert", caCert);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(keyStore);
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);
        return sslContext;
    }

    public static SSLContext createIgnoreSSLContext() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    }
                }
        };
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
        return sslContext;
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/HttpClientTest.java)

```py
import os
import pytest
import sys
from urllib3.util import Retry, Timeout
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType
from selenium.webdriver.remote.client_config import ClientConfig


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_with_client_config(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    retries = Retry(connect=2, read=2, redirect=2)
    timeout = Timeout(connect=300, read=3600)
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 init_args_for_pool_manager={
                                     "init_args_for_pool_manager": {"retries": retries, "timeout": timeout}},
                                 ca_certs=_get_resource_path("tls.crt"),
                                 username="admin", password="myStrongPassword")
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_ignore_certs(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 timeout=3600,
                                 ignore_certificates=True,
                                 username="admin", password="myStrongPassword")
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


def _get_resource_path(file_name: str):
    if os.path.abspath("").endswith("tests"):
        path = os.path.abspath(f"resources/{file_name}")
    else:
        path = os.path.abspath(f"tests/resources/{file_name}")
    return path

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_http_client.py)

[Add Example](/documentation/about/contributing/#creating-examples)

```rb

  it 'sets client configuration' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/http_client_spec.rb#L7-L8)

##### /examples/ruby/spec/drivers/http\_client\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'HTTP Client' do
  let(:url) { 'https://www.selenium.dev/selenium/web/' }

  it 'sets client configuration' do
    client = Selenium::WebDriver::Remote::Http::Default.new(open_timeout: 30, read_timeout: 30)
    expect(client.open_timeout).to eq 30
  end

  it 'uses the custom http client' do
    client = Selenium::WebDriver::Remote::Http::Default.new
    driver = Selenium::WebDriver.for :chrome, http_client: client
    driver.get(url)
    driver.quit
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

# 3 - Driver Service Class

```java
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L15-L16)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

**Note**: Java Service classes only allow values to be set during construction with a Builder pattern.

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L5-L6)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

**Note**: Python Service classes only allow values to be set as arguments to the constructor.

```cs
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L14-L15)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

**Note**: .NET Service classes allow values to be set as properties.

```rb
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L14-L15)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

```java
    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L25-L26)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(executable_path=chromedriver_bin)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L15)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```cs
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L23)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
    service.executable_path = driver_path
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L26)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

```java
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L33)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(port=1234)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L23)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            service.Port = 1234;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L32)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
    service.port = 1234
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L33)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```


# 4 - Remote WebDriver

```java
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L38-L39)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L13-L14)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L28-L29)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L20-L21)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L49-L52)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

Python adds a local file detector to remote webdriver instances by default, but you can also create your own class.

```py
    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L29-L32)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

.NET adds a local file detector to remote webdriver instances by default, but you can also create your own class.

```cs
            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L47-L50)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

Ruby adds a local file detector to remote webdriver instances by default, but you can also create your own lambda:

```rb
    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L33-L36)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## Downloads

Chrome, Edge and Firefox each allow you to set the location of the download directory. When you do this on a remote computer, though, the location is on the remote computer’s local file system. Selenium allows you to enable downloads to get these files onto the client computer.

### Enable Downloads in the Grid

Regardless of the client, when starting the grid in node or standalone mode, you must add the flag:

```
--enable-managed-downloads true
```

```java
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L60-L62)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L42-L44)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L59-L64)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L43-L44)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    List<String> files = ((HasDownloads) driver).getDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L73)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    files = driver.get_downloadable_files()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L52)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L72)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    files = driver.downloadable_files
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L52)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L83)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    driver.download_file(downloadable_file, target_directory)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L58)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L79)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    driver.download_file(downloadable_file, target_directory)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L57)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((HasDownloads) driver).deleteDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L88)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    driver.delete_downloadable_files()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L64)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ((RemoteWebDriver)driver).DeleteDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L84)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    driver.delete_downloadable_files
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L62)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    driver = new Augmenter().augment(driver);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L98)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

Of interest, using the `RemoteWebDriverBuilder` automatically augments the driver, so it is a great way to get all the functionality by default:

```java
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L106-L111)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

.NET uses a custom command executor for executing commands that are valid for the given browser in the remote driver.

```cs
            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L96-L100)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```xml
  <dependency>
      <groupId>io.opentelemetry</groupId>
      <artifactId>opentelemetry-exporter-jaeger</artifactId>
      <version>1.0.0</version>
    </dependency>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-netty</artifactId>
      <version>1.35.0</version>
    </dependency>
```

### Add/pass the required system properties while running the client

*

```java
System.setProperty("otel.traces.exporter", "jaeger");
System.setProperty("otel.exporter.jaeger.endpoint", "http://localhost:14250");
System.setProperty("otel.resource.attributes", "service.name=selenium-java-client");

ImmutableCapabilities capabilities = new ImmutableCapabilities("browserName", "chrome");

WebDriver driver = new RemoteWebDriver(new URL("http://www.example.com"), capabilities);

driver.get("http://www.google.com");

driver.quit();

  
```

Please refer to [Tracing Setup](https://github.com/SeleniumHQ/selenium/blob/selenium-4.0.0-beta-1/java/server/src/org/openqa/selenium/grid/commands/tracing.txt) for more information on external dependencies versions required for the desired Selenium version.

More information can be found at:

* OpenTelemetry: <https://opentelemetry.io>
* Configuring OpenTelemetry: <https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure>
* Jaeger: <https://www.jaegertracing.io>
* [Selenium Grid Observability](https://www.selenium.dev/documentation/grid/advanced_features/observability/)

----
url: https://www.selenium.dev/ja/documentation/test_practices/discouraged/http_response_codes/
----

# HTTPレスポンスコード

Selenium RCの一部のブラウザー構成では、Seleniumはブラウザーと自動化されているサイトの間のプロキシとして機能しました。 これは、Seleniumを通過したすべてのブラウザートラフィックをキャプチャまたは操作できることを意味していました。 `captureNetworkTraffic()` メソッドは、HTTPレスポンスコードを含むブラウザーと自動化されているサイト間のすべてのネットワークトラフィックをキャプチャすることを目的としています。

Selenium WebDriverは、ブラウザーの自動化に対するまったく異なるアプローチであり、ユーザーのように振る舞うことを好むため、WebDriverを使用してテストを記述する方法で表現します。 自動化された機能テストでは、ステータスコードの確認はテストの失敗の特に重要な詳細ではありません。 それに先行する手順がより重要です。

ブラウザーは常にHTTPステータスコードを表します。たとえば、404または500エラーページを想像してください。 これらのエラーページの1つに遭遇したときに"早く失敗"する簡単な方法は、ページが読み込まれるたびにページタイトルまたは信頼できるポイント（たとえば `<h1>` タグ）のコンテンツをチェックすることです。 ページオブジェクトモデルを使用している場合、このチェックをクラスコンストラクターまたはページの読み込みが予想される同様のポイントに含めることができます。 場合によっては、HTTPコードがブラウザーのエラーページに表示されることもあります。 WebDriverを使用してこれを読み取り、デバッグ出力を改善できます。

Webページ自体を確認することは、WebDriverの理想的なプラクティスに沿っており、WebDriverのユーザーのWebサイトの見え方を表現し、主張します。

HTTPステータスコードをキャプチャするための高度なソリューションは、プロキシを使用してSelenium RCの動作を複製することです。 WebDriver APIは、ブラウザーのプロキシを設定する機能を提供します。 Webサーバーとの間で送受信されるリクエストのコンテンツをプログラムで操作できるプロキシがいくつかあります。 プロキシを使用すると、リダイレクトレスポンスコードへの応答方法を決めることができます。 さらに、すべてのブラウザーがWebDriverでレスポンスコードを利用できるようにするわけではないため、プロキシを使用することを選択すると、すべてのブラウザーで機能するソリューションが得られます。

----
url: https://www.selenium.dev/zh-cn/documentation/about/copyright/
----

# 版权和归属

| 软件                                  | 版本       | 许可                                                          |
| ----------------------------------- | -------- | ----------------------------------------------------------- |
| [Hugo](/zh-cn/)                     | v0.110.0 | [Apache 2.0](//gohugo.io/about/license/)                    |
| [Docsy](//github.com/google/docsy/) | —        | [Apache 2.0](//github.com/google/docsy/blob/master/LICENSE) |

## 许可

源自Selenium项目的所有代码和文档均基于Apache2.0的许可, 由 [Software Freedom Conservancy](/zh-cn/) 作为版权所有者.

为方便起见, 此处包含许可证, 您也可以在此查看 [Apache 基金会站点](//apache.org/licenses/LICENSE-2.0.html):

```markdown
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
```

最后修改 October 3, 2023: [Update hugo as required (#1491) (aa734862bf2)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/aa734862bf2ec42a6d06f000ff490bd5cb852003)

----
url: https://www.selenium.dev/zh-cn/documentation/about/contributing/
----

# 为 Selenium 文档做贡献

有关改进Selenium文档和代码示例的信息

Selenium是一个大型软件项目, 其网站和文档是了解事情如何工作以及学习有效利用其潜力的关键.

该项目包含Selenium的网站和文档. 这是一项持续的工作(不针对任何特定版本), 用于提供有效使用Selenium、 如何参与以及如何为Selenium做出贡献的更新信息.

对网站和文档的贡献遵循以下部分中有关贡献的描述.

***

```
    {{< tab header="Ruby" >}}
    {{< gh-codeblock path="/examples/ruby/spec/browsers/chrome_spec.rb#L8-L9" >}}
    {{< /tab >}}
```

```shell
% git clone git@github.com:seleniumhq/seleniumhq.github.io.git
% cd seleniumhq.github.io
```

#### 依赖: Hugo

我们使用 [Hugo](https://gohugo.io/) 和 [Docsy theme](https://www.docsy.dev/) 用于构建和渲染本网站. 你需要Hugo“extended”扩展的Sass/SCSS版本用于这个网站. 我们推荐使用Hugo 0.148.2 .

请参考来自Docsy的说明 [安装Hugo](https://www.docsy.dev/docs/getting-started/#install-hugo) .

### 步骤 2: 分支

创建一个功能分支并开始工作:

```shell
% git checkout -b my-feature-branch
```

我们实践基于HEAD的开发模式, 这意味着所有更改都直接应用在trunk之上.

### 步骤 3: 做出改变

本仓库包含站点和文档. 在开始进行更改之前, 请初始化子模块并安装所需的依赖项 (请参阅下面的命令). 要对网站进行更改, 请使用 `website_and_docs` 目录. 要查看更改的实时预览, 请在站点的根目录上运行 `hugo server` .

```shell
% git submodule update --init --recursive
% cd website_and_docs
% hugo server
```

请参阅 [样式指南](https://www.selenium.dev/zh-cn/documentation/about/style/) , 以了解更多关于我们约定的信息

### 步骤 4: 提交

首先确保git知道您的姓名和电子邮件地址:

```shell
% git config --global user.name 'Santa Claus'
% git config --global user.email 'santa@example.com'
```

**编写良好的提交信息很重要.** 提交信息应描述更改的内容, 原因以及已解决的参考问题(如果有). 撰写时应遵循以下规则:

1. 第一行应少于或等于50个字符, 并包含对该更改的简短说明.
2. 保持第二行空白.
3. 在所有72列处换行.
4. 包括 `Fixes #N`, 其中 *N* 是提交修复的问题编号(如果有).

一个好的提交信息可能看起来像这样:

```text
explain commit normatively in one line

Body of commit message is a few lines of text, explaining things
in more detail, possibly giving some background about the issue
being fixed, etc.

The body of the commit message can be several paragraphs, and
please do proper word-wrap and keep columns shorter than about
72 characters or so. That way `git log` will show things
nicely even when it is indented.

Fixes #141
```

第一行必须有意义, 因为这是人们在运行 `git shortlog` 或 `git log --oneline` 时看到的内容.

### 步骤 5: Rebase

使用 `git rebase` (并非 `git merge`) 同步实时的工作.

```shell
% git fetch origin
% git rebase origin/trunk
```

### 步骤 6: 测试

永远记住要[运行本地服务](https://gohugo.io/getting-started/usage/#livereload), 这样做可以确保您的更改没有破坏任何事情.

### 步骤 7: Push

```shell
% git push origin my-feature-branch
```

访问 <https://github.com/yourusername/seleniumhq.github.io.git> 并点击 *Pull Request* 以及填写表格. **请明确您已经签署了CLA** (详见步骤 7).

Pull requests通常会在几天内进行审核. 如果有评论要解决, 请在新提交(最好是[修正](http://git-scm.com/docs/git-commit))中应用您的更改, 然后推push到同一分支.

### 步骤 8: 集成

代码审查完成后, 提交者将获取您的PR并将其集成到项目的trunk分支中. 因为我们希望在trunk分支上保持线性历史记录, 所以我们通常会squash并rebase您的分支历史记录.

## 沟通

有关如何与项目贡献者和整个社区进行沟通的所有详细信息, 请访问以下网址 <https://selenium.dev/support>

最后修改 November 4, 2025: [added information about web examples for english document (#2492) (4dc5f22359d)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/4dc5f22359dfceb83b43afb473ca2ef7882abd19)

----
url: https://www.selenium.dev/ja/documentation/webdriver/support_features/expected_conditions/
----

# Waiting with Expected Conditions

```py
    wait = WebDriverWait(driver, timeout=2)
    wait.until(EC.visibility_of_element_located((By.ID, "revealed")))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_expected_conditions.py#L14-L15)

##### /examples/python/tests/support/test\_expected\_conditions.py

```py
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

# Expected Conditions API Documentation:
# https://www.selenium.dev/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html


def test_expected_condition(driver):
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html")
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(EC.visibility_of_element_located((By.ID, "revealed")))

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"
```

.NET stopped supporting Expected Conditions in Selenium 4 to minimize maintenance hassle and redundancy.

Ruby makes frequent use of blocks, procs and lambdas and does not need Expected Conditions classes

----
url: https://www.selenium.dev/ja/_print/documentation/grid/advanced_features/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/grid/advanced_features/).

# 高度な機能

高度な機能のすべての詳細を取得し、それがどのように機能するか、および独自の設定方法を理解するには、次のセクションを参照してください。

* 1: [可観測性](#pg-cff3310fa01f534cfe804c3e76ae9056)
* 2: [GraphQLクエリのサポート](#pg-b11540ed82255545d0e8201c6e111a70)
* 3: [Grid エンドポイント](#pg-d62408233c3d62bcee1fef32842d1ecd)
* 4: [Customizing a Node](#pg-5b5dba3035d5fdea37ea443e04bc3675)
* 5: [External datastore](#pg-e65991b592e30916d941bdbfabb53abe)

# 1 - 可観測性

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar standalone --log-level FINE
```

2. Jaeger UI - OpenTelemetry は、コード内のトレースを計測するための API と SDK を提供します。一方、Jaeger はトレースのバックエンドで、トレースのテレメトリデータを収集し、データのクエリ、フィルタリング、ビジュアライズの機能を提供します。

Jaeger UI を用いたトレースの可視化の詳細な手順を確認するには、次のコマンドを実行してください:

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar info tracing
```

[非常に参考になる例と、Jaeger にトレースを送信するスクリプトです](https://github.com/manoj9788/tracing-selenium-grid)

## イベントログの活用

トレースを可視化しない場合でも、イベントロギングではトレースを有効にする必要があります。 **デフォルトでは、トレースは有効です。コンソールでログを見るために、追加のパラメータを渡す必要はありません。** スパン内のすべてのイベントは FINE レベルでログに記録されます。エラーイベントは、WARN レベルでログに記録されます。

全てのイベントは次のフィールドを持ちます:

| フィールド   | フィールド名          | 概要                                                                                                |
| ------- | --------------- | ------------------------------------------------------------------------------------------------- |
| イベント時刻  | eventId         | イベントのタイムスタンプ(エポックナノ秒)。                                                                            |
| トレース ID | tracedId        | 各トレースはトレース ID で一意に識別されます。                                                                         |
| スパン ID  | spanId          | トレース内の各スパンは、スパン ID により一意に識別されます。                                                                  |
| スパン種別   | spanKind        | スパン種別は、スパンの種類を示すスパンのプロパティです。スパンの処理の性質を識別するのに役立ちます。                                                |
| イベント名   | eventName       | ログメッセージにマッピングされます。                                                                                |
| イベント属性  | eventAttributes | イベントログの核となるもので、実行された操作に基づいて JSON フォーマットのキーと値のペアが用意されています。また、ロガークラスを表示するために、ハンドラークラスアトリビュートも含まれます。 |

サンプルログ

```
FINE [LoggingOptions$1.lambda$export$1] - {
  "traceId": "fc8aef1d44b3cc8bc09eb8e581c4a8eb",
  "spanId": "b7d3b9865d3ddd45",
  "spanKind": "INTERNAL",
  "eventTime": 1597819675128886121,
  "eventName": "Session request execution complete",
  "attributes": {
    "http.status_code": 200,
    "http.handler_class": "org.openqa.selenium.grid.router.HandleSession",
    "http.url": "\u002fsession\u002fdd35257f104bb43fdfb06242953f4c85",
    "http.method": "DELETE",
    "session.id": "dd35257f104bb43fdfb06242953f4c85"
  }
}
```

上記のフィールドに加えて、[OpenTelemetry の仕様](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/exceptions.md)に基づきエラーログは以下のフィールドで構成されます:

| フィールド    | フィールド名               | 概要                                           |
| -------- | -------------------- | -------------------------------------------- |
| 例外タイプ    | exception.type       | 例外クラス名。                                      |
| 例外メッセージ  | exception.message    | 例外の原因。                                       |
| スタックトレース | exception.stacktrace | 例外が発生した時点のコールスタックを表示します。 例外の発生源を把握するのに役立ちます。 |

サンプルエラーログ

```
WARN [LoggingOptions$1.lambda$export$1] - {
  "traceId": "7efa5ea57e02f89cdf8de586fe09f564",
  "spanId": "914df6bc9a1f6e2b",
  "spanKind": "INTERNAL",
  "eventTime": 1597820253450580272,
  "eventName": "exception",
  "attributes": {
    "exception.type": "org.openqa.selenium.ScriptTimeoutException",
    "exception.message": "Unable to execute request: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist ..." (full message will be printed),
    "exception.stacktrace": "org.openqa.selenium.ScriptTimeoutException: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist\nBuild info: version: '4.0.0-alpha-7', revision: 'Unknown'\nSystem info: host: 'XYZ-MacBook-Pro.local', ip: 'fe80:0:0:0:10d5:b63a:bdc6:1aff%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.7'\nDriver info: driver.version: unknown ...." (full stack will be printed),
    "http.handler_class": "org.openqa.selenium.grid.distributor.remote.RemoteDistributor",
    "http.url": "\u002fsession",
    "http.method": "POST"
  }
}
```

# 2 - GraphQLクエリのサポート

```shell
{
    session(id: "<session-id>") : {
        id,
        capabilities,
        startTime,
        uri,
        nodeId,
        nodeUri,
        sessionDurationMillis
        slot : {
            id,
            stereotype,
            lastStarted
        }
    }
    grid: {
        uri,
        totalSlots,
        nodeCount,
        maxSession,
        sessionCount,
        version,
        sessionQueueSize
    }
    sessionsInfo: {
        sessionQueueRequests,
        sessions: [
            {
                id,
                capabilities,
                startTime,
                uri,
                nodeId,
                nodeUri,
                sessionDurationMillis
                slot : {
                    id,
                    stereotype,
                    lastStarted
                }
            }
        ]
    }
    nodesInfo: {
        nodes : [
            {
                id,
                uri,
                status,
                maxSession,
                slotCount,
                sessions: [
                    {
                        id,
                        capabilities,
                        startTime,
                        uri,
                        nodeId,
                        nodeUri,
                        sessionDurationMillis
                        slot : {
                            id,
                            stereotype,
                            lastStarted
                        }
                    }
                ],
                sessionCount,
                stereotypes,
                version,
                osInfo: {
                    arch,
                    name,
                    version
                }
            }
        ]
    }
}
```

## GraphQLで照会する

GraphQLをクエリする最良の方法は、 `curl` リクエストを使用することです。 GraphQLを使用すると、必要なデータのみをフェッチできます。それ以上でもそれ以下でもありません。

GraphQLクエリの例のいくつかを以下に示します。 必要に応じて独自のクエリを作成できます。

### グリッド内の `maxSession`と` sessionCount`の数を照会する

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ grid { maxSession, sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

通常、ローカルマシンでは、 `<LINK_TO_GRAPHQL_ENDPOINT>` は `http://localhost:4444/graphql` になります。

### セッション、ノード、グリッドのすべての詳細を照会する

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { uri, maxSession, sessionCount }, nodesInfo { nodes { id, uri, status, sessions { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } }, slotCount, sessionCount }} }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### グリッドで現在のセッション数を取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### グリッドで最大セッション数を取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { maxSession } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### グリッド内のすべてのノードのすべてのセッションの詳細を取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, capabilities, startTime, uri, nodeId, nodeId, sessionDurationMillis } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### グリッド内の各ノードのすべてのセッションのスロット情報を取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, slot { id, stereotype, lastStarted } } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 特定のセッションのセッション情報を取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ session (id: \"<session-id>\") { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } } } "}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### グリッド内の各ノードのcapabilityを照会する

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { stereotypes } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### グリッド内の各ノードのステータスを照会する

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { status } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 各ノードとグリッドのURIを照会する

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { uri } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 新しいセッションキューで現在のリクエストを取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessionQueueRequests } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 新しいセッションキューのサイズを取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionQueueSize } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

# 3 - Grid エンドポイント

## Grid

### Grid ステータス

Grid ステータスは Grid の現在の状態を提供します。 登録されている全てのノードの詳細で構成されます。 各ノードのステータスには、ノードの稼働状況、セッション、およびスロットに関する情報が含まれます。

```shell
curl --request GET 'http://localhost:4444/status'
```

### セッションの削除

セッションを削除すると、WebDriver セッションが終了し、ドライバがアクティブなセッションマップから削除されます。 削除されたセッション ID を使用するリクエストや、ドライバのインスタンスを再利用しようとすると、エラーとなります。

```shell
curl --request DELETE 'http://localhost:4444/session/<session-id>'
```

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret> '
```

完全分散モードでは、ディストリビューター URL は ディストリビューターのアドレスになります。

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

Grid の設定時に登録用の secret を設定していない場合は次のようにします:

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET;'
```

### ノードのドレイン

ノードドレインコマンドはノードをグレースフルシャットダウンするために利用します。 ドレインは実行中のセッションがすべて完了した後にノードを停止します。 新規のセッションは受け付けません。

スタンドアロンモードでは、ディストリビューターの URL はスタンドアロンサーバーのアドレスとなります。

ハブ&ノードモードでは、ディストリビューターの URL は ハブのアドレスになります。

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret> '
```

完全分散モードでは、ディストリビューター URL は ディストリビューターのアドレスになります。

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

Grid の設定時に登録用の secret を設定していない場合は次のようにします:

```shell
curl --request POST 'http://<Router-URL>/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET;'
```

## ノード

この節でのエンドポイントは、ハブ&ノードモードとノードが独立して動作する完全分散型 Grid モードに適用されます。 ノードが 1 つの場合、デフォルトのノード URL は http\://localhost:5555 です。 複数のノードがある場合は、[Grid ステータス](/ja/documentation/grid/advanced_features/endpoints/#grid-%e3%82%b9%e3%83%86%e3%83%bc%e3%82%bf%e3%82%b9) を使ってすべてのノードの詳細とノードアドレスを取得してください。

### ステータス

ノードステータスは基本的にノードのヘルスチェックのためのものです。 ディストリビューターは定期的にノードの状態を ping で取得し、それに応じて Grid モデルを更新します。 ステータスには稼働状況、セッション、およびスロットに関する情報が含まれます。

```shell
curl --request GET 'http://localhost:5555/status'
```

### ドレイン

ディストリビューターは [ドレイン](/ja/documentation/grid/advanced_features/endpoints/#%e3%83%8e%e3%83%bc%e3%83%89%e3%81%ae%e3%83%89%e3%83%ac%e3%82%a4%e3%83%b3)コマンドを適切なノードに渡します。 ノードを直接ドレインするには以下の curl コマンドを使います。 どちらのエンドポイントも有効であり、同じ結果になります。 ドレインは、ノードを停止する前に進行中のセッションを終了させます。

```shell
curl --request POST 'http://localhost:5555/se/grid/node/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

Grid の設定時に登録用の secret を設定していない場合は次のようにします:

```shell
curl --request POST 'http://<node-URL>/se/grid/node/drain' --header 'X-REGISTRATION-SECRET;'
```

### セッションオーナーのチェック

あるセッションがノードに属しているかどうかをチェックするには、以下の curl コマンドを使います。

```shell
curl --request GET 'http://localhost:5555/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

Grid の設定時に登録用の secret を設定していない場合は次のようにします:

```shell
curl --request GET 'http://<node-URL>/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

もしセッションがノードに属していたら true を返し、そうでなければ false が返ります。

### セッションの削除

セッションを削除すると、WebDriver セッションが終了し、ドライバがアクティブなセッションマップから削除されます。 削除されたセッション ID を使用するリクエストや、ドライバのインスタンスを再利用しようとすると、エラーとなります。

```shell
curl --request DELETE 'http://localhost:5555/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

Grid の設定時に登録用の secret を設定していない場合は次のようにします:

```shell
curl --request DELETE 'http://<node-URL>/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

## 新規セッションキュー

### 新規セッションキューのクリア

新規セッションキューには、新規セッションリクエストが格納されます。 キューをクリアするには、以下に挙げる curl コマンドを使用します。 キューを消去すると、キューにあるすべてのリクエストを拒否します。 サーバーは各リクエストのそれぞれのクライアントにエラーレスポンスを返します。 クリアコマンドの結果は、削除されたリクエストの数です。

スタンドアロンモードでは、キューの URL はスタンドアロンサーバーのアドレスとなります。

ハブ&ノードモードでは、キューの URL は ハブのアドレスになります。

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

完全分散モードでは、キューの URL は 新規セッションキューのアドレスになります。

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

Grid の設定時に登録用の secret を設定していない場合は次のようにします:

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET;'
```

### 新規セッションリクエストの取得

新規セッションキューには、新規セッションリクエストが格納されます。 キューにある現在のリクエストを取得するには、以下に挙げる curl コマンドを使用します。 レスポンスはキュー内のリクエストの数とリクエストのペイロードを返します。

スタンドアロンモードでは、キューの URL はスタンドアロンサーバーのアドレスとなります。

ハブ&ノードモードでは、キューの URL は ハブのアドレスになります。

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

完全分散モードでは、キューの URL は 新規セッションキューのアドレスになります。

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

# 4 - Customizing a Node

```bash
java -jar custom_node-server.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

```bash
java -jar selenium-server-4.6.0.jar \
--ext custom_node-1.0-SNAPSHOT.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

Below is a sample that just prints some messages on to the console whenever there’s an activity of interest (session created, session deleted, a webdriver command executed etc.,) on the Node.

Sample customized node

```java
package org.seleniumhq.samples;

import java.net.URI;
import java.util.UUID;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.NoSuchSessionException;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.grid.config.Config;
import org.openqa.selenium.grid.data.CreateSessionRequest;
import org.openqa.selenium.grid.data.CreateSessionResponse;
import org.openqa.selenium.grid.data.NodeId;
import org.openqa.selenium.grid.data.NodeStatus;
import org.openqa.selenium.grid.data.Session;
import org.openqa.selenium.grid.log.LoggingOptions;
import org.openqa.selenium.grid.node.HealthCheck;
import org.openqa.selenium.grid.node.Node;
import org.openqa.selenium.grid.node.local.LocalNodeFactory;
import org.openqa.selenium.grid.security.Secret;
import org.openqa.selenium.grid.security.SecretOptions;
import org.openqa.selenium.grid.server.BaseServerOptions;
import org.openqa.selenium.internal.Either;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
import org.openqa.selenium.remote.tracing.Tracer;

public class DecoratedLoggingNode extends Node {

  private Node node;

  protected DecoratedLoggingNode(Tracer tracer, NodeId nodeId, URI uri, Secret registrationSecret, Duration sessionTimeout) {
    super(tracer, nodeId, uri, registrationSecret, sessionTimeout);
  }

  public static Node create(Config config) {
    LoggingOptions loggingOptions = new LoggingOptions(config);
    BaseServerOptions serverOptions = new BaseServerOptions(config);
    URI uri = serverOptions.getExternalUri();
    SecretOptions secretOptions = new SecretOptions(config);
    NodeOptions nodeOptions = new NodeOptions(config);
    Duration sessionTimeout = nodeOptions.getSessionTimeout();

    // Refer to the foot notes for additional context on this line.
    Node node = LocalNodeFactory.create(config);

    DecoratedLoggingNode wrapper = new DecoratedLoggingNode(loggingOptions.getTracer(),
        node.getId(),
        uri,
        secretOptions.getRegistrationSecret(),
        sessionTimeout);
    wrapper.node = node;
    return wrapper;
  }

  @Override
  public Either<WebDriverException, CreateSessionResponse> newSession(
      CreateSessionRequest sessionRequest) {
    System.out.println("Before newSession()");
    try {
      return this.node.newSession(sessionRequest);
    } finally {
      System.out.println("After newSession()");
    }
  }

  @Override
  public HttpResponse executeWebDriverCommand(HttpRequest req) {
    try {
      System.out.println("Before executeWebDriverCommand(): " + req.getUri());
      return node.executeWebDriverCommand(req);
    } finally {
      System.out.println("After executeWebDriverCommand()");
    }
  }

  @Override
  public Session getSession(SessionId id) throws NoSuchSessionException {
    try {
      System.out.println("Before getSession()");
      return node.getSession(id);
    } finally {
      System.out.println("After getSession()");
    }
  }

  @Override
  public HttpResponse uploadFile(HttpRequest req, SessionId id) {
    try {
      System.out.println("Before uploadFile()");
      return node.uploadFile(req, id);
    } finally {
      System.out.println("After uploadFile()");
    }
  }

  @Override
  public void stop(SessionId id) throws NoSuchSessionException {
    try {
      System.out.println("Before stop()");
      node.stop(id);
    } finally {
      System.out.println("After stop()");
    }
  }

  @Override
  public boolean isSessionOwner(SessionId id) {
    try {
      System.out.println("Before isSessionOwner()");
      return node.isSessionOwner(id);
    } finally {
      System.out.println("After isSessionOwner()");
    }
  }

  @Override
  public boolean isSupporting(Capabilities capabilities) {
    try {
      System.out.println("Before isSupporting");
      return node.isSupporting(capabilities);
    } finally {
      System.out.println("After isSupporting()");
    }
  }

  @Override
  public NodeStatus getStatus() {
    try {
      System.out.println("Before getStatus()");
      return node.getStatus();
    } finally {
      System.out.println("After getStatus()");
    }
  }

  @Override
  public HealthCheck getHealthCheck() {
    try {
      System.out.println("Before getHealthCheck()");
      return node.getHealthCheck();
    } finally {
      System.out.println("After getHealthCheck()");
    }
  }

  @Override
  public void drain() {
    try {
      System.out.println("Before drain()");
      node.drain();
    } finally {
      System.out.println("After drain()");
    }

  }

  @Override
  public boolean isReady() {
    try {
      System.out.println("Before isReady()");
      return node.isReady();
    } finally {
      System.out.println("After isReady()");
    }
  }
}
```

***Foot Notes:***

In the above example, the line `Node node = LocalNodeFactory.create(config);` explicitly creates a `LocalNode`.

There are basically 2 types of *user facing implementations* of `org.openqa.selenium.grid.node.Node` available.

These classes are good starting points to learn how to build a custom Node and also to learn the internals of a Node.

* `org.openqa.selenium.grid.node.local.LocalNode` - Used to represent a long running Node and is the default implementation that gets wired in when you start a `node`.

  * It can be created by calling `LocalNodeFactory.create(config);`, where:

    * `LocalNodeFactory` belongs to `org.openqa.selenium.grid.node.local`
    * `Config` belongs to `org.openqa.selenium.grid.config`

* `org.openqa.selenium.grid.node.k8s.OneShotNode` - This is a special reference implementation wherein the Node gracefully shuts itself down after servicing one test session. This class is currently not available as part of any pre-built maven artifact.

  * You can refer to the source code [here](https://github.com/SeleniumHQ/selenium/blob/trunk/java/src/org/openqa/selenium/grid/node/k8s/OneShotNode.java) to understand its internals.

  * To build it locally refer [here](https://github.com/SeleniumHQ/selenium/blob/trunk/deploys/k8s/README.md).

  * It can be created by calling `OneShotNode.create(config)`, where:

    * `OneShotNode` belongs to `org.openqa.selenium.grid.node.k8s`
    * `Config` belongs to `org.openqa.selenium.grid.config`

# 5 - External datastore

```sql
CREATE TABLE IF NOT EXISTS sessions_map(
    session_ids varchar(256),
    session_caps text,
    session_uri varchar(256),
    session_stereotype text,
    session_start varchar(256)
 );
```

* In the same directory as the `init.sql`, create a file named `docker-compose.yml` with its contents as below:

```yaml
version: '3.8'
services:
  db:
    image: postgres:9.6-bullseye
    restart: always
    environment:
      - POSTGRES_USER=seluser
      - POSTGRES_PASSWORD=seluser
      - POSTGRES_DB=selenium_sessions
    ports:
      - "5432:5432"
    volumes:
    - ./init.sql:/docker-entrypoint-initdb.d/init.sql
```

We can now start our database container by running:

```bash
docker-compose up -d
```

*Our database name is `selenium_sessions` with its username and password set to `seluser`*

If you are working with an already running PostGreSQL DB instance, then you just need to create a database named `selenium_sessions` and the table `sessions_map` using the above mentioned SQL statement.

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
implementation = "org.openqa.selenium.grid.sessionmap.jdbc.JdbcBackedSessionMap"
jdbc-url = "jdbc:postgresql://localhost:5432/selenium_sessions"
jdbc-user = "seluser"
jdbc-password = "seluser"
```

*Note:* If you plan to use an existing PostGreSQL DB instance, then replace `localhost:5432` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed Grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Sessions Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

```yaml
version: '3.8'
services:
  redis:
    image: redis:bullseye
    restart: always
    ports:
      - "6379:6379"
```

We can now start our Redis container by running:

```bash
docker-compose up -d
```

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
scheme = "redis"
implementation = "org.openqa.selenium.grid.sessionmap.redis.RedisBackedSessionMap"
hostname = "localhost"
port = 6379
```

*Note:* If you plan to use an existing Redis Cache instance, then replace `localhost` and `6379` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Session Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

* At this point the current directory should contain the following files:

  * `docker-compose.yml`
  * `sessions.toml`
  * `distributed.sh`

* You can now spawn the Grid by running `distributed.sh` shell script and quickly run a test. You will notice that the Grid now stores session information into the Redis instance. You can perhaps make use of a Redis GUI such as [TablePlus](https://tableplus.com/) to see them (Make sure that you have setup a debug point in your test, because the values will get deleted as soon as the test runs to completion).

In the line which spawns a `SessionMap` on a machine:

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/bidi/w3c/input/
----

# Browsing Context

```java
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ActionsTest.java#L41-L44)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ActionsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Input;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.interactions.Actions;

class ActionsTest extends BaseTest {
    private Input input;

    private String windowHandle;

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        windowHandle = driver.getWindowHandle();
        input = new Input(driver);
    }

    @Test
    void canPerformInputActions() {
        driver.get("https://www.selenium.dev/selenium/web/formSelectionPage.html");

        List<WebElement> options = driver.findElements(By.tagName("option"));

        Actions actions = new Actions(driver);
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());

        WebElement showButton = driver.findElement(By.name("showselected"));
        showButton.click();

        WebElement resultElement = driver.findElement(By.id("result"));
        Assertions.assertTrue(resultElement.getText().contains("roquefort parmigiano cheddar"));
        }

    @Test
    void canPerformReleaseAction() {
        driver.get("https://www.selenium.dev/selenium/web/bidi/release_action.html");

        WebElement inputTextBox = driver.findElement(By.id("keys"));

        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);

        List<Map<String, Object>> events =
                (List<Map<String, Object>>)
                        ((JavascriptExecutor) driver).executeScript("return allEvents.events");
        Assertions.assertEquals("KeyB", events.get(0).get("code"));
        Assertions.assertEquals("KeyA", events.get(1).get("code"));
        }
    }
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/input.spec.js#L27-L29)

##### /examples/javascript/test/bidirectional/input.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, Key, Builder} = require("selenium-webdriver")
const Input = require('selenium-webdriver/bidi/input')

describe('Input module', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can perform input action', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/formSelectionPage.html')

    let options = await driver.findElements(By.tagName('option'))

    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)

    let showButton = await driver.findElement(By.name('showselected'))
    showButton.click()

    let resultElement = await driver.findElement(By.id('result'))
    await resultElement.getText().then(function (text) {
      assert(text.includes('oquefort parmigiano cheddar'), `text is: ${text}`)
    })
  })

  it('can execute release in browsing context', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/bidi/release_action.html')

    let inputTextBox = await driver.findElement(By.id('keys'))

    await driver.executeScript('arguments[0].focus()', inputTextBox)

    const actions = driver.actions().keyDown('a').keyDown('b').getSequences()

    await input.perform(browsingContextId, actions)

    await driver.executeScript('resetEvents()')

    await input.release(browsingContextId)

    const events = await driver.executeScript('return allEvents.events')

    assert.strictEqual(events[0].code, 'KeyB')
    assert.strictEqual(events[1].code, 'KeyA')
  })
})
```

```java
        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ActionsTest.java#L59-L65)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ActionsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Input;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.interactions.Actions;

class ActionsTest extends BaseTest {
    private Input input;

    private String windowHandle;

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        windowHandle = driver.getWindowHandle();
        input = new Input(driver);
    }

    @Test
    void canPerformInputActions() {
        driver.get("https://www.selenium.dev/selenium/web/formSelectionPage.html");

        List<WebElement> options = driver.findElements(By.tagName("option"));

        Actions actions = new Actions(driver);
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());

        WebElement showButton = driver.findElement(By.name("showselected"));
        showButton.click();

        WebElement resultElement = driver.findElement(By.id("result"));
        Assertions.assertTrue(resultElement.getText().contains("roquefort parmigiano cheddar"));
        }

    @Test
    void canPerformReleaseAction() {
        driver.get("https://www.selenium.dev/selenium/web/bidi/release_action.html");

        WebElement inputTextBox = driver.findElement(By.id("keys"));

        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);

        List<Map<String, Object>> events =
                (List<Map<String, Object>>)
                        ((JavascriptExecutor) driver).executeScript("return allEvents.events");
        Assertions.assertEquals("KeyB", events.get(0).get("code"));
        Assertions.assertEquals("KeyA", events.get(1).get("code"));
        }
    }
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await input.release(browsingContextId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/input.spec.js#L55)

##### /examples/javascript/test/bidirectional/input.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, Key, Builder} = require("selenium-webdriver")
const Input = require('selenium-webdriver/bidi/input')

describe('Input module', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can perform input action', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/formSelectionPage.html')

    let options = await driver.findElements(By.tagName('option'))

    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)

    let showButton = await driver.findElement(By.name('showselected'))
    showButton.click()

    let resultElement = await driver.findElement(By.id('result'))
    await resultElement.getText().then(function (text) {
      assert(text.includes('oquefort parmigiano cheddar'), `text is: ${text}`)
    })
  })

  it('can execute release in browsing context', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/bidi/release_action.html')

    let inputTextBox = await driver.findElement(By.id('keys'))

    await driver.executeScript('arguments[0].focus()', inputTextBox)

    const actions = driver.actions().keyDown('a').keyDown('b').getSequences()

    await input.perform(browsingContextId, actions)

    await driver.executeScript('resetEvents()')

    await input.release(browsingContextId)

    const events = await driver.executeScript('return allEvents.events')

    assert.strictEqual(events[0].code, 'KeyB')
    assert.strictEqual(events[1].code, 'KeyA')
  })
})
```

----
url: https://www.selenium.dev/zh-cn/_print/documentation/webdriver/troubleshooting/errors/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/webdriver/troubleshooting/errors/).

# 理解常见的异常

如何处理Selenium代码中的各种问题.

* 1: [Unable to Locate Driver Error](#pg-65b4566cad18a000d8a33a1e9db619c8)

## 无效选择器的异常 (InvalidSelectorException)

某些时候难以获得正确的CSS以及XPath选择器。

### 潜在原因

* The CSS or XPath selector you are trying to use has invalid characters or an invalid query.
* You may have placed an XPATH value as a parameter to a CSS selector, or vice versa.
* You may have used a CSS or XPATH selector as a parameter to an ID selector.

### 可行方案

通过验证器服务运行选择器：

* [CSS 验证器](http://csslint.net/)
* [xPath 验证器](http://www.freeformatter.com/xpath-tester.html)

或者使用浏览器扩展程序来获取已知的良好值：

* [SelectorsHub](https://selectorshub.com/selectorshub/)

## 没有这样元素的异常 (NoSuchElementException)

在您尝试找到该元素的当前时刻无法定位元素。

### 潜在原因

* 您在错误的位置寻找元素 (也许以前的操作不成功)
* 您在错误的时间寻找元素 (该元素尚未显示在 DOM 中)
* 自您编写代码以来定位器已变更

### 可行方案

* 确保您位于期望的页面上，并且代码中的前置操作已正确完成
* 确保您使用的是正确的 [等待策略](https://www.selenium.dev/zh-cn/documentation/webdriver/waits/)
* Use an interactive [Selenium Wait Code Generator](https://99tools.net/selenium-wait-code-generator/) to create accurate explicit wait snippets for multiple supported languages including Java, Python, C#, JavaScript, and Ruby.
* 使用浏览器的devtools控制台更新定位器或使用浏览器扩展程序，例如:
  * [SelectorsHub](https://selectorshub.com/selectorshub/)

## 过时元素引用的异常 (StaleElementReferenceException)

当成功定位到元素时， WebDriver会为其设置一个引用ID作为标记， 如果由于上下文环境发生变化， 导致之前元素的位置发生了变化或者无法找到了， WebDriver并不会自动重新定位， 任何使用之前元素所做的操作将报错该异常。

### 常见因素

以下情况可能发生此异常:

* 您已刷新页面，或者页面的 DOM 已动态更改。
* 您已导航到其他页面。
* 您已切换到另一个窗口，或者进入/移出某个 `frame` / `iframe`。

### 常见方案

**DOM已变更**

当页面刷新或页面上的项目各处移动时， 页面上仍然有一个具有所需定位器的元素， 它只是不再被正在使用的元素对象访问， 并且必须重新定位该元素才能再次使用。

这往往通过以下两种方式之一完成：

* 每次使用时都要重新定位元素。 尽管有可能元素在定位和使用元素之间的微秒内， 发生变化的可能性很小。 缺点是这不是最有效的方法， 尤其是在 `Remote Grid`上运行时。

* 用另一个存储定位器的对象包装 Web 元素，并缓存定位的 Selenium 元素。 对该包装对象执行操作时，您可以尝试使用之前找到的缓存对象， 如果它是发生了变化，则可以捕获异常， 使用存储的定位器重新定位元素，并重试该方法。 这样效率更高，但如果您使用的定位器在页面更改后引用了不同的元素（而不是您想要的元素），则可能会导致问题。

**上下文已变更**

元素对象是针对特定的上下文存储的， 因此如果您切换到不同的上下文， 比如不同的 `Window` 或不同的 `frame` 或 `iframe` 元素引用仍然有效， 但暂时无法访问。在这种情况下， 重新定位元素无济于事，因为它在当前上下文中不存在。

要解决此问题，您需要确保在使用该元素之前切换回正确的上下文。

**页面已变更**

这种情况发生在您不仅更改了上下文， 而且导航到另一个页面并破坏了元素所在的上下文。 您无法仅从当前上下文重新定位它， 也无法切换回元素有效的活动上下文。 如果这是您的错误原因， 您必须回到正确的位置并重新定位元素。

## ElementClickInterceptedException

This exception occurs when Selenium tries to click an element, but the click would instead be received by a different element. Before Selenium will click an element, it checks if the element is visible, unobscured by any other elements, and enabled - if the element is obscured, it will raise this exception.

### Likely Cause

**UI Elements Overlapping**

Elements on the UI are typically placed next to each other, but occasionally elements may overlap. For example, a navbar always staying at the top of your window as you scroll a page. If that navbar happens to be covering an element we are trying to click, Selenium might believe it to be visible and enabled, but when you try to click it will throw this exception. Pop-ups and Modals are also common offenders here.

**Animations**

Elements with animations have the potential to cause this exception as well - it is recommended to wait for animations to cease before attempting to click an element.

### Possible Solutions

**Use Explicit Waits**

[Explicit Waits](https://www.selenium.dev/zh-cn/documentation/webdriver/waits/) will likely be your best friend in these instances. A great way is to use `ExpectedCondition.ToBeClickable()` with `WebDriverWait` to wait until the right moment.

**Scroll the Element into View**

In instances where the element is out of view, but Selenium still registers the element as visible (e.g. navbars overlapping a section at the top of your screen), you can use the `WebDriver.executeScript()` method to execute a javascript function to scroll (e.g. `WebDriver.executeScript('window.scrollBy(0,-250)')`) or you can utilize the Actions class with `Actions.moveToElement(element)`.

## 无效SessionId异常

有时您尝试访问的会话与当前可用的会话不同。

### 可能原因

通常发生在会话被删除时（例如：`driver.quit()`）或会话发生更改时，例如最后一个标签页/浏览器已关闭（例如：`driver.close()`）。

### 可能的解决方案

检查脚本中是否有 `driver.close()` 和 `driver.quit()` 的实例，以及其他可能导致标签页/浏览器关闭的原因。可能是您在应该/能够定位元素之前就尝试定位了该元素。

## SessionNotCreatedException

此异常发生在 WebDriver 无法为浏览器创建新会话时。通常由于版本不匹配、系统级限制或配置问题导致。

### 可能的原因

* 浏览器版本和 WebDriver 版本不兼容（例如 ChromeDriver v113 和 Chrome v115）。
* macOS 隐私设置可能会阻止 WebDriver 运行。
* WebDriver 二进制文件丢失、不可访问或没有执行权限。

### 可能的解决方案

* 确保 WebDriver 版本与浏览器版本匹配。对于 Chrome，请在浏览器中访问 `chrome://settings/help` 检查浏览器版本，并从 [ChromeDriver 下载](https://chromedriver.chromium.org/downloads)页面下载匹配的驱动程序。
* 在 macOS 上，转到 **系统设置 > 隐私与安全性**，并允许驱动程序运行（如果被阻止）。
* 验证驱动程序二进制文件是否可执行（在 Linux/macOS 上运行 `chmod +x /path/to/driver`）。

## ElementNotInteractableException

当 Selenium 尝试与当前状态下无法交互的元素进行交互时，会发生此异常。

### 可能的原因

1. **不支持的操作**：尝试对不支持操作的元素执行操作，例如对 `<form>` 或 `<label>` 使用 `sendKeys`。
2. **多个元素匹配定位器**：定位器匹配到非可交互的元素，例如 `<td>` 标签，而不是目标的 `<input>` 字段。
3. **隐藏的元素**：元素存在于 DOM 中，但由于 CSS、`hidden` 属性或元素超出可见视口范围而不可见。

### 可能的解决方案

1. 根据元素类型使用适当的操作（例如，仅对 `<input>` 字段使用 `sendKeys`）。
2. 确保定位器唯一标识目标元素，以避免错误匹配。
3. 在与元素交互之前，检查其是否在页面上可见。如果需要，将元素滚动到视图中。
4. 使用显式等待以确保元素在执行操作前可交互。

## ElementNotVisibleException

This exception is thrown when the element you are trying to interact with *is* present in the DOM, but is not visible.

### Likely Cause

This can occur in several situations:

* Another element is blocking your intended element
* The element is disabled/invisible to the user

### Possible Solutions

This issue cannot always be resolved on the user’s end, however when it can it is usually solved by the following: using an explicit wait, or interacting with the page in such a way to make the element visible (scrolling, clicking a button, etc.)

# 1 - Unable to Locate Driver Error

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.bash_profile
source ~/.bash_profile
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Terminal and execute:

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.zshenv
source ~/.zshenv
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Command Prompt and execute:

```shell
echo %PATH%
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
setx PATH "%PATH%;C:\WebDriver\bin"
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver.exe --version
```

| 浏览器               | 支持的操作系统                     | 维护者              | 下载                                                                    | 问题追溯                                                             |
| ----------------- | --------------------------- | ---------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------- |
| Chromium/Chrome   | Windows/macOS/Linux         | Google           | [下载](//chromedriver.chromium.org/downloads)                           | [Issues](//bugs.chromium.org/p/chromedriver/issues/list)         |
| Firefox           | Windows/macOS/Linux         | Mozilla          | [下载](//github.com/mozilla/geckodriver/releases)                       | [Issues](//github.com/mozilla/geckodriver/issues)                |
| Edge              | Windows/macOS/Linux         | Microsoft        | [下载](//developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/) | [Issues](https://github.com/MicrosoftDocs/edge-developer/issues) |
| Internet Explorer | Windows                     | Selenium Project | [下载](/downloads)                                                      | [Issues](//github.com/SeleniumHQ/selenium/labels/D-IE)           |
| Safari            | macOS High Sierra and newer | Apple            | 内置                                                                    | [Issues](//bugreport.apple.com/logon)                            |

备注：Opera驱动不再适用于Selenium的最新功能，目前官方不支持。

----
url: https://www.selenium.dev/ja/_print/documentation/webdriver/elements/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/webdriver/elements/).

# Web要素

DOM内の要素オブジェクトの識別と操作

* 1: [要素を探す](#pg-22210ae4aac8f914f07086b7280a15bb)
* 2: [Interacting with web elements](#pg-e71b11b2a7e069d2a8fa4abf95e9c9e4)
* 3: [Web要素の検索](#pg-43e7195137b0710dbc6bfaf6b3e5ec23)
* 4: [Web要素に関する情報](#pg-7fa64f90eb19eb12e2e87f40ee49be77)
* 5: [File Upload](#pg-2922f3e98e474fa6076c3cde2510b91b)

ほとんどの人のSeleniumコードの大部分は、Web要素の操作に関連しています。

# 1 - 要素を探す

DOM内の1つ以上の特定の要素を識別する方法

ロケーターは、ページ上の要素を識別する方法です。 これは、[検索要素](https://www.selenium.dev/ja/documentation/webdriver/elements/finders/) メソッドに渡される引数です。

検出方法とは別にロケーターを宣言するタイミングと理由など、 [ロケーター](https://www.selenium.dev/ja/documentation/test_practices/encouraged/locators/)に関するヒントについては、 [推奨されるテストプラクティス](https://www.selenium.dev/ja/documentation/test_practices/encouraged/) を確認してください。

### 要素選択の方法

WebDriverには標準のロケータが8種類あります。

| ロケータ              | 詳細                             |
| ----------------- | ------------------------------ |
| class name        | class名に値を含む要素を探す (複合クラス名は使えない) |
| css selector      | CSSセレクタが一致する要素を探す              |
| id                | id属性が一致する要素を探す                 |
| name              | name属性が一致する要素を探す               |
| link text         | a要素のテキストが一致する要素を探す             |
| partial link text | a要素のテキストが部分一致する要素を探す           |
| tag name          | タグ名が一致する要素を探す                  |
| xpath             | XPathと一致する要素を探す                |

## Creating Locators

To work on a web element using Selenium, we need to first locate it on the web page. Selenium provides us above mentioned ways, using which we can locate element on the page. To understand and create locator we will use the following HTML snippet.

```html
<html>
<body>
<style>
.information {
  background-color: white;
  color: black;
  padding: 10px;
}
</style>
<h2>Contact Selenium</h2>

<form>
  <input type="radio" name="gender" value="m" />Male &nbsp;
  <input type="radio" name="gender" value="f" />Female <br>
  <br>
  <label for="fname">First name:</label><br>
  <input class="information" type="text" id="fname" name="fname" value="Jane"><br><br>
  <label for="lname">Last name:</label><br>
  <input class="information" type="text" id="lname" name="lname" value="Doe"><br><br>
  <label for="newsletter">Newsletter:</label>
  <input type="checkbox" name="newsletter" value="1" /><br><br>
  <input type="submit" value="Submit">
</form> 

<p>To know more about Selenium, visit the official page 
<a href ="www.selenium.dev">Selenium Official Page</a> 
</p>

</body>
</html>
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L31" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L7-L9)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.ClassName("information"));
  
```

```rb
    driver.find_element(class: 'information')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L7)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.className('information'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.className("information"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L38" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L17-L19)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.CssSelector("#fname"));
  
```

```rb
    driver.find_element(css: '#fname')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L11)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.css('#fname'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.css("#fname"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L45" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L27-L29)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.Id("lname"));
  
```

```rb
    driver.find_element(id: 'lname')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L15)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.id('lname'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.id("lname"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L52" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L37-L39)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.Name("newsletter"));
  
```

```rb
    driver.find_element(name: 'newsletter')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L19)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.name('newsletter'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.name("newsletter"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L59" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L47-L49)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.LinkText("Selenium Official Page"));
  
```

```rb
    driver.find_element(link_text: 'Selenium Official Page')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L23)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.linkText('Selenium Official Page'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.linkText("Selenium Official Page"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L66" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L57-L59)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.PartialLinkText("Official Page"));
  
```

```rb
    driver.find_element(partial_link_text: 'Official Page')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L27)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.partialLinkText('Official Page'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.partialLinkText("Official Page"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L73" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L67-L69)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.TagName("a"));
  
```

```rb
    driver.find_element(tag_name: 'a')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L31)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.tagName('a'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.tagName("a"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L80" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L77-L79)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.Xpath("//input[@value='f']"));
  
```

```rb
    driver.find_element(xpath: "//input[@value='f']")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L35)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.xpath('//input[@value='f']'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.xpath('//input[@value='f']'))
  
```

```java
    import org.openqa.selenium.By;
    WebDriver driver = new ChromeDriver();
	driver.findElement(By.className("information"));
  
```

```python
    from selenium.webdriver.common.by import By
    driver = webdriver.Chrome()
	driver.find_element(By.CLASS_NAME, "information")
  
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.ClassName("information"));
  
```

```rb
    driver.find_element(class: 'information')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L7)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.className('information'));
  
```

```kotlin
    import org.openqa.selenium.By
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.className("information"))
  
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java#L37-L38)

##### /examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java

```java
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java#L22-L23)

##### /examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java

```java
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## 相対ロケーター

**Selenium 4** introduces Relative Locators (previously called as *Friendly Locators*). These locators are helpful when it is not easy to construct a locator for the desired element, but easy to describe spatially where the element is in relation to an element that does have an easily constructed locator.

### How it works

Selenium uses the JavaScript function [getBoundingClientRect()](https://developer.mozilla.org/en-US/docs/Web/API/Element/getBoundingClientRect) to determine the size and position of elements on the page, and can use this information to locate neighboring elements.\
find the relative elements.

Relative locator methods can take as the argument for the point of origin, either a previously located element reference, or another locator. In these examples we’ll be using locators only, but you could swap the locator in the final method with an element object and it will work the same.

Let us consider the below example for understanding the relative locators.

### Available relative locators

#### Above

If the email text field element is not easily identifiable for some reason, but the password text field element is, we can locate the text field element using the fact that it is an “input” element “above” the password element.

*
*
*
*
*
*

```java
By emailLocator = RelativeLocator.with(By.tagName("input")).above(By.id("password"));
```

```python
email_locator = locate_with(By.TAG_NAME, "input").above({By.ID: "password"})
```

```csharp
var emailLocator = RelativeBy.WithLocator(By.TagName("input")).Above(By.Id("password"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L40)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let emailLocator = locateWith(By.tagName('input')).above(By.id('password'));
```

```kotlin
val emailLocator = RelativeLocator.with(By.tagName("input")).above(By.id("password"))
```

```java
By passwordLocator = RelativeLocator.with(By.tagName("input")).below(By.id("email"));
```

```python
password_locator = locate_with(By.TAG_NAME, "input").below({By.ID: "email"})
```

```csharp
var passwordLocator = RelativeBy.WithLocator(By.TagName("input")).Below(By.Id("email"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L44)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let passwordLocator = locateWith(By.tagName('input')).below(By.id('email'));
```

```kotlin
val passwordLocator = RelativeLocator.with(By.tagName("input")).below(By.id("email"))
```

```java
By cancelLocator = RelativeLocator.with(By.tagName("button")).toLeftOf(By.id("submit"));
```

```python
cancel_locator = locate_with(By.TAG_NAME, "button").to_left_of({By.ID: "submit"})
```

```csharp
var cancelLocator = RelativeBy.WithLocator(By.tagName("button")).LeftOf(By.Id("submit"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L48)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let cancelLocator = locateWith(By.tagName('button')).toLeftOf(By.id('submit'));
```

```kotlin
val cancelLocator = RelativeLocator.with(By.tagName("button")).toLeftOf(By.id("submit"))
```

```java
By submitLocator = RelativeLocator.with(By.tagName("button")).toRightOf(By.id("cancel"));
```

```python
submit_locator = locate_with(By.TAG_NAME, "button").to_right_of({By.ID: "cancel"})
```

```csharp
var submitLocator = RelativeBy.WithLocator(By.tagName("button")).RightOf(By.Id("cancel"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L52)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let submitLocator = locateWith(By.tagName('button')).toRightOf(By.id('cancel'));
```

```kotlin
val submitLocator = RelativeLocator.with(By.tagName("button")).toRightOf(By.id("cancel"))
```

```java
By emailLocator = RelativeLocator.with(By.tagName("input")).near(By.id("lbl-email"));
```

```python
email_locator = locate_with(By.TAG_NAME, "input").near({By.ID: "lbl-email"})
```

```csharp
var emailLocator = RelativeBy.WithLocator(By.tagName("input")).Near(By.Id("lbl-email"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L56)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let emailLocator = locateWith(By.tagName('input')).near(By.id('lbl-email'));
```

```kotlin
val emailLocator = RelativeLocator.with(By.tagName("input")).near(By.id("lbl-email"));
```

```java
By submitLocator = RelativeLocator.with(By.tagName("button")).below(By.id("email")).toRightOf(By.id("cancel"));
```

```python
submit_locator = locate_with(By.TAG_NAME, "button").below({By.ID: "email"}).to_right_of({By.ID: "cancel"})
```

```csharp
var submitLocator = RelativeBy.WithLocator(By.tagName("button")).Below(By.Id("email")).RightOf(By.Id("cancel"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L60)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let submitLocator = locateWith(By.tagName('button')).below(By.id('email')).toRightOf(By.id('cancel'));
```

```kotlin
val submitLocator = RelativeLocator.with(By.tagName("button")).below(By.id("email")).toRightOf(By.id("cancel"))
```

# 2 - Interacting with web elements

```java
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L18-L22)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L12-L17)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L17-L21)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'color_input').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L11)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
    await submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L20)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
  const assert = require("assert");
  
  (async function firstTest() {
    let driver;
    
    try {
      driver = await new Builder().forBrowser(Browser.CHROME).build();
      await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
    
      let title = await driver.getTitle();
      assert.equal("Web form", title);
    
      await driver.manage().setTimeouts({implicit: 500});
    
      let textBox = await driver.findElement(By.name('my-text'));
      let submitButton = await driver.findElement(By.css('button'));
    
      await textBox.sendKeys('Selenium');
      await submitButton.click();
    
      let message = await driver.findElement(By.id('message'));
      let value = await message.getText();
      assert.equal("Received!", value);
    } catch (e) {
      console.log(e)
    } finally {
      await driver.quit();
    }
  }())
  
```

```kotlin
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    // Click the element
    driver.findElement(By.name("color_input")).click();
  
  
```

```java
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L27-L32)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L22-L27)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L27-L33)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L16)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
      let inputField = await driver.findElement(By.name('no_type'));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/interactions.spec.js#L21)

##### /examples/javascript/test/elements/interactions.spec.js

```js

  const {By, Browser, Builder} = require('selenium-webdriver');
  const assert = require("node:assert");
  
  
  describe('Element Interactions', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('should Clear input and send keys into input field', async function () {
  
      try {
        await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
        let inputField = await driver.findElement(By.name('no_type'));
        await inputField.clear();
        await inputField.sendKeys('Selenium');
        const text = await inputField.getAttribute('value');
        assert.strictEqual(text, "Selenium");
      } catch (e) {
        console.log(e)
      }
    });
  });
```

```kotlin
  
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

	//Clear field to empty it from any previous data
	driver.findElement(By.name("email_input")).clear()
	
    // Enter text 
    driver.findElement(By.name("email_input")).sendKeys("admin@localhost.dev")
  
  
```

```java
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L38-L40)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    email_input.clear()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L34)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L40-L43)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'email_input').clear
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L15)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
      await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/interactions.spec.js#L20)

##### /examples/javascript/test/elements/interactions.spec.js

```js

  const {By, Browser, Builder} = require('selenium-webdriver');
  const assert = require("node:assert");
  
  
  describe('Element Interactions', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('should Clear input and send keys into input field', async function () {
  
      try {
        await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
        let inputField = await driver.findElement(By.name('no_type'));
        await inputField.clear();
        await inputField.sendKeys('Selenium');
        const text = await inputField.getAttribute('value');
        assert.strictEqual(text, "Selenium");
      } catch (e) {
        console.log(e)
      }
    });
  });
```

```kotlin
  
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

	//Clear field to empty it from any previous data
	driver.findElement(By.name("email_input")).clear()
	
  
  
```

## Submit

In Selenium 4 this is no longer implemented with a separate endpoint and functions by executing a script. As such, it is recommended not to use this method and to click the applicable form submission button instead.

# 3 - Web要素の検索

提供されたロケーターの値に基づいて要素を検索します。

Seleniumを使用する最も基本的な側面の1つは、操作する要素の参照を取得することです。 Seleniumは、要素を一意に識別するための多数の組み込み[ロケーター戦略](https://www.selenium.dev/ja/documentation/webdriver/elements/locators/)を提供します。 非常に高度なシナリオでロケーターを使用する方法はたくさんあります。 このドキュメントの目的のために、このHTMLスニペットについて考えてみましょう。

```html
<ol id="vegetables">
 <li class="potatoes">…
 <li class="onions">…
 <li class="tomatoes"><span>Tomato is a Vegetable</span>…
</ol>
<ul id="fruits">
  <li class="bananas">…
  <li class="apples">…
  <li class="tomatoes"><span>Tomato is a Fruit</span>…
</ul>
```

```java
WebElement vegetable = driver.findElement(By.className("tomatoes"));
  
```

```python
vegetable = driver.find_element(By.CLASS_NAME, "tomatoes")
  
```

```csharp
var vegetable = driver.FindElement(By.ClassName("tomatoes"));
  
```

```rb
      driver.find_element(class: 'tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L10)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const vegetable = await driver.findElement(By.className('tomatoes'));
  
```

```kotlin
val vegetable: WebElement = driver.findElement(By.className("tomatoes"))
  
```

```java
WebElement fruits = driver.findElement(By.id("fruits"));
WebElement fruit = fruits.findElement(By.className("tomatoes"));
  
```

```python
fruits = driver.find_element(By.ID, "fruits")
fruit = fruits.find_element(By.CLASS_NAME,"tomatoes")
  
```

```csharp
IWebElement fruits = driver.FindElement(By.Id("fruits"));
IWebElement fruit = fruits.FindElement(By.ClassName("tomatoes"));
  
```

```rb
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L14-L15)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const fruits = await driver.findElement(By.id('fruits'));
const fruit = fruits.findElement(By.className('tomatoes'));
  
```

```kotlin
val fruits = driver.findElement(By.id("fruits"))
val fruit = fruits.findElement(By.className("tomatoes"))
  
```

```java
WebElement shadowHost = driver.findElement(By.cssSelector("#shadow_host"));
SearchContext shadowRoot = shadowHost.getShadowRoot();
WebElement shadowContent = shadowRoot.findElement(By.cssSelector("#shadow_content"));
```

```python
shadow_host = driver.find_element(By.CSS_SELECTOR, '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(By.CSS_SELECTOR, '#shadow_content')
```

```csharp
var shadowHost = _driver.FindElement(By.CssSelector("#shadow_host"));
var shadowRoot = shadowHost.GetShadowRoot();
var shadowContent = shadowRoot.FindElement(By.CssSelector("#shadow_content"));
```

```ruby
shadow_host = @driver.find_element(css: '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(css: '#shadow_content')
```

```java
WebElement fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"));
  
```

```python
fruit = driver.find_element(By.CSS_SELECTOR,"#fruits .tomatoes")
  
```

```csharp
var fruit = driver.FindElement(By.CssSelector("#fruits .tomatoes"));
  
```

```rb
      driver.find_element(css: '#fruits .tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L19)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const fruit = await driver.findElement(By.css('#fruits .tomatoes'));
  
```

```kotlin
val fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"))
  
```

```java
List<WebElement> plants = driver.findElements(By.tagName("li"));
  
```

```python
plants = driver.find_elements(By.TAG_NAME, "li")
  
```

```csharp
IReadOnlyList<IWebElement> plants = driver.FindElements(By.TagName("li"));
  
```

```rb
      driver.find_elements(tag_name: 'li')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L23)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const plants = await driver.findElements(By.tagName('li'));
  
```

```kotlin
val plants: List<WebElement> = driver.findElements(By.tagName("li"))
  
```

```java
List<WebElement> elements = driver.findElements(By.tagName("li"));

for (WebElement element : elements) {
    System.out.println("Paragraph text:" + element.getText());
}
  
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Firefox()

    # Navigate to Url
driver.get("https://www.example.com")

    # Get all the elements available with tag name 'p'
elements = driver.find_elements(By.TAG_NAME, 'p')

for e in elements:
    print(e.text)
  
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using System.Collections.Generic;

namespace FindElementsExample {
 class FindElementsExample {
  public static void Main(string[] args) {
   IWebDriver driver = new FirefoxDriver();
   try {
    // Navigate to Url
    driver.Navigate().GoToUrl("https://example.com");

    // Get all the elements available with tag name 'p'
    IList < IWebElement > elements = driver.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }

   } finally {
    driver.Quit();
   }
  }
 }
}
  
```

```rb
      elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L27-L28)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
   
   require 'spec_helper'
   
   RSpec.describe 'Element Finders' do
     let(:driver) { start_session }
   
     context 'without executing finders', skip: 'these are just examples, not actual tests' do
       it 'finds the first matching element' do
         driver.find_element(class: 'tomatoes')
       end
   
       it 'uses a subset of the dom to find an element' do
         fruits = driver.find_element(id: 'fruits')
         fruits.find_element(class: 'tomatoes')
       end
   
       it 'uses an optimized locator' do
         driver.find_element(css: '#fruits .tomatoes')
       end
   
       it 'finds all matching elements' do
         driver.find_elements(tag_name: 'li')
       end
   
       it 'gets an element from a collection' do
         elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'finds element from element' do
         element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'find active element' do
         driver.find_element(css: '[name="q"]').send_keys('webElement')
         driver.switch_to.active_element.attribute('title')
       end
     end
   end
   
```

```javascript
const {Builder, By} = require('selenium-webdriver');
(async function example() {
    let driver = await new Builder().forBrowser('firefox').build();
    try {
        // Navigate to Url
        await driver.get('https://www.example.com');

        // Get all the elements available with tag 'p'
        let elements = await driver.findElements(By.css('p'));
        for(let e of elements) {
            console.log(await e.getText());
        }
    }
    finally {
        await driver.quit();
    }
})();
  
```

```kotlin
import org.openqa.selenium.By
import org.openqa.selenium.firefox.FirefoxDriver

fun main() {
    val driver = FirefoxDriver()
    try {
        driver.get("https://example.com")
        // Get all the elements available with tag name 'p'
        val elements = driver.findElements(By.tagName("p"))
        for (element in elements) {
            println("Paragraph text:" + element.text)
        }
    } finally {
        driver.quit()
    }
}
  
```

```java
  import org.openqa.selenium.By;
  import org.openqa.selenium.WebDriver;
  import org.openqa.selenium.WebElement;
  import org.openqa.selenium.chrome.ChromeDriver;
  import java.util.List;

  public class findElementsFromElement {
      public static void main(String[] args) {
          WebDriver driver = new ChromeDriver();
          try {
              driver.get("https://example.com");

              // Get element with tag name 'div'
              WebElement element = driver.findElement(By.tagName("div"));

              // Get all the elements available with tag name 'p'
              List<WebElement> elements = element.findElements(By.tagName("p"));
              for (WebElement e : elements) {
                  System.out.println(e.getText());
              }
          } finally {
              driver.quit();
          }
      }
  }
  
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://www.example.com")
##get elements from parent element using TAG_NAME

    # Get element with tag name 'div'
element = driver.find_element(By.TAG_NAME, 'div')

    # Get all the elements available with tag name 'p'
elements = element.find_elements(By.TAG_NAME, 'p')
for e in elements:
    print(e.text)

##get elements from parent element using XPATH
##NOTE: in order to utilize XPATH from current element, you must add "." to beginning of path

    # Get first element of tag 'ul'
element = driver.find_element(By.XPATH, '//ul')

    # get children of tag 'ul' with tag 'li'
elements  = element.find_elements(By.XPATH, './/li')
for e in elements:
    print(e.text)
  
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace FindElementsFromElement {
 class FindElementsFromElement {
  public static void Main(string[] args) {
   IWebDriver driver = new ChromeDriver();
   try {
    driver.Navigate().GoToUrl("https://example.com");

    // Get element with tag name 'div'
    IWebElement element = driver.FindElement(By.TagName("div"));

    // Get all the elements available with tag name 'p'
    IList < IWebElement > elements = element.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }
   } finally {
    driver.Quit();
   }
  }
 }
}
  
```

```rb
      element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L32-L34)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
   
   require 'spec_helper'
   
   RSpec.describe 'Element Finders' do
     let(:driver) { start_session }
   
     context 'without executing finders', skip: 'these are just examples, not actual tests' do
       it 'finds the first matching element' do
         driver.find_element(class: 'tomatoes')
       end
   
       it 'uses a subset of the dom to find an element' do
         fruits = driver.find_element(id: 'fruits')
         fruits.find_element(class: 'tomatoes')
       end
   
       it 'uses an optimized locator' do
         driver.find_element(css: '#fruits .tomatoes')
       end
   
       it 'finds all matching elements' do
         driver.find_elements(tag_name: 'li')
       end
   
       it 'gets an element from a collection' do
         elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'finds element from element' do
         element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'find active element' do
         driver.find_element(css: '[name="q"]').send_keys('webElement')
         driver.switch_to.active_element.attribute('title')
       end
     end
   end
   
```

```javascript
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = new Builder()
          .forBrowser('chrome')
          .build();

      await driver.get('https://www.example.com');

      // Get element with tag name 'div'
      let element = driver.findElement(By.css("div"));

      // Get all the elements available with tag name 'p'
      let elements = await element.findElements(By.css("p"));
      for(let e of elements) {
          console.log(await e.getText());
      }
  })();
  
```

```kotlin
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://example.com")

          // Get element with tag name 'div'
          val element = driver.findElement(By.tagName("div"))

          // Get all the elements available with tag name 'p'
          val elements = element.findElements(By.tagName("p"))
          for (e in elements) {
              println(e.text)
          }
      } finally {
          driver.quit()
      }
  }
  
```

```java
  import org.openqa.selenium.*;
  import org.openqa.selenium.chrome.ChromeDriver;

  public class activeElementTest {
    public static void main(String[] args) {
      WebDriver driver = new ChromeDriver();
      try {
        driver.get("http://www.google.com");
        driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement");

        // Get attribute of current active element
        String attr = driver.switchTo().activeElement().getAttribute("title");
        System.out.println(attr);
      } finally {
        driver.quit();
      }
    }
  }
  
```

```python
  from selenium import webdriver
  from selenium.webdriver.common.by import By

  driver = webdriver.Chrome()
  driver.get("https://www.google.com")
  driver.find_element(By.CSS_SELECTOR, '[name="q"]').send_keys("webElement")

    # Get attribute of current active element
  attr = driver.switch_to.active_element.get_attribute("title")
  print(attr)
  
```

```csharp
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;

    namespace ActiveElement {
     class ActiveElement {
      public static void Main(string[] args) {
       IWebDriver driver = new ChromeDriver();
       try {
        // Navigate to Url
        driver.Navigate().GoToUrl("https://www.google.com");
        driver.FindElement(By.CssSelector("[name='q']")).SendKeys("webElement");

        // Get attribute of current active element
        string attr = driver.SwitchTo().ActiveElement().GetAttribute("title");
        System.Console.WriteLine(attr);
       } finally {
        driver.Quit();
       }
      }
     }
    }
  
```

```rb
      driver.find_element(css: '[name="q"]').send_keys('webElement')
        driver.switch_to.active_element.attribute('title')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L38-L39)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
  
  require 'spec_helper'
  
  RSpec.describe 'Element Finders' do
    let(:driver) { start_session }
  
    context 'without executing finders', skip: 'these are just examples, not actual tests' do
      it 'finds the first matching element' do
        driver.find_element(class: 'tomatoes')
      end
  
      it 'uses a subset of the dom to find an element' do
        fruits = driver.find_element(id: 'fruits')
        fruits.find_element(class: 'tomatoes')
      end
  
      it 'uses an optimized locator' do
        driver.find_element(css: '#fruits .tomatoes')
      end
  
      it 'finds all matching elements' do
        driver.find_elements(tag_name: 'li')
      end
  
      it 'gets an element from a collection' do
        elements = driver.find_elements(:tag_name, 'p')
        elements.each { |e| puts e.text }
      end
  
      it 'finds element from element' do
        element = driver.find_element(:tag_name, 'div')
        elements = element.find_elements(:tag_name, 'p')
        elements.each { |e| puts e.text }
      end
  
      it 'find active element' do
        driver.find_element(css: '[name="q"]').send_keys('webElement')
        driver.switch_to.active_element.attribute('title')
      end
    end
  end
  
```

```javascript
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = await new Builder().forBrowser('chrome').build();
      await driver.get('https://www.google.com');
      await  driver.findElement(By.css('[name="q"]')).sendKeys("webElement");

      // Get attribute of current active element
      let attr = await driver.switchTo().activeElement().getAttribute("title");
      console.log(`${attr}`)
  })();
  
```

```kotlin
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://www.google.com")
          driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement")

          // Get attribute of current active element
          val attr = driver.switchTo().activeElement().getAttribute("title")
          print(attr)
      } finally {
          driver.quit()
      }
  }
  
```

# 4 - Web要素に関する情報

```java
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L27-L29)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L12-L15)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L18-L22)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    displayed_value = driver.find_element(name: 'email_input').displayed?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L12)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L16-L17)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
 driver.get("https://www.selenium.dev/selenium/web/inputs.html")

 //returns true if element is displayed else returns false 
 val flag = driver.findElement(By.name("email_input")).isDisplayed()
```

```java
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L32-L34)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L19)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L25-L27)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    enabled_value = driver.find_element(name: 'email_input').enabled?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L17)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L23-L24)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
 //navigates to url
 driver.get("https://www.selenium.dev/selenium/web/inputs.html")

 //returns true if element is enabled else returns false 
 val attr = driver.findElement(By.name("button_input")).isEnabled()
 
```

```java
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L37-L39)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L23)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L30-L32)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    selected_value = driver.find_element(name: 'email_input').selected?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L22)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L30-L31)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//returns true if element is checked else returns false
val attr =  driver.findElement(By.name("checkbox_input")).isSelected()
```

```java
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L42-L44)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L27)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L35-L37)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    tag_name = driver.find_element(name: 'email_input').tag_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L27)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L37-L38)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//returns TagName of the element
val attr =  driver.findElement(By.name("email_input")).getTagName()
```

```java
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L47-L50)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    rect = driver.find_element(By.NAME, "range_input").rect
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L31)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L40-L43)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    size = driver.find_element(name: 'email_input').size
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L32)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    let object = await driver.findElement(By.name('range_input')).getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L45)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

// Returns height, width, x and y coordinates referenced element
val res = driver.findElement(By.name("range_input")).rect

// Rectangle class provides getX,getY, getWidth, getHeight methods
println(res.getX())
  
```

```java
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L52-L54)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L35-L37)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L49-L50)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L38)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L76-L78)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to Url
driver.get("https://www.selenium.dev/selenium/web/colorPage.html")

// Retrieves the computed style property 'color' of linktext
val cssValue = driver.findElement(By.id("namedColor")).getCssValue("background-color")
```

```java
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L58-L60)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    text = driver.find_element(By.TAG_NAME, "h1").text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L41)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L53-L55)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    text = driver.find_element(xpath: '//h1').text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L43)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L84-L86)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to URL
driver.get("https://www.selenium.dev/selenium/web/linked_image.html")

// retrieves the text of the element
val text = driver.findElement(By.id("justanotherlink")).getText()
```

```java
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L64-L68)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L44-L46)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L58-L62)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L48)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L55-L59)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to URL
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//fetch the value property associated with the textbox
val attr = driver.findElement(By.name("email_input")).getAttribute("value")
```

```java
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/FileUploadTest.java#L17-L19)

##### /examples/java/src/test/java/dev/selenium/elements/FileUploadTest.java

```java
package dev.selenium.elements;

import dev.selenium.BaseChromeTest;
import java.io.File;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

public class FileUploadTest extends BaseChromeTest {

  @Test
  public void fileUploadTest() {
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }
}
```

```py
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_file_upload.py#L12-L14)

##### /examples/python/tests/elements/test\_file\_upload.py

```py
import os

from selenium import webdriver
from selenium.webdriver.common.by import By


def test_uploads(driver):
    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"
```

```cs
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/FileUploadTest.cs#L21-L23)

##### /examples/dotnet/SeleniumDocs/Elements/FileUploadTest.cs

```cs
using System;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;

namespace SeleniumDocs.Elements
{
    [TestClass]
    public class FileUploadTest : BaseChromeTest
    {
        [TestMethod]
        public void Uploads()
        {
            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }
    }
}
```

```rb
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/file_upload_spec.rb#L12-L14)

##### /examples/ruby/spec/elements/file\_upload\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'File Upload' do
  let(:driver) { start_session }

  it 'uploads' do
    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    file_name = driver.find_element(id: 'uploaded-files')
    expect(file_name.text).to eq 'selenium-snapshot.png'
  end
end
```

```js
    await driver.get('https://the-internet.herokuapp.com/upload');
    // Upload snapshot
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/fileUpload.spec.js#L24-L25)

##### /examples/javascript/test/elements/fileUpload.spec.js

```js

const {Browser, By, until, Builder} = require("selenium-webdriver");
const path = require("path");
const assert = require('node:assert');


describe('File Upload Test', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async() => await driver.quit());

  it('Should be able to upload a file successfully', async function() {
    const image = path.resolve('./test/resources/selenium-snapshot.png')

    await driver.manage().setTimeouts({implicit: 5000});

    // Navigate to URL
    await driver.get('https://the-internet.herokuapp.com/upload');
    // Upload snapshot
    await driver.findElement(By.id("file-upload")).sendKeys(image);
    await driver.findElement(By.id("file-submit")).submit();

    const revealed = await driver.findElement(By.id('uploaded-files'))
    await driver.wait(until.elementIsVisible(revealed), 2000);
    const data = await driver.findElement(By.css('h3'));

    assert.equal(await data.getText(), `File Uploaded!`);
  });
});
```

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/interactions/virtual_authenticator/
----

# 虚拟身份验证器

```java
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L55-L61)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L48-55)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L40-L46)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setHasUserVerification(true);
    options.setIsUserConsenting(true);
    options.setTransport(Transport['USB']);
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    assert(Object.keys(options).length === 6);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticatorOptions.spec.js#L11-L17)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticatorOptions.spec.js

```js
const {VirtualAuthenticatorOptions, Transport, Protocol} = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')


describe('Virtual authenticator options', function () {
  let options;

  it('Virtual options', async function () {
    options = new VirtualAuthenticatorOptions();
    options.setIsUserVerified(true);
    options.setHasUserVerification(true);
    options.setIsUserConsenting(true);
    options.setTransport(Transport['USB']);
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    assert(Object.keys(options).length === 6);
  });

  it('User verified', async function () {
    options.setIsUserVerified(true);

    assert(options.toDict()['isUserVerified']);
  });
});
```

```java
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L68-L73)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L63-71)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L53-L58)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L51-L55)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L86)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#80-86)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L68-L74)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L62-L63)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L100-L103)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#103-107)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L89-L97)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L80-L94)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L143-L145)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L145-148)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L140-L147)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L136-L140)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L137-L146)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L139-150)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.add_credential(credential)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L150)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L131-L142)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L157-L171)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L162-178)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    credential_list = driver.get_credentials()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L183)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L154-L170)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

## 删除凭据

根据传递的凭据ID从身份验证器中删除凭据。

```cs
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L189-198)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

*
*
*
*
*
*

```java
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L181-L190)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.remove_credential(credential.id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L209)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```java
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L196-L205)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L207-216)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.remove_all_credentials()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L239)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L181-L190)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L211-L212)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L224-225)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L245-L247)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setIsUserVerified(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L197-L197)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/support_features/
----

# Support features

针对更高层面功能的额外支持类.

Selenium的核心库试图提供底层以及普适的功能. 每种语言的支持类都为常见交互提供特定的包装器, 可用于简化某些行为.

***

##### [期望状态的等待](/zh-cn/documentation/webdriver/support_features/expected_conditions/)

本文档描述了一系列类, 这些类用于明确指定在测试中需要等待的各种条件.

##### [命令监听器](/zh-cn/documentation/webdriver/support_features/listeners/)

##### [同颜色一起工作](/zh-cn/documentation/webdriver/support_features/colors/)

##### [线程守卫](/zh-cn/documentation/webdriver/support_features/thread_guard/)

##### [使用选择列表元素](/zh-cn/documentation/webdriver/support_features/select_lists/)

与其他元素相比，选择列表具有特殊的行为.

最后修改 October 2, 2022: [Update Chinese version of "support\_features" (#1186) (f776bb830fc)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/f776bb830fc4f6e57513a8fbf84f3843916caa06)

----
url: https://www.selenium.dev/ja/documentation/grid/configuration/cli_options/
----

# Selenium GridのCLI オプション

全てのGridコンポーネントのCLIオプション詳細

Grid の設定には、さまざまなセクションが用意されています。 各セクションには、コマンドライン引数で設定可能なオプションがあります。コマンドライン引数で設定できます。

コンポーネントとセクションの対応は以下の通りです。

オプションが変更、または追加されたが文書化されていない場合、 このドキュメントは古くなる可能性があることに注意してください。 もしそのような状況を見つけたら、[“構成ヘルプ”](https://www.selenium.dev/ja/documentation/grid/configuration/help/)を確認し、 ドキュメントを更新するプルリクエストを気軽に送ってください。

## セクション

|                               | スタンドアロン | ハブ | ノード | ディストリビューター | ルーター | セッション | 新規セッションキュー |
| ----------------------------- | ------- | -- | --- | ---------- | ---- | ----- | ---------- |
| [Distributor](#distributor)   | **      | ** |     | **         | **   |       |            |
| [Docker](#docker)             | **      |    | **  |            |      |       |            |
| [Events](#events)             |         | ** | **  | **         |      | **    | **         |
| [Logging](#logging)           | **      | ** | **  | **         | **   | **    | **         |
| [Network](#network)           | **      | ** |     |            | **   |       |            |
| [Node](#node)                 | **      |    | **  |            |      |       |            |
| [Router](#router)             | **      | ** |     |            | **   |       |            |
| [Relay](#relay)               | **      |    | **  |            |      |       |            |
| [Server](#server)             | **      | ** | **  | **         | **   | **    | **         |
| [SessionQueue](#sessionqueue) | **      | ** |     | **         | **   |       | **         |
| [Sessions](#sessions)         |         |    |     | **         | **   | **    |            |

### Distributor

| オプション                          | 型       | 値/例                                                                 | 概要                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ------------------------------ | ------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--healthcheck-interval`       | int     | `120`                                                               | 全てのノードに対してヘルスチェックを実行する頻度（秒）を指定します。これにより、サーバーは全てのノードに対して正常に ping を送信できるようになります。                                                                                                                                                                                                                                                                                                                                                                      |
| `--distributor`                | uri     | `http://localhost:5553`                                             | ディストリビューターの URL。                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `--distributor-host`           | string  | `localhost`                                                         | ディストリビューターがリッスンするホスト名。                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `--distributor-implementation` | string  | `org.openqa.selenium.grid.distributor.local.LocalDistributor`       | デフォルトでないディストリビューター実装の完全なクラス名。                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `--distributor-port`           | int     | `5553`                                                              | ディストリビューターがリッスンするポート番号。                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `--reject-unsupported-caps`    | boolean | `false`                                                             | Grid がサポートしていない capabilities をリクエストされた時、ディストリビューターがリクエストを即座に今日できるようにします。これはオンデマンドでノードを立ち上げをしない Grid の設定に適しています。                                                                                                                                                                                                                                                                                                                                     |
| `--slot-matcher`               | string  | `org.openqa.selenium.grid.data.DefaultSlotMatcher`                  | デフォルト以外で使用するスロットマッチャーの完全なクラス名。これはノードが特定のセッションをサポートできるかを判断するために使用されます。                                                                                                                                                                                                                                                                                                                                                                               |
| `--slot-selector`              | string  | `org.openqa.selenium.grid.distributor.selector.DefaultSlotSelector` | デフォルト以外のスロットセレクターの完全なクラス名。これは、ノードがマッチした後ノード内のスロットを選択するために使用されます。                                                                                                                                                                                                                                                                                                                                                                                    |
| `--newsession-threadpool-size` | int     | `24`                                                                | The Distributor uses a fixed-sized thread pool to create new sessions as it consumes new session requests from the queue. This allows configuring the size of the thread pool. The default value is no. of available processors \* 3. Note: If the no. of threads is way greater than the available processors it will not always increase the performance. A high number of threads causes more context switching which is an expensive operation. |
| `--purge-nodes-interval`       | int     | `30`                                                                | How often, in seconds, will the Distributor purge Nodes that have been down for a while. This is calculated based on the heartbeat received from a particular node.                                                                                                                                                                                                                                                                                 |

### Docker

| オプション                       | 型         | 値/例                                                               | 概要                                                                                                                                                                                                                                                                                          |
| --------------------------- | --------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--docker-assets-path`      | string    | `/opt/selenium/assets`                                            | アセットが保存される絶対パス。                                                                                                                                                                                                                                                                             |
| `--docker-`                 | string\[] | `selenium/standalone-firefox:latest '{"browserName": "firefox"}'` | イメージとステレオタイプの capabilities を対応付ける Docker 設定 (例 \`-D selenium/standalone-firefox:latest ‘{“browserName”: “firefox”}’)                                                                                                                                                                        |
| `--docker-devices`          | string\[] | `/dev/kvm:/dev/kvm`                                               | コンテナに対してデバイスを公開します。各デバイスマッピングは、ホストとコンテナの両方のデバイスへのパスを、コロンで区切って保つ必要があります。例: /device/path/in/host:/device/path/in/container                                                                                                                                                                    |
| `--docker-host`             | string    | `localhost`                                                       | Docker デーモンが動作しているホスト名。                                                                                                                                                                                                                                                                     |
| `--docker-port`             | int       | `2375`                                                            | Docker デーモンが動作しているポート名。                                                                                                                                                                                                                                                                     |
| `--docker-url`              | string    | `http://localhost:2375`                                           | Docker デーモンに接続するための URL。                                                                                                                                                                                                                                                                    |
| `--docker-video-image`      | string    | `selenium/video:latest`                                           | ビデオレコーディングが有効になっているときに利用される Docker イメージ。                                                                                                                                                                                                                                                    |
| `--docker-host-config-keys` | string\[] | `Dns DnsOptions DnsSearch ExtraHosts Binds`                       | Specify which docker host configuration keys should be passed to browser containers. Keys name can be found in the Docker API [documentation](https://docs.docker.com/engine/api/v1.41/#tag/Container/operation/ContainerCreate), or by running `docker inspect` the node-docker container. |

### Events

| オプション                     | 型       | 値/例                                                | 概要                                                                                                                                                |
| ------------------------- | ------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--bind-bus`              | boolean | `false`                                            | 接続をバインドするかコネクトするかを指定します。 true の場合、コンポーネントはイベントバスにバインドされます（イベントバスもコンポーネントによって起動されます、通常はディストリビューターとハブによって起動されます）。 false の場合、コンポーネントがイベントバスにコネクトします。 |
| `--events-implementation` | string  | `org.openqa.selenium.events.zeromq.ZeroMqEventBus` | デフォルトでないイベントバス実装の完全なクラス名。                                                                                                                         |
| `--publish-events`        | string  | `tcp://*:4442`                                     | イベントをイベントバスに配信するための接続文字列。                                                                                                                         |
| `--subscribe-events`      | string  | `tcp://*:4443`                                     | イベントをイベントバスから購読するための接続文字列。                                                                                                                        |

### Logging

| オプション                    | 型       | 値/例                                                                                                                                      | 概要                                                                                                                                       |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `--http-logs`            | boolean | `false`                                                                                                                                  | http ログを有効にします。http ログを記録するには、トレースを有効にする必要があります。                                                                                         |
| `--log-encoding`         | string  | `UTF-8`                                                                                                                                  | ログのエンコーディング。                                                                                                                             |
| `--log`                  | string  | Windows パスの例: `'\path\to\file\gridlog.log'` or `'C:\path\path\to\file\gridlog.log'` Linux/Unix/MacOS パスの例: `'/path/to/file/gridlog.log'` | ログを出力するファイル。OS のファイルパスと互換性があることを確認してください。                                                                                                |
| `--log-level`            | string  | `“INFO”`                                                                                                                                 | ログレベル。デフォルトは INFO です。 ログレベルはこちらを参照してください。 <https://docs.oracle.com/en/java/javase/11/docs/api/java.logging/java/util/logging/Level.html> |
| `--plain-logs`           | boolean | `true`                                                                                                                                   | プレーンなログを使用します。                                                                                                                           |
| `--structured-logs`      | boolean | `false`                                                                                                                                  | 構造化ログを使用します。                                                                                                                             |
| `--tracing`              | boolean | `true`                                                                                                                                   | トレースを有効にします。                                                                                                                             |
| `--log-timestamp-format` | string  | `HH:mm:ss.SSS`                                                                                                                           | ログのタイムスタンプ形式を設定できます。                                                                                                                     |

### Network

| オプション            | 型       | 値/例     | 概要                                                  |
| ---------------- | ------- | ------- | --------------------------------------------------- |
| `--relax-checks` | boolean | `false` | 受信リクエストのオリジンヘッダーとコンテンツタイプに対する、厳格な W3C 準拠の検証をを緩和します。 |

### Node

| オプション                            | 型         | 値/例                                                                                                                                                                                                                                                                        | 概要                                                                                                                                                                                                                                                                                                                                                                             |
| -------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--detect-drivers`               | boolean   | `true`                                                                                                                                                                                                                                                                     | 現在のシステム上で利用可能なドライバーを自動で検出してノードに追加します。                                                                                                                                                                                                                                                                                                                                          |
| `--driver-configuration`         | string\[] | `display-name="Firefox Nightly" max-sessions=2 webdriver-path="/usr/local/bin/geckodriver" stereotype="{\"browserName\": \"firefox\", \"browserVersion\": \"86\", \"moz:firefoxOptions\": {\"binary\":\"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"` | ノードがサポートするドライバーの一覧。可読性向上のため TOML ファイルで設定することを推奨します。                                                                                                                                                                                                                                                                                                                            |
| `--driver-factory`               | string\[] | `org.openqa.selenium.example.LynxDriverFactory '{"browserName": "lynx"}'`                                                                                                                                                                                                  | 完全修飾クラス名と、そのクラスが対応するブラウザの設定とのマッピング。                                                                                                                                                                                                                                                                                                                                            |
| `--driver-implementation`        | string\[] | `"firefox"`                                                                                                                                                                                                                                                                | チェックされるドライバー。指定された場合、自動設定はスキップされます。                                                                                                                                                                                                                                                                                                                                            |
| `--node-implementation`          | string    | `"org.openqa.selenium.grid.node.local.LocalNodeFactory"`                                                                                                                                                                                                                   | デフォルトでないノード実装の完全なクラス名。これはセッションのライフサイクルを管理するために使用されます。                                                                                                                                                                                                                                                                                                                          |
| `--grid-url`                     | string    | `https://grid.example.com`                                                                                                                                                                                                                                                 | Grid 全体のパブリックな URL (通常ハブかルーターのアドレスです)。                                                                                                                                                                                                                                                                                                                                         |
| `--heartbeat-period`             | int       | `60`                                                                                                                                                                                                                                                                       | ノードが生存していることを知らせるため、ノードがディストリビューターに送るハードビートを、どのくらいの頻度（秒）で送るか。                                                                                                                                                                                                                                                                                                                  |
| `--max-sessions`                 | int       | `8`                                                                                                                                                                                                                                                                        | 最大同時接続セッション数。デフォルトは利用可能なプロセッサーの数です。                                                                                                                                                                                                                                                                                                                                            |
| `--override-max-sessions`        | boolean   | `false`                                                                                                                                                                                                                                                                    | 利用可能なプロセッサーの数は、推奨される最大セッション数（プロセッサーごとに 1 つのブラウザセッション）です。このフラグを true に設定すると、推奨される最大値を上書きすることができます。セッションの安定性と信頼性が損なわれ、ホストがリソースを使い果たす可能性があります。                                                                                                                                                                                                                                    |
| `--register-cycle`               | int       | `10`                                                                                                                                                                                                                                                                       | ノードがディストリビューターに初回登録を試みる頻度(秒)。                                                                                                                                                                                                                                                                                                                                                  |
| `--register-period`              | int       | `120`                                                                                                                                                                                                                                                                      | ノードが初めてディストリビューターに初回登録を試みるのにかかる時間(秒)。この時間が経過すると、ノードは再登録を試みない。                                                                                                                                                                                                                                                                                                                  |
| `--session-timeout`              | int       | `300`                                                                                                                                                                                                                                                                      | X をセッションタイムアウト(秒)としたとき、 ノード は、過去 X 秒間に何の活動もなかったセッションを自動的に終了させます。 これにより他のテストが利用できるようスロットを解放します。                                                                                                                                                                                                                                                                                 |
| `--vnc-env-var`                  | string\[] | `SE_START_XVFB SE_START_VNC SE_START_NO_VNC`                                                                                                                                                                                                                               | VNC ストリームが利用可能かどうかを判断するために利用する環境変数。                                                                                                                                                                                                                                                                                                                                            |
| `--no-vnc-port`                  | int       | `7900`                                                                                                                                                                                                                                                                     | VNC が利用可能な場合、ローカルの noVNC ストリームを取得できるポートを設定します。                                                                                                                                                                                                                                                                                                                                 |
| `--drain-after-session-count`    | int       | `1`                                                                                                                                                                                                                                                                        | X 個のセッションが実行された後に、ノードをドレインしてシャットダウンします。 Kubernetes のような環境で有用です。 0 より大きい値を指定すると、この機能が有効になります。                                                                                                                                                                                                                                                                                   |
| `--hub`                          | string    | `http://localhost:4444`                                                                                                                                                                                                                                                    | ハブ・ノード構成におけるハブのアドレスを指定します。ホスト名か IP アドレスが指定できます。この場合、ハブは `http://hostname:4444` とみなされ、 `--grid-url` は同じものになります。 `--publish-events` は `tcp://hostname:4442` 、`--subscribe-events` は `tcp://hostname:4443` となります。 `hostname` にポート番号が含まれている場合は、それが `--grid-url` に使用されますが、イベントバスの URI は変更されません。これらのデフォルト値は、適切なフラグを設定することでオーバーライドすることができます。ホスト名にプロトコル(`https`のような)が含まれる場合もそれが利用されます。 |
| `--enable-cdp`                   | boolean   | `true`                                                                                                                                                                                                                                                                     | Grid 内で CDP プロキシーを有効にします。もしネットワークが web socket を許可していない場合、Grid 管理者は CDP を無効にできます。デフォルトは true です。                                                                                                                                                                                                                                                                                |
| `--enable-managed-downloads`     | boolean   | `false`                                                                                                                                                                                                                                                                    | This causes the Node to auto manage files downloaded for a given session on the Node.                                                                                                                                                                                                                                                                                          |
| `--selenium-manager`             | boolean   | `false`                                                                                                                                                                                                                                                                    | When drivers are not available on the current system, use Selenium Manager. False by default.                                                                                                                                                                                                                                                                                  |
| `--connection-limit-per-session` | int       | `10`                                                                                                                                                                                                                                                                       | Let X be the maximum number of websocket connections per session.This will ensure one session is not able to exhaust the connection limit of the host.                                                                                                                                                                                                                         |

### Relay

| オプション                        | 型         | 値/例                                                                                                               | 概要                                                                                                              |
| ---------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `--service-url`              | string    | `http://localhost:4723`                                                                                           | Appium サーバーやクラウドサービスなど、WebDriver コマンドをサポートするサービスに接続するための URL です。                                                |
| `--service-host`             | string    | `localhost`                                                                                                       | WebDriver コマンドをサポートしてるサービスが稼働しているホスト名。                                                                          |
| `--service-port`             | int       | `4723`                                                                                                            | WebDriver コマンドをサポートしてるサービスが稼働しているポート番号。                                                                         |
| `--service-status-endpoint`  | string    | `/status`                                                                                                         | WebDriver サービスの状態を問い合わせるエンドポイント、オプショナルです。HTTP 200 レスポンスが期待されます。                                                 |
| `--service-protocol-version` | string    | `HTTP/1.1`                                                                                                        | Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status |
| `--service-configuration`    | string\[] | `max-sessions=2 stereotype='{"browserName": "safari", "platformName": "iOS", "appium:platformVersion": "14.5"}}'` | 呼び出しの中継先となるサービスの設定。可読性向上のため、TOML ファイルで設定することを推奨します。                                                             |

### Router

| オプション          | 型       | 値/例                        | 概要                                                                                            |
| -------------- | ------- | -------------------------- | --------------------------------------------------------------------------------------------- |
| `--password`   | string  | `myStrongPassword`         | クライアントがサーバーに接続する際に使用するパスワード。このパスワードとユーザー名の両方が設定されていないと使用できません。                                |
| `--username`   | string  | `admin`                    | クライアントがサーバーに接続する際に使用するユーザー名。このユーザー名とパスワードの両方が設定されていないと使用できません。                                |
| `--sub-path`   | string  | `my_company/selenium_grid` | A sub-path that should be considered for all user facing routes on the Hub/Router/Standalone. |
| `--disable-ui` | boolean | `true`                     | Disable the Grid UI.                                                                          |

### Server

| オプション                 | 型       | 値/例                  | 概要                                                                                                                                               |
| --------------------- | ------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--allow-cors`        | boolean | `true`               | Selenium サーバーが任意のホストからのウェブブラウザ接続を許可するかどうか。                                                                                                       |
| `--host`              | string  | `localhost`          | サーバーの IP もしくはホスト名、通常自動的に決定されます。                                                                                                                  |
| `--bind-host`         | boolean | `true`               | サーバがホストアドレス/ホスト名にバインドするか、あるいは到達可能な URL を知らせるためだけに使用するかを指定します。複雑なネットワーク構成で、サーバが現在の IP やホスト名ではなく、 外部の IP やホスト名で自分自身を公開する場合に有用です (例: Docker コンテナ内)。 |
| `--https-certificate` | path    | `/path/to/cert.pem`  | HTTPS のためのサーバー証明書。詳細は “java -jar selenium-server.jar info security” を実行してください。                                                                   |
| `--https-private-key` | path    | `/path/to/key.pkcs8` | HTTPS のための秘密鍵。 詳細は “java -jar selenium-server.jar info security” を実行してください。                                                                      |
| `--max-threads`       | int     | `24`                 | リスナースレッドの最大数。デフォルトは、有効なプロセッサーの \* 3 です。                                                                                                          |
| `--port`              | int     | `4444`               | リッスンポート。このパラメータは異なるコンポーネントによって使用されるため、デフォルトはありません。例えば、ルータ/ハブ/スタンドアロンは 4444 を使用し、ノードは 5555 を使用します。                                                |

### SessionQueue

| オプション                       | 型      | 値/例                     | 概要                                                                                                                                                      |
| --------------------------- | ------ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--sessionqueue`            | uri    | `http://localhost:1237` | 新規セッションキューサーバーのアドレス。                                                                                                                                    |
| `-sessionqueue-host`        | string | `localhost`             | 新規セッションキューがリッスンするホスト。                                                                                                                                   |
| `--sessionqueue-port`       | int    | `1234`                  | 新規セッションキューがリッスンするポート                                                                                                                                    |
| `--session-request-timeout` | int    | `300`                   | タイムアウト(秒)。 新規セッションリクエストはキューに追加され、設定された時間以上キューに残っているリクエストはタイムアウトします。                                                                                     |
| `--session-retry-interval`  | int    | `5`                     | リトライ間隔(秒)。すべてのスロットがビジーな場合、 新規セッションリクエストはこの時間の間隔をおいてからリトライされます。                                                                                          |
| `--maximum-response-delay`  | int    | `8`                     | How often, in seconds, will the the SessionQueue response in case there is no data, to reduce the http requests while polling for new session requests. |

### Sessions

| オプション             | 型      | 値/例                     | 概要                      |
| ----------------- | ------ | ----------------------- | ----------------------- |
| `--sessions`      | uri    | `http://localhost:1234` | セッションマップサーバーのアドレス。      |
| `--sessions-host` | string | `localhost`             | セッションマップサーバーがリッスンするホスト。 |
| `--sessions-port` | int    | `1234`                  | セッションマップサーバーがリッスンするポート。 |

## 設定例

上記のオプションはすべて、Grid コンポーネントを起動する際に使用することができます。 Grid の適切な設定を模索するのに利用してください。

[TOML ファイル](https://www.selenium.dev/ja/documentation/grid/configuration/toml_options/) を使用して Grid を設定することをおすすめします。 設定ファイルは読みやすく、コード管理できます。

必要に応じて TOML ファイルと CLI オプションを併用することができます。

### コマンドラインフラグ

コマンドラインフラグとしてオプションを渡すには、適切なコンポーネントを特定し以下のテンプレートのようにします。

```
java -jar selenium-server-<version>.jar <component> --<option> value
```

#### スタドアロン、最大セッションとメインポートを設定する

```
java -jar selenium-server-<version>.jar standalone --max-sessions 4 --port 4444
```

#### ハブ、新規セッションリクエストのタイムアウト、メインポートを設定し、トレースを無効にする

```
java -jar selenium-server-<version>.jar hub --session-request-timeout 500 --port 3333 --tracing false
```

#### ノード、最大 4 セッション、デバッグログ、ポート 7777, FireFox と Edge のみ

```
java -jar selenium-server-<version>.jar node --max-sessions 4 --log-level "fine" --port 7777 --driver-implementation "firefox" --driver-implementation "edge"
```

#### ディストリビューター、セッションマップ・新規セッションキューの URL を指定、バスを無効にする

```
java -jar selenium-server-<version>.jar distributor --sessions http://localhost:5556 --sessionqueue http://localhost:5559 --bind-bus false
```

#### 特定ノードにカスタム capabilities を設定する

**重要:** カスタム capabilities は全てのノードに設定される必要があります。 また全てのセッションリクエストに含まれなければいけません。

##### ハブの起動

```
java -jar selenium-server-<version>.jar hub
```

##### customcap に `true` をセットしてノード A を起動する

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":true}' --port 6161
```

##### customcap に `false` をセットしてノード B を起動する

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":false}' --port 6262
```

##### ノード A とマッチ

```java
ChromeOptions options = new ChromeOptions();
options.setCapability("gsg:customcap", true);
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

ノード B とマッチさせるにはカスタム capability を `false` に設定します。

#### Enabling Managed downloads by the Node

At times a test may need to access files that were downloaded by it on the Node. To retrieve such files, following can be done.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node with manage downloads enabled

```
java -jar selenium-server-<version>.jar node --enable-managed-downloads true
```

##### Set the capability at the test level

Tests that want to use this feature should set the capability `"se:downloadsEnabled"`to `true`

```java
options.setCapability("se:downloadsEnabled", true);
```

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

In the response the list of file names appear under the key `names`.

##### Dowloading a file:

* The endpoint to `POST` from is `/session/<sessionId>/se/files` with a payload of the form `{"name": "fileNameGoesHere}`
* The session needs to be active in order for the command to work.
* The raw response looks like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "Base64EncodedStringContentsOfDownloadedFileAsZipGoesHere"
  }
}
```

* The response blob contains two keys,

  * `filename` - The file name that was downloaded.
  * `contents` - Base64 encoded zipped contents of the file.

* The file contents are Base64 encoded and they need to be unzipped.

##### List files that can be downloaded

The below mentioned `curl` example can be used to list all the files that were downloaded by the current session in the Node, and which can be retrieved locally.

```bash
curl -X GET "http://localhost:4444/session/90c0149a-2e75-424d-857a-e78734943d4c/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

##### Retrieve a downloaded file

Assuming the downloaded file is named `Red-blue-green-channel.jpg`, and using `curl`, the file could be downloaded with the following command:

```bash
curl -H "Accept: application/json" \
-H "Content-Type: application/json; charset=utf-8" \
-X POST -d '{"name":"Red-blue-green-channel.jpg"}' \
"http://localhost:4444/session/18033434-fa4f-4d11-a7df-9e6d75920e19/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "UEsDBBQACAgIAJpagVYAAAAAAAAAAAAAAAAaAAAAUmVkLWJsAAAAAAAAAAAAUmVkLWJsdWUtZ3JlZW4tY2hhbm5lbC5qcGdQSwUGAAAAAAEAAQBIAAAAcNkAAAAA"
  }
}
```

##### Complete sample code in Java

Below is an example in Java that does the following:

* Sets the capability to indicate that the test requires automatic managing of downloaded files.
* Triggers a file download via a browser.
* Lists the files that are available for retrieval from the remote node (These are essentially files that were downloaded in the current session)
* Picks one file and downloads the file from the remote node to the local machine.

```java
import com.google.common.collect.ImmutableMap;

import org.openqa.selenium.By;
import org.openqa.selenium.io.Zip;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.io.File;
import java.net.URL;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import static org.openqa.selenium.remote.http.Contents.asJson;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.HttpMethod.GET;
import static org.openqa.selenium.remote.http.HttpMethod.POST;

public class DownloadsSample {

  public static void main(String[] args) throws Exception {
    // Assuming the Grid is running locally.
    URL gridUrl = new URL("http://localhost:4444");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("se:downloadsEnabled", true);
    RemoteWebDriver driver = new RemoteWebDriver(gridUrl, options);
    try {
      demoFileDownloads(driver, gridUrl);
    } finally {
      driver.quit();
    }
  }

	private static void demoFileDownloads(RemoteWebDriver driver, URL gridUrl) throws Exception {
		driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
		// Download the two available files on the page
		driver.findElement(By.id("file-1")).click();
		driver.findElement(By.id("file-2")).click();

		// The download happens in a remote Node, which makes it difficult to know when the file
		// has been completely downloaded. For demonstration purposes, this example uses a
		// 10-second sleep which should be enough time for a file to be downloaded.
		// We strongly recommend to avoid hardcoded sleeps, and ideally, to modify your
		// application under test, so it offers a way to know when the file has been completely
		// downloaded.
		TimeUnit.SECONDS.sleep(10);

		//This is the endpoint which will provide us with list of files to download and also to
		//let us download a specific file.
		String downloadsEndpoint = String.format("/session/%s/se/files", driver.getSessionId());

		String fileToDownload;

		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To list all files that are were downloaded on the remote node for the current session
			// we trigger GET request.
			HttpRequest request = new HttpRequest(GET, downloadsEndpoint);
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			@SuppressWarnings("unchecked")
			List<String> names = (List<String>) value.get("names");
			// Let's say there were "n" files downloaded for the current session, we would like
			// to retrieve ONLY the first file.
			fileToDownload = names.get(0);
		}

		// Now, let's download the file
		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To retrieve a specific file from one or more files that were downloaded by the current session
			// on a remote node, we use a POST request.
			HttpRequest request = new HttpRequest(POST, downloadsEndpoint);
			request.setContent(asJson(ImmutableMap.of("name", fileToDownload)));
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			// The returned map would contain 2 keys,
			// filename - This represents the name of the file (same as what was provided by the test)
			// contents - Base64 encoded String which contains the zipped file.
			String zippedContents = value.get("contents").toString();
			// The file contents would always be a zip file and has to be unzipped.
			File downloadDir = Zip.unzipToTempDir(zippedContents, "download", "");
			// Read the file contents
			File downloadedFile = Optional.ofNullable(downloadDir.listFiles()).orElse(new File[]{})[0];
			String fileContent = String.join("", Files.readAllLines(downloadedFile.toPath()));
			System.out.println("The file which was "
					+ "downloaded in the node is now available in the directory: "
					+ downloadDir.getAbsolutePath() + " and has the contents: " + fileContent);
		}
	}


}
```

最終更新 May 26, 2025: [Changing url to reference logging levels in Grid (427260bb04f)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/427260bb04fd853b881eedb2ec1031c59858bc82)

----
url: https://www.selenium.dev/ja/documentation/test_practices/encouraged/
----

# 推奨された行動

Seleniumプロジェクトからのテストに関するいくつかのガイドラインと推奨事項

「ベストプラクティス」に関するメモ：このドキュメントでは、“ベストプラクティス"というフレーズを意図的に避けています。 すべての状況に有効なアプローチはありません。 “ガイドラインとレコメンデーション"というアイデアを好みます。 これらを一通り読み、特定の環境でどのアプローチが効果的かを慎重に決定することをお勧めします。

機能テストは、多くの理由で適切に行うのが困難です。 まるでアプリケーションの状態、複雑さ、および依存関係が、テストを十分に難しくしないと思えるほど、ブラウザ（特にクロスブラウザの非互換性）を扱うのは、良いテストの作成を難しくします。

Seleniumは、機能的なユーザーインタラクションを簡単にするツールを提供しますが、適切に設計されたテストスイートの作成には役立ちません。 この章では、機能的なWebページの自動化に取り組む方法に関するアドバイス、ガイドライン、および推奨事項を提供します。

この章では、長年にわたって成功を収めてきたSeleniumの多くのユーザーの間で人気のあるソフトウェア設計パターンを記録します。

***

##### [ページオブジェクトモデル](/ja/documentation/test_practices/encouraged/page_object_models/)

##### [ドメイン固有言語（DSL）](/ja/documentation/test_practices/encouraged/domain_specific_language/)

##### [アプリケーション状態の生成](/ja/documentation/test_practices/encouraged/generating_application_state/)

##### [モック外部サービス](/ja/documentation/test_practices/encouraged/mock_external_services/)

##### [改善されたレポート](/ja/documentation/test_practices/encouraged/improved_reporting/)

##### [ロケータをうまく扱うTips](/ja/documentation/test_practices/encouraged/locators/)

どのロケータを指定すべきか、コード内でロケータをどう管理すると良いか。

##### [状態を共有しない](/ja/documentation/test_practices/encouraged/avoid_sharing_state/)

##### [テストの独立性](/ja/documentation/test_practices/encouraged/test_independency/)

##### [Fluent APIの使用を検討する](/ja/documentation/test_practices/encouraged/consider_using_a_fluent_api/)

##### [テストごとに新しいブラウザを起動する](/ja/documentation/test_practices/encouraged/fresh_browser_per_test/)

----
url: https://www.selenium.dev/documentation/grid/configuration/help/
----

# Configuration help

```shell
java -jar selenium-server-<version>.jar info config
```

### Security

To get details on setting up the Grid servers for secure communication and node registration:

```shell
java -jar selenium-server-<version>.jar info security
```

### Session Map setup

By default, Grid uses a local session map to store session information. Grid supports additional storage options like Redis and JDBC - SQL supported databases. To set up different session storage, use the following command to get setup steps:

```shell
java -jar selenium-server-<version>.jar info sessionmap
```

### Setting up tracing with OpenTelemetry and Jaeger

By default, tracing is enabled. To export traces and visualize them via Jaeger, use the following command for instructions:

```shell
java -jar selenium-server-<version>.jar info tracing
```

## List the Selenium Grid commands

```shell
java -jar selenium-server-<version>.jar --config-help
```

It will show all the available commands and description for each one.

## Component help commands

Pass –help config option after the Selenium role to get component-specific config information.

### Standalone

```shell
java -jar selenium-server-<version>.jar standalone --help
```

### Hub

```shell
java -jar selenium-server-<version>.jar hub --help
```

### Sessions

```shell
java -jar selenium-server-<version>.jar sessions --help
```

### New Session Queue

```shell
java -jar selenium-server-<version>.jar sessionqueue --help
```

### Distributor

```shell
java -jar selenium-server-<version>.jar distributor --help
```

### Router

```shell
java -jar selenium-server-<version>.jar router --help
```

### Node

```shell
java -jar selenium-server-<version>.jar node --help
```

----
url: https://www.selenium.dev/documentation/webdriver/bidi/w3c/
----

# BiDirectional API (W3C compliant)

Examples of working with Chrome DevTools Protocol in Selenium. CDP support is temporary until WebDriver BiDi has been implemented.

The following list of APIs will be growing as the [WebDriver BiDirectional Protocol](https://w3c.github.io/webdriver-bidi/) 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](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=\&template=feature.md).

***

##### [Browsing Context](/documentation/webdriver/bidi/w3c/browsing_context/)

##### [Input](/documentation/webdriver/bidi/w3c/input/)

##### [Log](/documentation/webdriver/bidi/w3c/log/)

##### [Network](/documentation/webdriver/bidi/w3c/network/)

##### [Script](/documentation/webdriver/bidi/w3c/script/)

----
url: https://www.selenium.dev/documentation/ie_driver_server/internals/
----

----
url: https://www.selenium.dev/documentation/legacy/developers/
----

# Legacy developer documentation

Information of interest to developers of Selenium

***

##### [Crazy Fun Build Tool](/documentation/legacy/developers/crazy_fun_build/)

The original Selenium Build Tool that grew from nothing to be extremely unwieldy, making it both crazy and “fun” to work with.

##### [Buck Build Tool](/documentation/legacy/developers/buck/)

Buck is a build tool from Facebook that we were working with to replace Crazy fun. We have since replaced it with [Bazel](https://bazel.build/).

##### [Adding new drivers to Selenium 2 code](/documentation/legacy/developers/drivers/)

Instructions for how to create tests for new drivers for Selenium 2.

##### [Selenium's Continuous Integration Implementation](/documentation/legacy/developers/ci_tool/)

We used to have a Jenkins CI tool that executed unit tests and ran integration tests on Sauce Labs. We moved all of the tests to Travis, and now execute everything with Github Actions.

##### [Google Summer of Code 2011](/documentation/legacy/developers/summer_of_code/)

Selenium encouraged users to take advantage of this program.

##### [Developer Tips](/documentation/legacy/developers/tips/)

Details on how to execute Selenium Test Suite with Crazy Fun.

##### [Snapshot of Roadmaps for Selenium Releases](/documentation/legacy/developers/roadmap/)

The list of plans and things to accomplish before a release

----
url: https://www.selenium.dev/documentation/webdriver/drivers/options/
----

# Browser Options

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L73-74)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L79-80)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L11)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L80-82)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L86-88)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options.browser_version = 'latest'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L40)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## pageLoadStrategy

Three types of page load strategies are available.

The page load strategy queries the [document.readyState](//developer.mozilla.org/en-US/docs/Web/API/Document/readyState) as described in the table below:

| Strategy | Ready State | Notes                                                                     |
| -------- | ----------- | ------------------------------------------------------------------------- |
| normal   | complete    | Used by default, waits for all resources to download                      |
| eager    | interactive | DOM access is ready, but other resources like images may still be loading |
| none     | Any         | Does not block WebDriver at all                                           |

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L21-L23)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L7-9)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L13-14)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L11-L12)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L28-L34)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L34-L36)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L15-L17)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L29-30)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L20-L21)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L8-L14)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L47-L49)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L23-L25)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
        public void SetPageLoadStrategyNone()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L41-42)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L29-L30)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L18-L24)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L88-L90)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L94-96)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L38-L39)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L60-L61)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L101-103)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L51-L52)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L38-L41)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L96-L98)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L30-32)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L114-L115)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L111-L113)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L37-39)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L105-L106)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L126-L128)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L44-46)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L96-L97)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L141-L142)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L51-53)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L60-L61)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L151-L152)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L58-60)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L69-L70)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L163-L164)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L65-67)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L78-L79)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class ProxyTest {
  public static void main(String[] args) {
    Proxy proxy = new Proxy();
    proxy.setHttpProxy("<HOST:PORT>");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("proxy", proxy);
    WebDriver driver = new ChromeDriver(options);
    driver.get("https://www.google.com/");
    driver.manage().window().maximize();
    driver.quit();
  }
}
```

```py
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L72-74)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

public class ProxyTest{
public static void Main() {
ChromeOptions options = new ChromeOptions();
Proxy proxy = new Proxy();
proxy.Kind = ProxyKind.Manual;
proxy.IsAutoDetect = false;
proxy.SslProxy = "<HOST:PORT>";
options.Proxy = proxy;
options.AddArgument("ignore-certificate-errors");
IWebDriver driver = new ChromeDriver(options);
driver.Navigate().GoToUrl("https://www.selenium.dev/");
}
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L87-L88)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```javascript
let webdriver = require('selenium-webdriver');
let chrome = require('selenium-webdriver/chrome');
let proxy = require('selenium-webdriver/proxy');
let opts = new chrome.Options();

(async function example() {
opts.setProxy(proxy.manual({http: '<HOST:PORT>'}));
let driver = new webdriver.Builder()
.forBrowser('chrome')
.setChromeOptions(opts)
.build();
try {
await driver.get("https://selenium.dev");
}
finally {
await driver.quit();
}
}());
```

```kotlin
import org.openqa.selenium.Proxy
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

class proxyTest {
fun main() {

        val proxy = Proxy()
        proxy.setHttpProxy("<HOST:PORT>")
        val options = ChromeOptions()
        options.setCapability("proxy", proxy)
        val driver: WebDriver = ChromeDriver(options)
        driver["https://www.google.com/"]
        driver.manage().window().maximize()
        driver.quit()
    }
}
```

----
url: https://www.selenium.dev/ja/documentation/webdriver/bidi/w3c/browsing_context/
----

# Browsing Context

```java
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L44-L47)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L33-L35)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

    @Test
    void testNavigateToAUrl() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L58-L61)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L48-L50)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L37-L41)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L25-L28)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L50-L55)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L40-L43)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        Assertions.assertNotNull(browsingContext.getId());
        Assertions.assertNotNull(info.getNavigationId());
        Assertions.assertTrue(info.getUrl().contains("/bidi/logEntryAdded.html"));
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L64-L69)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L55-L58)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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"));
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L72-L80)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L67)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L83-L92)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L79-L82)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        Assertions.assertTrue(info.getChildren().get(0).getUrl().contains("formPage.html"));
    }

    @Test
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L95-L108)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    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()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L90-L96)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    }

    @Test
    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());
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L111-L123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L103-L109)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window2.close();

        Assertions.assertThrows(BiDiException.class, window2::getTree);
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L126-L133)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.20.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.20.0.0)

```js
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L426-L431)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext tab2 = new BrowsingContext(driver, WindowType.TAB);

        tab2.close();

        Assertions.assertThrows(BiDiException.class, tab2::getTree);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L136-L153)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L115-L118)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L157-L161)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L192-L194)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```js
    await window1.activate()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L204)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L169-L173)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.reload(undefined, 'complete')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L351)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    @Test
    void testDismissUserPromptWithText() {
        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";
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L220-L228)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.handleUserPrompt(true, userText)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L301)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        driver.get("https://www.selenium.dev/selenium/web/coordinates_tests/simple_page.html");

        WebElement element = driver.findElement(By.id("box"));
        Rectangle elementRectangle = element.getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L248-L252)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const response = await browsingContext.captureScreenshot()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L362)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    }

    @Test
    void textCaptureElementScreenshot() {
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L259-L268)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L165-L169)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L275-L280)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const response = await browsingContext.captureElementScreenshot(elementId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L184)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L304-L307)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.setViewport(250, 300)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L335)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L317-L322)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    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'],
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L145-L157)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        wait.until(visibilityOfElementLocated(By.id("imageButton"))).submit();
        wait.until(titleIs("We Arrive Here"));

        browsingContext.back();
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L330-L336)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.back()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L396)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L342-L352)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.forward()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L420)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L359-L365)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.traverseHistory(-1)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L378)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L34-L41)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L23-L28)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L54-L63)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L53-L62)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L81-88)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L70-L78)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L97-104)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L113-123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L86-L97)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L113-123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L150-163)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L170-L181)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0.0)

```js
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L105-L113)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

----
url: https://www.selenium.dev/ja/documentation/webdriver/troubleshooting/errors/driver_location/
----

# Unable to Locate Driver Error

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.bash_profile
source ~/.bash_profile
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Terminal and execute:

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.zshenv
source ~/.zshenv
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Command Prompt and execute:

```shell
echo %PATH%
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
setx PATH "%PATH%;C:\WebDriver\bin"
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver.exe --version
```

| ブラウザー             | サポートするOS                    | 維持管理機関           | ダウンロード                                                                       | イシュートラッカー                                                        |
| ----------------- | --------------------------- | ---------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| Chromium/Chrome   | Windows/macOS/Linux         | Google           | [Downloads](//chromedriver.chromium.org/downloads)                           | [Issues](//bugs.chromium.org/p/chromedriver/issues/list)         |
| Firefox           | Windows/macOS/Linux         | Mozilla          | [Downloads](//github.com/mozilla/geckodriver/releases)                       | [Issues](//github.com/mozilla/geckodriver/issues)                |
| Edge              | Windows/macOS/Linux         | Microsoft        | [Downloads](//developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/) | [Issues](https://github.com/MicrosoftDocs/edge-developer/issues) |
| Internet Explorer | Windows                     | Selenium Project | [Downloads](/downloads)                                                      | [Issues](//github.com/SeleniumHQ/selenium/labels/D-IE)           |
| Safari            | macOS High Sierra and newer | Apple            | Built in                                                                     | [Issues](//bugreport.apple.com/logon)                            |

Note: The Opera driver no longer works with the latest functionality of Selenium and is currently officially unsupported.

----
url: https://www.selenium.dev/documentation/webdriver/bidi/w3c/input/
----

# Input

```java
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ActionsTest.java#L41-L44)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ActionsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Input;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.interactions.Actions;

class ActionsTest extends BaseTest {
    private Input input;

    private String windowHandle;

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        windowHandle = driver.getWindowHandle();
        input = new Input(driver);
    }

    @Test
    void canPerformInputActions() {
        driver.get("https://www.selenium.dev/selenium/web/formSelectionPage.html");

        List<WebElement> options = driver.findElements(By.tagName("option"));

        Actions actions = new Actions(driver);
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());

        WebElement showButton = driver.findElement(By.name("showselected"));
        showButton.click();

        WebElement resultElement = driver.findElement(By.id("result"));
        Assertions.assertTrue(resultElement.getText().contains("roquefort parmigiano cheddar"));
        }

    @Test
    void canPerformReleaseAction() {
        driver.get("https://www.selenium.dev/selenium/web/bidi/release_action.html");

        WebElement inputTextBox = driver.findElement(By.id("keys"));

        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);

        List<Map<String, Object>> events =
                (List<Map<String, Object>>)
                        ((JavascriptExecutor) driver).executeScript("return allEvents.events");
        Assertions.assertEquals("KeyB", events.get(0).get("code"));
        Assertions.assertEquals("KeyA", events.get(1).get("code"));
        }
    }
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/input.spec.js#L27-L29)

##### /examples/javascript/test/bidirectional/input.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, Key, Builder} = require("selenium-webdriver")
const Input = require('selenium-webdriver/bidi/input')

describe('Input module', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can perform input action', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/formSelectionPage.html')

    let options = await driver.findElements(By.tagName('option'))

    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)

    let showButton = await driver.findElement(By.name('showselected'))
    showButton.click()

    let resultElement = await driver.findElement(By.id('result'))
    await resultElement.getText().then(function (text) {
      assert(text.includes('oquefort parmigiano cheddar'), `text is: ${text}`)
    })
  })

  it('can execute release in browsing context', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/bidi/release_action.html')

    let inputTextBox = await driver.findElement(By.id('keys'))

    await driver.executeScript('arguments[0].focus()', inputTextBox)

    const actions = driver.actions().keyDown('a').keyDown('b').getSequences()

    await input.perform(browsingContextId, actions)

    await driver.executeScript('resetEvents()')

    await input.release(browsingContextId)

    const events = await driver.executeScript('return allEvents.events')

    assert.strictEqual(events[0].code, 'KeyB')
    assert.strictEqual(events[1].code, 'KeyA')
  })
})
```

```java
        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ActionsTest.java#L59-L65)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ActionsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Input;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.interactions.Actions;

class ActionsTest extends BaseTest {
    private Input input;

    private String windowHandle;

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        windowHandle = driver.getWindowHandle();
        input = new Input(driver);
    }

    @Test
    void canPerformInputActions() {
        driver.get("https://www.selenium.dev/selenium/web/formSelectionPage.html");

        List<WebElement> options = driver.findElements(By.tagName("option"));

        Actions actions = new Actions(driver);
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());

        WebElement showButton = driver.findElement(By.name("showselected"));
        showButton.click();

        WebElement resultElement = driver.findElement(By.id("result"));
        Assertions.assertTrue(resultElement.getText().contains("roquefort parmigiano cheddar"));
        }

    @Test
    void canPerformReleaseAction() {
        driver.get("https://www.selenium.dev/selenium/web/bidi/release_action.html");

        WebElement inputTextBox = driver.findElement(By.id("keys"));

        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);

        List<Map<String, Object>> events =
                (List<Map<String, Object>>)
                        ((JavascriptExecutor) driver).executeScript("return allEvents.events");
        Assertions.assertEquals("KeyB", events.get(0).get("code"));
        Assertions.assertEquals("KeyA", events.get(1).get("code"));
        }
    }
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await input.release(browsingContextId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/input.spec.js#L55)

##### /examples/javascript/test/bidirectional/input.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, Key, Builder} = require("selenium-webdriver")
const Input = require('selenium-webdriver/bidi/input')

describe('Input module', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can perform input action', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/formSelectionPage.html')

    let options = await driver.findElements(By.tagName('option'))

    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)

    let showButton = await driver.findElement(By.name('showselected'))
    showButton.click()

    let resultElement = await driver.findElement(By.id('result'))
    await resultElement.getText().then(function (text) {
      assert(text.includes('oquefort parmigiano cheddar'), `text is: ${text}`)
    })
  })

  it('can execute release in browsing context', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/bidi/release_action.html')

    let inputTextBox = await driver.findElement(By.id('keys'))

    await driver.executeScript('arguments[0].focus()', inputTextBox)

    const actions = driver.actions().keyDown('a').keyDown('b').getSequences()

    await input.perform(browsingContextId, actions)

    await driver.executeScript('resetEvents()')

    await input.release(browsingContextId)

    const events = await driver.executeScript('return allEvents.events')

    assert.strictEqual(events[0].code, 'KeyB')
    assert.strictEqual(events[1].code, 'KeyA')
  })
})
```

----
url: https://www.selenium.dev/documentation/legacy/selenium_1/
----

# Selenium RC (Selenium 1)

```shell
    java -jar selenium-server-standalone-<version-number>.jar
```

This can be simplified by creating a batch or shell executable file (.bat on Windows and .sh on Linux) containing the command above. Then make a shortcut to that executable on your desktop and simply double-click the icon to start the server.

For the server to run you’ll need Java installed and the PATH environment variable correctly configured to run it from the console. You can check that you have Java correctly installed by running the following on a console.

```shell
       java -version
```

|                   |                            |             |
| ----------------- | -------------------------- | ----------- |
| open              | /                          |             |
| type              | q                          | selenium rc |
| clickAndWait      | btnG                       |             |
| assertTextPresent | Results \* for selenium rc |             |

Note: This example would work with the Google search page <http://www.google.com>

### Selenese as Programming Code

Here is the test script exported (via Selenium-IDE) to each of the supported programming languages. If you have at least basic knowledge of an object- oriented programming language, you will understand how Selenium runs Selenese commands by reading one of these examples. To see an example in a specific language, select one of these buttons.

#### CSharp

```csharp

        using System;
        using System.Text;
        using System.Text.RegularExpressions;
        using System.Threading;
        using NUnit.Framework;
        using Selenium;

        namespace SeleniumTests
        {
            [TestFixture]
            public class NewTest
            {
                private ISelenium selenium;
                private StringBuilder verificationErrors;
                
                [SetUp]
                public void SetupTest()
                {
                    selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
                    selenium.Start();
                    verificationErrors = new StringBuilder();
                }
                
                [TearDown]
                public void TeardownTest()
                {
                    try
                    {
                        selenium.Stop();
                    }
                    catch (Exception)
                    {
                        // Ignore errors if unable to close the browser
                    }
                    Assert.AreEqual("", verificationErrors.ToString());
                }
                
                [Test]
                public void TheNewTest()
                {
                    selenium.Open("/");
                    selenium.Type("q", "selenium rc");
                    selenium.Click("btnG");
                    selenium.WaitForPageToLoad("30000");
                    Assert.AreEqual("selenium rc - Google Search", selenium.GetTitle());
                }
            }
        }
```

#### Java

```java
      
	  /** Add JUnit framework to your classpath if not already there 
	   *  for this example to work
	  */
      package com.example.tests;

      import com.thoughtworks.selenium.*;
      import java.util.regex.Pattern;

      public class NewTest extends SeleneseTestCase {
          public void setUp() throws Exception {
              setUp("http://www.google.com/", "*firefox");
          }
            public void testNew() throws Exception {
                selenium.open("/");
                selenium.type("q", "selenium rc");
                selenium.click("btnG");
                selenium.waitForPageToLoad("30000");
                assertTrue(selenium.isTextPresent("Results * for selenium rc"));
          }
      }
```

#### Php

```php
      <?php

      require_once 'PHPUnit/Extensions/SeleniumTestCase.php';

      class Example extends PHPUnit_Extensions_SeleniumTestCase
      {
        function setUp()
        {
          $this->setBrowser("*firefox");
          $this->setBrowserUrl("http://www.google.com/");
        }

        function testMyTestCase()
        {
          $this->open("/");
          $this->type("q", "selenium rc");
          $this->click("btnG");
          $this->waitForPageToLoad("30000");
          $this->assertTrue($this->isTextPresent("Results * for selenium rc"));
        }
      }
      ?>
```

#### Python

```python

     from selenium import selenium
      import unittest, time, re

      class NewTest(unittest.TestCase):
          def setUp(self):
              self.verificationErrors = []
              self.selenium = selenium("localhost", 4444, "*firefox",
                      "http://www.google.com/")
              self.selenium.start()
         
          def test_new(self):
              sel = self.selenium
              sel.open("/")
              sel.type("q", "selenium rc")
              sel.click("btnG")
              sel.wait_for_page_to_load("30000")
              self.failUnless(sel.is_text_present("Results * for selenium rc"))
         
          def tearDown(self):
              self.selenium.stop()
              self.assertEqual([], self.verificationErrors)
```

#### Ruby

```ruby

      require "selenium/client"
      require "test/unit"

      class NewTest < Test::Unit::TestCase
        def setup
          @verification_errors = []
          if $selenium
            @selenium = $selenium
          else
            @selenium =  Selenium::Client::Driver.new("localhost", 4444, "*firefox", "http://www.google.com/", 60);
            @selenium.start
          end
          @selenium.set_context("test_new")
        end

        def teardown
          @selenium.stop unless $selenium
          assert_equal [], @verification_errors
        end

        def test_new
          @selenium.open "/"
          @selenium.type "q", "selenium rc"
          @selenium.click "btnG"
          @selenium.wait_for_page_to_load "30000"
          assert @selenium.is_text_present("Results * for selenium rc")
        end
      end
```

```java
    selenium = new DefaultSelenium("localhost", 4444, "*iehta", "http://www.google.com/");
```

The Selenium-IDE generated code will look like this. This example has comments added manually for additional clarity.

```java
   package com.example.tests;
   // We specify the package of our tests

   import com.thoughtworks.selenium.*;
   // This is the driver's import. You'll use this for instantiating a
   // browser and making it do what you need.

   import java.util.regex.Pattern;
   // Selenium-IDE add the Pattern module because it's sometimes used for 
   // regex validations. You can remove the module if it's not used in your 
   // script.

   public class NewTest extends SeleneseTestCase {
   // We create our Selenium test case

         public void setUp() throws Exception {
           setUp("http://www.google.com/", "*firefox");
                // We instantiate and start the browser
         }

         public void testNew() throws Exception {
              selenium.open("/");
              selenium.type("q", "selenium rc");
              selenium.click("btnG");
              selenium.waitForPageToLoad("30000");
              assertTrue(selenium.isTextPresent("Results * for selenium rc"));
              // These are the real test steps
        }
   }
```

### `C#`

The .NET Client Driver works with Microsoft.NET. It can be used with any .NET testing framework like NUnit or the Visual Studio 2005 Team System.

Selenium-IDE assumes you will use NUnit as your testing framework. You can see this in the generated code below. It includes the *using* statement for NUnit along with corresponding NUnit attributes identifying the role for each member function of the test class.

You will probably have to rename the test class from “NewTest” to something of your own choosing. Also, you will need to change the browser-open parameters in the statement:

```csharp
    selenium = new DefaultSelenium("localhost", 4444, "*iehta", "http://www.google.com/");
```

The generated code will look similar to this.

```csharp

    using System;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading;
    using NUnit.Framework;
    using Selenium;
    
    namespace SeleniumTests

    {
        [TestFixture]

        public class NewTest

        {
        private ISelenium selenium;

        private StringBuilder verificationErrors;

        [SetUp]

        public void SetupTest()

        {
            selenium = new DefaultSelenium("localhost", 4444, "*iehta",
            "http://www.google.com/");

            selenium.Start();

            verificationErrors = new StringBuilder();
        }

        [TearDown]

        public void TeardownTest()
        {
            try
            {
            selenium.Stop();
            }

            catch (Exception)
            {
            // Ignore errors if unable to close the browser
            }

            Assert.AreEqual("", verificationErrors.ToString());
        }
        [Test]

        public void TheNewTest()
        {
            // Open Google search engine.        
            selenium.Open("http://www.google.com/"); 
            
            // Assert Title of page.
            Assert.AreEqual("Google", selenium.GetTitle());
            
            // Provide search term as "Selenium OpenQA"
            selenium.Type("q", "Selenium OpenQA");
            
            // Read the keyed search term and assert it.
            Assert.AreEqual("Selenium OpenQA", selenium.GetValue("q"));
            
            // Click on Search button.
            selenium.Click("btnG");
            
            // Wait for page to load.
            selenium.WaitForPageToLoad("5000");
            
            // Assert that "www.openqa.org" is available in search results.
            Assert.IsTrue(selenium.IsTextPresent("www.openqa.org"));
            
            // Assert that page title is - "Selenium OpenQA - Google Search"
            Assert.AreEqual("Selenium OpenQA - Google Search", 
                         selenium.GetTitle());
        }
        }
    }
```

You can allow NUnit to manage the execution of your tests. Or alternatively, you can write a simple `main()` program that instantiates the test object and runs each of the three methods, `SetupTest()`, `TheNewTest()`, and `TeardownTest()` in turn.

### Python

Pyunit is the test framework to use for Python.

The basic test structure is:

```python

   from selenium import selenium
   # This is the driver's import.  You'll use this class for instantiating a
   # browser and making it do what you need.

   import unittest, time, re
   # This are the basic imports added by Selenium-IDE by default.
   # You can remove the modules if they are not used in your script.

   class NewTest(unittest.TestCase):
   # We create our unittest test case

       def setUp(self):
           self.verificationErrors = []
           # This is an empty array where we will store any verification errors
           # we find in our tests

           self.selenium = selenium("localhost", 4444, "*firefox",
                   "http://www.google.com/")
           self.selenium.start()
           # We instantiate and start the browser

       def test_new(self):
           # This is the test code.  Here you should put the actions you need
           # the browser to do during your test.
            
           sel = self.selenium
           # We assign the browser to the variable "sel" (just to save us from 
           # typing "self.selenium" each time we want to call the browser).
            
           sel.open("/")
           sel.type("q", "selenium rc")
           sel.click("btnG")
           sel.wait_for_page_to_load("30000")
           self.failUnless(sel.is_text_present("Results * for selenium rc"))
           # These are the real test steps

       def tearDown(self):
           self.selenium.stop()
           # we close the browser (I'd recommend you to comment this line while
           # you are creating and debugging your tests)

           self.assertEqual([], self.verificationErrors)
           # And make the test fail if we found that any verification errors
           # were found
```

### Ruby

Old (pre 2.0) versions of Selenium-IDE generate Ruby code that requires the old Selenium gem. Therefore, it is advisable to update any Ruby scripts generated by the IDE as follows:

1. On line 1, change `require "selenium"` to `require "selenium/client"`

2. On line 11, change `Selenium::SeleniumDriver.new` to `Selenium::Client::Driver.new`

You probably also want to change the class name to something more informative than “Untitled,” and change the test method’s name to something other than “test\_untitled.”

Here is a simple example created by modifying the Ruby code generated by Selenium IDE, as described above.

```ruby

   # load the Selenium-Client gem
   require "selenium/client"

   # Load Test::Unit, Ruby's default test framework.
   # If you prefer RSpec, see the examples in the Selenium-Client
   # documentation.
   require "test/unit"

   class Untitled < Test::Unit::TestCase

     # The setup method is called before each test.
     def setup

       # This array is used to capture errors and display them at the
       # end of the test run.
       @verification_errors = []

       # Create a new instance of the Selenium-Client driver.
       @selenium = Selenium::Client::Driver.new \
         :host => "localhost",
         :port => 4444,
         :browser => "*chrome",
         :url => "http://www.google.com/",
         :timeout_in_second => 60

       # Start the browser session
       @selenium.start

       # Print a message in the browser-side log and status bar
       # (optional).
       @selenium.set_context("test_untitled")

     end

     # The teardown method is called after each test.
     def teardown

       # Stop the browser session.
       @selenium.stop

       # Print the array of error messages, if any.
       assert_equal [], @verification_errors
     end

     # This is the main body of your test.
     def test_untitled
     
       # Open the root of the site we specified when we created the
       # new driver instance, above.
       @selenium.open "/"

       # Type 'selenium rc' into the field named 'q'
       @selenium.type "q", "selenium rc"

       # Click the button named "btnG"
       @selenium.click "btnG"

       # Wait for the search results page to load.
       # Note that we don't need to set a timeout here, because that
       # was specified when we created the new driver instance, above.
       @selenium.wait_for_page_to_load

       begin

          # Test whether the search results contain the expected text.
	  # Notice that the star (*) is a wildcard that matches any
	  # number of characters.
	  assert @selenium.is_text_present("Results * for selenium rc")
	  
       rescue Test::Unit::AssertionFailedError
       
          # If the assertion fails, push it onto the array of errors.
	  @verification_errors << $!

       end
     end
   end
```

```csharp
      selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
      selenium.Start();
```

#### Java

```java

      setUp("http://www.google.com/", "*firefox");
```

#### Perl

```perl
      my $sel = Test::WWW::Selenium->new( host => "localhost", 
                                          port => 4444, 
                                          browser => "*firefox", 
                                          browser_url => "http://www.google.com/" );
```

#### Php

```php
      $this->setBrowser("*firefox");
      $this->setBrowserUrl("http://www.google.com/");
```

#### Python

```python
      self.selenium = selenium("localhost", 4444, "*firefox",
                               "http://www.google.com/")
      self.selenium.start()
```

#### Ruby

```ruby
      @selenium = Selenium::ClientDriver.new("localhost", 4444, "*firefox", "http://www.google.com/", 10000);
      @selenium.start
```

```
    selenium.type("field-id","string to type")
```

|                   |                              |               |
| ----------------- | ---------------------------- | ------------- |
| open              | /                            |               |
| type              | q                            | selenium rc   |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium rc   |               |
| type              | q                            | selenium ide  |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium ide  |               |
| type              | q                            | selenium grid |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium grid |               |

The code has been repeated to run the same steps 3 times. But multiple copies of the same code is not good program practice because it’s more work to maintain. By using a programming language, we can iterate over the search results for a more flexible and maintainable solution.

#### In `C#`

```csharp
   // Collection of String values.
   String[] arr = {"ide", "rc", "grid"};    
        
   // Execute loop for each String in array 'arr'.
   foreach (String s in arr) {
       sel.open("/");
       sel.type("q", "selenium " +s);
       sel.click("btnG");
       sel.waitForPageToLoad("30000");
       assertTrue("Expected text: " +s+ " is missing on page."
       , sel.isTextPresent("Results * for selenium " + s));
    }
```

### Condition Statements

To illustrate using conditions in tests we’ll start with an example. A common problem encountered while running Selenium tests occurs when an expected element is not available on page. For example, when running the following line:

```
   selenium.type("q", "selenium " +s);
```

If element ‘q’ is not on the page then an exception is thrown:

```java
   com.thoughtworks.selenium.SeleniumException: ERROR: Element q not found
```

This can cause your test to abort. For some tests that’s what you want. But often that is not desirable as your test script has many other subsequent tests to perform.

A better approach is to first validate whether the element is really present and then take alternatives when it it is not. Let’s look at this using Java.

```java
   // If element is available on page then perform type operation.
   if(selenium.isElementPresent("q")) {
       selenium.type("q", "Selenium rc");
   } else {
       System.out.printf("Element: " +q+ " is not available on page.")
   }
```

The advantage of this approach is to continue with test execution even if some UI elements are not available on page.

### Executing JavaScript from Your Test

JavaScript comes very handy in exercising an application which is not directly supported by Selenium. The **getEval** method of Selenium API can be used to execute JavaScript from Selenium RC.

Consider an application having check boxes with no static identifiers. In this case one could evaluate JavaScript from Selenium RC to get ids of all check boxes and then exercise them.

```java
   public static String[] getAllCheckboxIds () { 
		String script = "var inputId  = new Array();";// Create array in java script.
		script += "var cnt = 0;"; // Counter for check box ids.  
		script += "var inputFields  = new Array();"; // Create array in java script.
		script += "inputFields = window.document.getElementsByTagName('input');"; // Collect input elements.
		script += "for(var i=0; i<inputFields.length; i++) {"; // Loop through the collected elements.
		script += "if(inputFields[i].id !=null " +
		"&& inputFields[i].id !='undefined' " +
		"&& inputFields[i].getAttribute('type') == 'checkbox') {"; // If input field is of type check box and input id is not null.
		script += "inputId[cnt]=inputFields[i].id ;" + // Save check box id to inputId array.
		"cnt++;" + // increment the counter.
		"}" + // end of if.
		"}"; // end of for.
		script += "inputId.toString();" ;// Convert array in to string.			
		String[] checkboxIds = selenium.getEval(script).split(","); // Split the string.
		return checkboxIds;
    }
```

To count number of images on a page:

```java
   selenium.getEval("window.document.images.length;");
```

Remember to use window object in case of DOM expressions as by default selenium window is referred to, not the test window.

## Server Options

When the server is launched, command line options can be used to change the default server behaviour.

Recall, the server is started by running the following.

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar
```

To see the list of options, run the server with the `-h` option.

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar -h
```

You’ll see a list of all the options you can use with the server and a brief description of each. The provided descriptions will not always be enough, so we’ve provided explanations for some of the more important options.

### Proxy Configuration

If your AUT is behind an HTTP proxy which requires authentication then you should configure http.proxyHost, http.proxyPort, http.proxyUser and http.proxyPassword using the following command.

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar -Dhttp.proxyHost=proxy.com -Dhttp.proxyPort=8080 -Dhttp.proxyUser=username -Dhttp.proxyPassword=password
```

### Multi-Window Mode

If you are using Selenium 1.0 you can probably skip this section, since multiwindow mode is the default behavior. However, prior to version 1.0, Selenium by default ran the application under test in a sub frame as shown here.

Some applications didn’t run correctly in a sub frame, and needed to be loaded into the top frame of the window. The multi-window mode option allowed the AUT to run in a separate window rather than in the default frame where it could then have the top frame it required.

For older versions of Selenium you must specify multiwindow mode explicitly with the following option:

```bash
   -multiwindow 
```

As of Selenium RC 1.0, if you want to run your test within a single frame (i.e. using the standard for earlier Selenium versions) you can state this to the Selenium Server using the option

```bash
   -singlewindow 
```

### Specifying the Firefox Profile

Firefox will not run two instances simultaneously unless you specify a separate profile for each instance. Selenium RC 1.0 and later runs in a separate profile automatically, so if you are using Selenium 1.0, you can probably skip this section. However, if you’re using an older version of Selenium or if you need to use a specific profile for your tests (such as adding an https certificate or having some addons installed), you will need to explicitly specify the profile.

First, to create a separate Firefox profile, follow this procedure. Open the Windows Start menu, select “Run”, then type and enter one of the following:

```bash
   firefox.exe -profilemanager 
```

```bash
   firefox.exe -P 
```

Create the new profile using the dialog. Then when you run Selenium Server, tell it to use this new Firefox profile with the server command-line option *-firefoxProfileTemplate* and specify the path to the profile using its filename and directory path.

```bash
   -firefoxProfileTemplate "path to the profile" 
```

**Warning**: Be sure to put your profile in a new folder separate from the default!!! The Firefox profile manager tool will delete all files in a folder if you delete a profile, regardless of whether they are profile files or not.

More information about Firefox profiles can be found in [Mozilla’s Knowledge Base](http://support.mozilla.com/en/kb/Managing+profiles)

### Run Selenese Directly Within the Server Using -htmlSuite

You can run Selenese html files directly within the Selenium Server by passing the html file to the server’s command line. For instance:

```bash
   java -jar selenium-server-standalone-<version-number>.jar -htmlSuite "*firefox" 
   "http://www.google.com" "c:\absolute\path\to\my\HTMLSuite.html" 
   "c:\absolute\path\to\my\results.html"
```

This will automatically launch your HTML suite, run all the tests and save a nice HTML report with the results.

*Note:* When using this option, the server will start the tests and wait for a specified number of seconds for the test to complete; if the test doesn’t complete within that amount of time, the command will exit with a non-zero exit code and no results file will be generated.

This command line is very long so be careful when you type it. Note this requires you to pass in an HTML Selenese suite, not a single test. Also be aware the -htmlSuite option is incompatible with `-interactive` You cannot run both at the same time.

### Selenium Server Logging

#### Server-Side Logs

When launching Selenium server the **-log** option can be used to record valuable debugging information reported by the Selenium Server to a text file.

```bash
   java -jar selenium-server-standalone-<version-number>.jar -log selenium.log
```

This log file is more verbose than the standard console logs (it includes DEBUG level logging messages). The log file also includes the logger name, and the ID number of the thread that logged the message. For example:

```bash
   20:44:25 DEBUG [12] org.openqa.selenium.server.SeleniumDriverResourceHandler - 
   Browser 465828/:top frame1 posted START NEW
```

The message format is

```bash
   TIMESTAMP(HH:mm:ss) LEVEL [THREAD] LOGGER - MESSAGE
```

This message may be multiline.

#### Browser-Side Logs

JavaScript on the browser side (Selenium Core) also logs important messages; in many cases, these can be more useful to the end-user than the regular Selenium Server logs. To access browser-side logs, pass the **-browserSideLog** argument to the Selenium Server.

```bash
   java -jar selenium-server-standalone-<version-number>.jar -browserSideLog
```

**-browserSideLog** must be combined with the **-log** argument, to log browserSideLogs (as well as all other DEBUG level logging messages) to a file.

## Specifying the Path to a Specific Browser

You can specify to Selenium RC a path to a specific browser. This is useful if you have different versions of the same browser and you wish to use a specific one. Also, this is used to allow your tests to run against a browser not directly supported by Selenium RC. When specifying the run mode, use the \*custom specifier followed by the full path to the browser’s executable:

```bash
   *custom <path to browser> 
```

```bash
   cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\MyBrowser.exe&2=http://www.google.com
```

### Running Tests with Different Browser Configurations

Normally Selenium RC automatically configures the browser, but if you launch the browser using the “\*custom” run mode, you can force Selenium RC to launch the browser as-is, without using an automatic configuration.

For example, you can launch Firefox with a custom configuration like this:

```bash
   cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\firefox.exe&2=http://www.google.com
```

Note that when launching the browser this way, you must manually configure the browser to use the Selenium Server as a proxy. Normally this just means opening your browser preferences and specifying “localhost:4444” as an HTTP proxy, but instructions for this can differ radically from browser to browser. Consult your browser’s documentation for details.

Be aware that Mozilla browsers can vary in how they start and stop. One may need to set the MOZ\_NO\_REMOTE environment variable to make Mozilla browsers behave a little more predictably. Unix users should avoid launching the browser using a shell script; it’s generally better to use the binary executable (e.g. firefox-bin) directly.

## Troubleshooting Common Problems

When getting started with Selenium RC there’s a few potential problems that are commonly encountered. We present them along with their solutions here.

### Unable to Connect to Server

When your test program cannot connect to the Selenium Server, Selenium throws an exception in your test program. It should display this message or a similar one:

```bash
    "Unable to connect to remote server (Inner Exception Message: 
	No connection could be made because the target machine actively 
	refused it )"
    
	(using .NET and XP Service Pack 2) 
```

If you see a message like this, be sure you started the Selenium Server. If so, then there is a problem with the connectivity between the Selenium Client Library and the Selenium Server.

When starting with Selenium RC, most people begin by running their test program (with a Selenium Client Library) and the Selenium Server on the same machine. To do this use “localhost” as your connection parameter. We recommend beginning this way since it reduces the influence of potential networking problems which you’re getting started. Assuming your operating system has typical networking and TCP/IP settings you should have little difficulty. In truth, many people choose to run the tests this way.

If, however, you do want to run Selenium Server on a remote machine, the connectivity should be fine assuming you have valid TCP/IP connectivity between the two machines.

If you have difficulty connecting, you can use common networking tools like *ping*, *telnet*, *ifconfig(Unix)/ipconfig* (Windows), etc to ensure you have a valid network connection. If unfamilar with these, your system administrator can assist you.

### Unable to Load the Browser

Ok, not a friendly error message, sorry, but if the Selenium Server cannot load the browser you will likely see this error.

```bash
    (500) Internal Server Error
```

```bash
    Error:  java.lang.RuntimeException: Firefox refused shutdown while 
    preparing a profile 
```

Here’s the complete error message from the server:

```bash
    16:20:03.919 INFO - Preparing Firefox profile... 
    16:20:27.822 WARN - GET /selenium-server/driver/?cmd=getNewBrowserSession&1=*fir 
    efox&2=http%3a%2f%2fsage-webapp1.qa.idc.com HTTP/1.1 
    java.lang.RuntimeException: Firefox refused shutdown while preparing a profile 
            at org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLaunc 
    her.waitForFullProfileToBeCreated(FirefoxCustomProfileLauncher.java:277) 
    ... 
    Caused by: org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLaunc 
    her$FileLockRemainedException: Lock file still present! C:\DOCUME~1\jsvec\LOCALS 
    ~1\Temp\customProfileDir203138\parent.lock 
```

To resolve this, see the section on Specifying a Separate Firefox Profile

### Versioning Problems

Make sure your version of Selenium supports the version of your browser. For example, Selenium RC 0.92 does not support Firefox 3. At times you may be lucky (I was). But don’t forget to check which browser versions are supported by the version of Selenium you are using. When in doubt, use the latest release version of Selenium with the most widely used version of your browser.

### Error message: “(Unsupported major.minor version 49.0)” while starting server

This error says you’re not using a correct version of Java. The Selenium Server requires Java 1.5 or higher.

To check double-check your java version, run this from the command line.

```bash
   java -version
```

You should see a message showing the Java version.

```bash
   java version "1.5.0_07"
   Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03)
   Java HotSpot(TM) Client VM (build 1.5.0_07-b03, mixed mode)
```

```bash
   cmd=getNewBrowserSession&1=*firefox /usr/local/firefox/firefox-bin&2=http://www.google.com
```

```bash
   /usr/lib/firefox-x.x.x/ 
```

Where the x.x.x is the version number you currently have. So, to add that path to the user’s path. you will have to add the following to your .bashrc file:

```bash
   export PATH="$PATH:/usr/lib/firefox-x.x.x/"
```

If necessary, you can specify the path to firefox-bin directly in your test, like this:

```bash
   "*firefox /usr/lib/firefox-x.x.x/firefox-bin"
```

### IE and Style Attributes

If you are running your tests on Internet Explorer and you cannot locate elements using their `style` attribute. For example:

```bash
    //td[@style="background-color:yellow"]
```

This would work perfectly in Firefox, Opera or Safari but not with IE. IE interprets the keys in `@style` as uppercase. So, even if the source code is in lowercase, you should use:

```bash
    //td[@style="BACKGROUND-COLOR:yellow"]
```

This is a problem if your test is intended to work on multiple browsers, but you can easily code your test to detect the situation and try the alternative locator that only works in IE.

### Error encountered - “Cannot convert object to primitive value” with shut down of \*googlechrome browser

To avoid this error you have to start browser with an option that disables same origin policy checks:

```bash
   selenium.start("commandLineFlags=--disable-web-security");
```

### Error encountered in IE - “Couldn’t open app window; is the pop-up blocker enabled?”

To avoid this error you have to configure the browser: disable the popup blocker AND uncheck ‘Enable Protected Mode’ option in Tools » Options » Security.

***

1. The proxy is a third person in the middle that passes the ball between the two parts. It acts as a “web server” that delivers the AUT to the browser. Being a proxy gives Selenium Server the capability of “lying” about the AUT’s real URL. [↩︎](#fnref:1)

2. The browser is launched with a configuration profile that has set localhost:4444 as the HTTP proxy, this is why any HTTP request that the browser does will pass through Selenium server and the response will pass through it and not from the real server. [↩︎](#fnref:2)

----
url: https://www.selenium.dev/documentation/legacy/selenium_2/remote_server/
----

# Remote WebDriver standalone server

Working with the Standalone Server.

This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/RemoteWebDriverServer)

The server will always run on the machine with the browser you want to test. The server can be used either from the command line or through code configuration.

## Starting the server from the command line

Once you have downloaded `selenium-server-standalone-{VERSION}.jar`, place it on the computer with the browser you want to test. Then, from the directory with the jar, run the following:

```shell
java -jar selenium-server-standalone-{VERSION}.jar
```

## Considerations for running the server

The caller is expected to terminate each session properly, calling either `Selenium#stop()` or `WebDriver#quit`.

The selenium-server keeps in-memory logs for each ongoing session, which are cleared when `Selenium#stop()` or `WebDriver#quit` is called. If you forget to terminate these sessions, your server may leak memory. If you keep extremely long-running sessions, you will probably need to stop/quit every now and then (or increase memory with -Xmx jvm option).

## Timeouts (from version 2.21)

The server has two different timeouts, which can be set as follows:

```shell
java -jar selenium-server-standalone-{VERSION}.jar -timeout=20 -browserTimeout=60
```

```java
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.security.SslSocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;

import javax.servlet.Servlet;
import java.io.File;

import org.openqa.selenium.remote.server.DriverServlet;

public class AppServer {
  private Server server = new Server();

  public AppServer() throws Exception {
    WebAppContext context = new WebAppContext();
    context.setContextPath("");
    context.setWar(new File("."));
    server.addHandler(context);

    context.addServlet(DriverServlet.class, "/wd/*");

    SelectChannelConnector connector = new SelectChannelConnector();
    connector.setPort(3001);
    server.addConnector(connector);

    server.start();
  }
}
```

----
url: https://www.selenium.dev/ja/documentation/test_practices/overview/
----

# テスト自動化について

```java
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
User user = UserFactory.createCommonUser(); //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
AccountPage accountPage = loginAs(user.getEmail(), user.getPassword());
  
```

```python
# Create a user who has read-only permissions--they can configure a unicorn,
# but they do not have payment information set up, nor do they have
# administrative privileges. At the time the user is created, its email
# address and password are randomly generated--you don't even need to
# know them.
user = user_factory.create_common_user() #This method is defined elsewhere.

# Log in as this user.
# Logging in on this site takes you to your personal "My Account" page, so the
# AccountPage object is returned by the loginAs method, allowing you to then
# perform actions from the AccountPage.
account_page = login_as(user.get_email(), user.get_password())
  
```

```csharp
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
User user = UserFactory.CreateCommonUser(); //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
AccountPage accountPage = LoginAs(user.Email, user.Password);
  
```

```ruby
# Create a user who has read-only permissions--they can configure a unicorn,
# but they do not have payment information set up, nor do they have
# administrative privileges. At the time the user is created, its email
# address and password are randomly generated--you don't even need to
# know them.
user = UserFactory.create_common_user #This method is defined elsewhere.

# Log in as this user.
# Logging in on this site takes you to your personal "My Account" page, so the
# AccountPage object is returned by the loginAs method, allowing you to then
# perform actions from the AccountPage.
account_page = login_as(user.email, user.password)
  
```

```javascript
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
var user = userFactory.createCommonUser(); //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
var accountPage = loginAs(user.email, user.password);
  
```

```kotlin
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
val user = UserFactory.createCommonUser() //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
val accountPage = loginAs(user.getEmail(), user.getPassword())
  
```

```java
// The Unicorn is a top-level Object--it has attributes, which are set here. 
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
Unicorn sparkles = new Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS);

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.
AddUnicornPage addUnicornPage = accountPage.addUnicorn();

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
UnicornConfirmationPage unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles);
  
```

```python
# The Unicorn is a top-level Object--it has attributes, which are set here.
# This only stores the values; it does not fill out any web forms or interact
# with the browser in any way.
sparkles = Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

# Since we're already "on" the account page, we have to use it to get to the
# actual place where you configure unicorns. Calling the "Add Unicorn" method
# takes us there.
add_unicorn_page = account_page.add_unicorn()

# Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
# its createUnicorn() method. This method will take Sparkles' attributes,
# fill out the form, and click submit.
unicorn_confirmation_page = add_unicorn_page.create_unicorn(sparkles)
  
```

```csharp
// The Unicorn is a top-level Object--it has attributes, which are set here. 
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
Unicorn sparkles = new Unicorn("Sparkles", UnicornColors.Purple, UnicornAccessories.Sunglasses, UnicornAdornments.StarTattoos);

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.
AddUnicornPage addUnicornPage = accountPage.AddUnicorn();

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
UnicornConfirmationPage unicornConfirmationPage = addUnicornPage.CreateUnicorn(sparkles);
  
```

```ruby
# The Unicorn is a top-level Object--it has attributes, which are set here.
# This only stores the values; it does not fill out any web forms or interact
# with the browser in any way.
sparkles = Unicorn.new('Sparkles', UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

# Since we're already "on" the account page, we have to use it to get to the
# actual place where you configure unicorns. Calling the "Add Unicorn" method
# takes us there.
add_unicorn_page = account_page.add_unicorn

# Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
# its createUnicorn() method. This method will take Sparkles' attributes,
# fill out the form, and click submit.
unicorn_confirmation_page = add_unicorn_page.create_unicorn(sparkles)
  
```

```javascript
// The Unicorn is a top-level Object--it has attributes, which are set here.
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
var sparkles = new Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS);

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.

var addUnicornPage = accountPage.addUnicorn();

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
var unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles);

  
```

```kotlin
// The Unicorn is a top-level Object--it has attributes, which are set here. 
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
val sparkles = Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.
val addUnicornPage = accountPage.addUnicorn()

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles)

  
```

```java
// The exists() method from UnicornConfirmationPage will take the Sparkles 
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
Assert.assertTrue("Sparkles should have been created, with all attributes intact", unicornConfirmationPage.exists(sparkles));
  
```

```python
# The exists() method from UnicornConfirmationPage will take the Sparkles
# object--a specification of the attributes you want to see, and compare
# them with the fields on the page.
assert unicorn_confirmation_page.exists(sparkles), "Sparkles should have been created, with all attributes intact"
  
```

```csharp
// The exists() method from UnicornConfirmationPage will take the Sparkles 
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
Assert.True(unicornConfirmationPage.Exists(sparkles), "Sparkles should have been created, with all attributes intact");
  
```

```ruby
# The exists() method from UnicornConfirmationPage will take the Sparkles
# object--a specification of the attributes you want to see, and compare
# them with the fields on the page.
expect(unicorn_confirmation_page.exists?(sparkles)).to be, 'Sparkles should have been created, with all attributes intact'
  
```

```javascript
// The exists() method from UnicornConfirmationPage will take the Sparkles
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
assert(unicornConfirmationPage.exists(sparkles), "Sparkles should have been created, with all attributes intact");

  
```

```kotlin
// The exists() method from UnicornConfirmationPage will take the Sparkles 
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
assertTrue("Sparkles should have been created, with all attributes intact", unicornConfirmationPage.exists(sparkles))
  
```

テスターはまだこのコードでユニコーンについて話しているだけです。 ボタンもロケーターもブラウザーコントロールもありません。 ラリーが来週、Ruby-on-Railsが好きではなくなったと判断し、Fortranフロントエンドを使用して最新のHaskellバインディングでサイト全体を再実装することを決めた場合でも、アプリケーションを *モデル化する* この方法により、これらのテストレベルのコマンドを所定の位置に変えずに維持できます。

ページオブジェクトは、サイトの再設計に準拠するために若干のメンテナンスが必要になりますが、これらのテストは同じままです。 この基本的な設計を採用することで、可能な限りブラウザに面した最小限の手順でワークフローを進めていきたいと思うでしょう。 次のワークフローでは、ユニコーンをショッピングカートに追加します。 カートの状態が適切に維持されていることを確認するために、おそらくこのテストを何度も繰り返す必要があります。 開始する前に、カートに複数のユニコーンがありますか？ ショッピングカートには何個収容できますか？ 同じ名前や機能で複数作成すると、壊れますか？ 既存のものを保持するだけですか、それとも別のものを追加しますか？

ワークフローを移動するたびに、アカウントを作成し、ユーザーとしてログインし、ユニコーンを設定する必要を避けたいと考えています。 理想的には、APIまたはデータベースを介してアカウントを作成し、ユニコーンを事前設定できるようになります。 その後、ユーザーとしてログインし、きらめきを見つけてカートに追加するだけです。

### 自動化するかしないか

自動化は常に有利ですか？ テストケースの自動化をいつ決定する必要がありますか？

テストケースを自動化することは必ずしも有利ではありません。 手動テストがより適切な場合があります。 たとえば、近い将来にアプリケーションのユーザーインターフェースが大幅に変更される場合は、自動化を書き換える必要があるかもしれません。 また、テストの自動化を構築する時間が足りない場合もあります。 短期的には、手動テストの方が効果的です。 アプリケーションの期限が非常に厳しい場合、現在利用できるテストの自動化はなく、その期間内にテストを実施することが不可欠です。 手動テストが最適なソリューションです。

----
url: https://www.selenium.dev/ja/documentation/webdriver/drivers/options/
----

# ブラウザーオプション

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L73-74)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L79-80)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L11)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L80-82)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L86-88)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options.browser_version = 'latest'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L40)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## pageLoadStrategy

3種類のページ読み込み戦略を利用できます。

ページ読み込み戦略は、次の表で説明しています。

| 戦略     | 準備完了状態      | 注釈                                              |
| ------ | ----------- | ----------------------------------------------- |
| normal | complete    | デフォルトで使用され、すべてのリソースをダウンロードするのを待ちます              |
| eager  | interactive | DOM アクセスの準備は整っていますが、画像などの他のリソースはまだロード中の可能性があります |
| none   | Any         | WebDriver をまったくブロックしません                         |

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L21-L23)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L7-9)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L13-14)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L11-L12)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L28-L34)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L34-L36)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L15-L17)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L29-30)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L20-L21)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L8-L14)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L47-L49)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L23-L25)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
        public void SetPageLoadStrategyNone()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L41-42)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L29-L30)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L18-L24)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L88-L90)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L94-96)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L38-L39)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L60-L61)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L101-103)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L51-L52)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L38-L41)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L96-L98)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L30-32)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L114-L115)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L111-L113)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L37-39)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L105-L106)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L126-L128)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L44-46)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L96-L97)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L141-L142)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L51-53)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L60-L61)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L151-L152)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L58-60)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L69-L70)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L163-L164)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L65-67)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L78-L79)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class ProxyTest {
  public static void main(String[] args) {
    Proxy proxy = new Proxy();
    proxy.setHttpProxy("<HOST:PORT>");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("proxy", proxy);
    WebDriver driver = new ChromeDriver(options);
    driver.get("https://www.google.com/");
    driver.manage().window().maximize();
    driver.quit();
  }
}
```

```py
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L72-74)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

public class ProxyTest{
public static void Main() {
ChromeOptions options = new ChromeOptions();
Proxy proxy = new Proxy();
proxy.Kind = ProxyKind.Manual;
proxy.IsAutoDetect = false;
proxy.SslProxy = "<HOST:PORT>";
options.Proxy = proxy;
options.AddArgument("ignore-certificate-errors");
IWebDriver driver = new ChromeDriver(options);
driver.Navigate().GoToUrl("https://www.selenium.dev/");
}
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L87-L88)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```javascript
let webdriver = require('selenium-webdriver');
let chrome = require('selenium-webdriver/chrome');
let proxy = require('selenium-webdriver/proxy');
let opts = new chrome.Options();

(async function example() {
opts.setProxy(proxy.manual({http: '<HOST:PORT>'}));
let driver = new webdriver.Builder()
.forBrowser('chrome')
.setChromeOptions(opts)
.build();
try {
await driver.get("https://selenium.dev");
}
finally {
await driver.quit();
}
}());
```

```kotlin
import org.openqa.selenium.Proxy
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

class proxyTest {
fun main() {

        val proxy = Proxy()
        proxy.setHttpProxy("<HOST:PORT>")
        val options = ChromeOptions()
        options.setCapability("proxy", proxy)
        val driver: WebDriver = ChromeDriver(options)
        driver["https://www.google.com/"]
        driver.manage().window().maximize()
        driver.quit()
    }
}
```

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/drivers/service/
----

# Classe de Serviço do Driver

```java
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L15-L16)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L5-L6)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L14-L15)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

```rb
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L14-L15)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

```java
    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L25-L26)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(executable_path=chromedriver_bin)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L15)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```cs
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L23)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
    service.executable_path = driver_path
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L26)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

```java
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L33)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(port=1234)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L23)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            service.Port = 1234;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L32)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
    service.port = 1234
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L33)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

----
url: https://www.selenium.dev/documentation/webdriver/drivers/http_client/
----

# HTTP Client Configuration

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import org.openqa.selenium.remote.http.ClientConfig;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import java.io.FileInputStream;
import java.net.URL;
import java.nio.file.Path;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.time.Duration;

import org.openqa.selenium.UsernameAndPassword;

import static java.net.http.HttpClient.Version.HTTP_1_1;

public class HttpClientTest extends BaseTest {
    URL gridUrl;

    @BeforeEach
    public void startGrid() {
        gridUrl = startStandaloneGridAdvanced();
    }

    @Test
    public void remoteWebDriverWithClientConfig() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createSSLContextWithCA(Path.of("src/test/resources/tls.crt").toAbsolutePath().toString()))
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
    }

    @Test
    public void remoteWebDriverIgnoreSSL() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createIgnoreSSLContext())
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
    }

    @Test
    public void remoteWebDriverWithEmbedAuthUrl() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createSSLContextWithCA(Path.of("src/test/resources/tls.crt").toAbsolutePath().toString()))
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(embedAuthToUrl(gridUrl, "admin", "myStrongPassword"))
                .config(clientConfig)
                .build();
    }

    private URL embedAuthToUrl(URL url, String username, String password) throws Exception {
        String userInfo = username + ":" + password;
        String urlWithAuth = url.getProtocol() + "://" + userInfo + "@" + url.getHost() + ":" + url.getPort() + url.getPath();
        return new URL(urlWithAuth);
    }

    public static SSLContext createSSLContextWithCA(String caCertPath) throws Exception {
        FileInputStream fis = new FileInputStream(caCertPath);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate caCert = (X509Certificate) cf.generateCertificate(fis);
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, null);
        keyStore.setCertificateEntry("caCert", caCert);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(keyStore);
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);
        return sslContext;
    }

    public static SSLContext createIgnoreSSLContext() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    }
                }
        };
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
        return sslContext;
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/HttpClientTest.java)

```py
import os
import pytest
import sys
from urllib3.util import Retry, Timeout
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType
from selenium.webdriver.remote.client_config import ClientConfig


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_with_client_config(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    retries = Retry(connect=2, read=2, redirect=2)
    timeout = Timeout(connect=300, read=3600)
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 init_args_for_pool_manager={
                                     "init_args_for_pool_manager": {"retries": retries, "timeout": timeout}},
                                 ca_certs=_get_resource_path("tls.crt"),
                                 username="admin", password="myStrongPassword")
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_ignore_certs(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 timeout=3600,
                                 ignore_certificates=True,
                                 username="admin", password="myStrongPassword")
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


def _get_resource_path(file_name: str):
    if os.path.abspath("").endswith("tests"):
        path = os.path.abspath(f"resources/{file_name}")
    else:
        path = os.path.abspath(f"tests/resources/{file_name}")
    return path

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_http_client.py)

[Add Example](/documentation/about/contributing/#creating-examples)

```rb

  it 'sets client configuration' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/http_client_spec.rb#L7-L8)

##### /examples/ruby/spec/drivers/http\_client\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'HTTP Client' do
  let(:url) { 'https://www.selenium.dev/selenium/web/' }

  it 'sets client configuration' do
    client = Selenium::WebDriver::Remote::Http::Default.new(open_timeout: 30, read_timeout: 30)
    expect(client.open_timeout).to eq 30
  end

  it 'uses the custom http client' do
    client = Selenium::WebDriver::Remote::Http::Default.new
    driver = Selenium::WebDriver.for :chrome, http_client: client
    driver.get(url)
    driver.quit
  end
end
```

----
url: https://www.selenium.dev/documentation/webdriver/browsers/internet_explorer/
----

# IE specific functionality

```java
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#38-L41)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

```py
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L11-L14)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L35-L38)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

```rb
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L17-L20)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#46-L47)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

```py
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L21-L22)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L44-L45)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L24-L25)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
let driver = await new Builder()
.forBrowser('internet explorer')
.setIEOptions(options)
.build();
```

```kotlin
val options = InternetExplorerOptions()
val driver = InternetExplorerDriver(options)
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.waitForUploadDialogUpTo(Duration.ofSeconds(2));
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L28-L29)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.FileUploadDialogTimeout = TimeSpan.FromMilliseconds(2000);
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.file_upload_dialog_timeout = 2000
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L29)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().fileUploadDialogTimeout(2000);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.waitForUploadDialogUpTo(Duration.ofSeconds(2))
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.destructivelyEnsureCleanSession();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ensure_clean_session = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L38-L39)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.EnsureCleanSession = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ensure_clean_session = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L35)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true
    
    require 'spec_helper'
    
    RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
      describe 'Options' do
        let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
        let(:url) { 'https://www.selenium.dev/selenium/web/' }
    
        before do
          @options = Selenium::WebDriver::IE::Options.new
          @options.attach_to_edge_chrome = true
          @options.edge_executable_path = edge_location
        end
    
        it 'basic options Win10' do
          options = Selenium::WebDriver::IE::Options.new
          options.attach_to_edge_chrome = true
          options.edge_executable_path = edge_location
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'basic options Win11' do
          options = Selenium::WebDriver::Options.ie
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'sets the file upload dialog timeout' do
          @options.file_upload_dialog_timeout = 2000
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ensures a clean session' do
          @options.ensure_clean_session = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the zoom setting' do
          @options.ignore_zoom_level = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the protected mode settings' do
          @options.ignore_protected_mode_settings = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'adds the silent option' do
          @options.silent = true
          expect(@options.silent).to be_truthy
        end
    
        it 'sets the command line options' do
          @options.add_argument('-k')
          Selenium::WebDriver.for(:ie, options: @options)
        end
    
        it 'launches ie with the create process api' do
          @options.force_create_process_api = true
          Selenium::WebDriver.for(:ie, options: @options)
          expect(@options.instance_variable_get(:@options)['force_create_process_api'])
            .to eq({force_create_process_api: true})
        end
      end
    
      describe 'Service' do
        let(:file_name) { Tempfile.new('iedriver').path }
        let(:root_directory) { Dir.mktmpdir }
    
        after do
          FileUtils.rm_f(file_name)
          FileUtils.remove_entry root_directory
        end
    
        it 'logs to file' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = file_name
    
          @driver = Selenium::WebDriver.for :ie, service: service
          expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
        end
    
        it 'logs to console' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = $stdout
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
        end
    
        it 'sets log level' do
          service = Selenium::WebDriver::Service.ie
          service.log = $stdout
    
          service.args << '-log-level=WARN'
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
        end
    
        it 'sets location for supporting files' do
          service = Selenium::WebDriver::Service.ie
    
          service.args << "–extract-path=#{root_directory}"
    
          @driver = Selenium::WebDriver.for :ie, service: service
        end
      end
    end
    
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().ensureCleanSession(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.destructivelyEnsureCleanSession()
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.ignoreZoomSettings();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L48-L49)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.IgnoreZoomLevel = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ignore_zoom_level = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L41)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true
    
    require 'spec_helper'
    
    RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
      describe 'Options' do
        let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
        let(:url) { 'https://www.selenium.dev/selenium/web/' }
    
        before do
          @options = Selenium::WebDriver::IE::Options.new
          @options.attach_to_edge_chrome = true
          @options.edge_executable_path = edge_location
        end
    
        it 'basic options Win10' do
          options = Selenium::WebDriver::IE::Options.new
          options.attach_to_edge_chrome = true
          options.edge_executable_path = edge_location
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'basic options Win11' do
          options = Selenium::WebDriver::Options.ie
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'sets the file upload dialog timeout' do
          @options.file_upload_dialog_timeout = 2000
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ensures a clean session' do
          @options.ensure_clean_session = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the zoom setting' do
          @options.ignore_zoom_level = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the protected mode settings' do
          @options.ignore_protected_mode_settings = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'adds the silent option' do
          @options.silent = true
          expect(@options.silent).to be_truthy
        end
    
        it 'sets the command line options' do
          @options.add_argument('-k')
          Selenium::WebDriver.for(:ie, options: @options)
        end
    
        it 'launches ie with the create process api' do
          @options.force_create_process_api = true
          Selenium::WebDriver.for(:ie, options: @options)
          expect(@options.instance_variable_get(:@options)['force_create_process_api'])
            .to eq({force_create_process_api: true})
        end
      end
    
      describe 'Service' do
        let(:file_name) { Tempfile.new('iedriver').path }
        let(:root_directory) { Dir.mktmpdir }
    
        after do
          FileUtils.rm_f(file_name)
          FileUtils.remove_entry root_directory
        end
    
        it 'logs to file' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = file_name
    
          @driver = Selenium::WebDriver.for :ie, service: service
          expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
        end
    
        it 'logs to console' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = $stdout
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
        end
    
        it 'sets log level' do
          service = Selenium::WebDriver::Service.ie
          service.log = $stdout
    
          service.args << '-log-level=WARN'
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
        end
    
        it 'sets location for supporting files' do
          service = Selenium::WebDriver::Service.ie
    
          service.args << "–extract-path=#{root_directory}"
    
          @driver = Selenium::WebDriver.for :ie, service: service
        end
      end
    end
    
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().ignoreZoomSetting(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.ignoreZoomSettings()
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.introduceFlakinessByIgnoringSecurityDomains();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L58-L59)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.IntroduceInstabilityByIgnoringProtectedModeSettings = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ignore_protected_mode_settings = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L47)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true
    
    require 'spec_helper'
    
    RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
      describe 'Options' do
        let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
        let(:url) { 'https://www.selenium.dev/selenium/web/' }
    
        before do
          @options = Selenium::WebDriver::IE::Options.new
          @options.attach_to_edge_chrome = true
          @options.edge_executable_path = edge_location
        end
    
        it 'basic options Win10' do
          options = Selenium::WebDriver::IE::Options.new
          options.attach_to_edge_chrome = true
          options.edge_executable_path = edge_location
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'basic options Win11' do
          options = Selenium::WebDriver::Options.ie
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'sets the file upload dialog timeout' do
          @options.file_upload_dialog_timeout = 2000
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ensures a clean session' do
          @options.ensure_clean_session = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the zoom setting' do
          @options.ignore_zoom_level = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the protected mode settings' do
          @options.ignore_protected_mode_settings = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'adds the silent option' do
          @options.silent = true
          expect(@options.silent).to be_truthy
        end
    
        it 'sets the command line options' do
          @options.add_argument('-k')
          Selenium::WebDriver.for(:ie, options: @options)
        end
    
        it 'launches ie with the create process api' do
          @options.force_create_process_api = true
          Selenium::WebDriver.for(:ie, options: @options)
          expect(@options.instance_variable_get(:@options)['force_create_process_api'])
            .to eq({force_create_process_api: true})
        end
      end
    
      describe 'Service' do
        let(:file_name) { Tempfile.new('iedriver').path }
        let(:root_directory) { Dir.mktmpdir }
    
        after do
          FileUtils.rm_f(file_name)
          FileUtils.remove_entry root_directory
        end
    
        it 'logs to file' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = file_name
    
          @driver = Selenium::WebDriver.for :ie, service: service
          expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
        end
    
        it 'logs to console' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = $stdout
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
        end
    
        it 'sets log level' do
          service = Selenium::WebDriver::Service.ie
          service.log = $stdout
    
          service.args << '-log-level=WARN'
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
        end
    
        it 'sets location for supporting files' do
          service = Selenium::WebDriver::Service.ie
    
          service.args << "–extract-path=#{root_directory}"
    
          @driver = Selenium::WebDriver.for :ie, service: service
        end
      end
    end
    
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().introduceFlakinessByIgnoringProtectedModeSettings(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.introduceFlakinessByIgnoringSecurityDomains()
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.setCapability("silent", true);
WebDriver driver = new InternetExplorerDriver(options);
  
```

```py
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L68-L69)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
InternetExplorerOptions options = new InternetExplorerOptions();
options.AddAdditionalInternetExplorerOption("silent", true);
IWebDriver driver = new InternetExplorerDriver(options);
  
```

```rb
      @options.silent = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L53)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true
    
    require 'spec_helper'
    
    RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
      describe 'Options' do
        let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
        let(:url) { 'https://www.selenium.dev/selenium/web/' }
    
        before do
          @options = Selenium::WebDriver::IE::Options.new
          @options.attach_to_edge_chrome = true
          @options.edge_executable_path = edge_location
        end
    
        it 'basic options Win10' do
          options = Selenium::WebDriver::IE::Options.new
          options.attach_to_edge_chrome = true
          options.edge_executable_path = edge_location
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'basic options Win11' do
          options = Selenium::WebDriver::Options.ie
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'sets the file upload dialog timeout' do
          @options.file_upload_dialog_timeout = 2000
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ensures a clean session' do
          @options.ensure_clean_session = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the zoom setting' do
          @options.ignore_zoom_level = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the protected mode settings' do
          @options.ignore_protected_mode_settings = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'adds the silent option' do
          @options.silent = true
          expect(@options.silent).to be_truthy
        end
    
        it 'sets the command line options' do
          @options.add_argument('-k')
          Selenium::WebDriver.for(:ie, options: @options)
        end
    
        it 'launches ie with the create process api' do
          @options.force_create_process_api = true
          Selenium::WebDriver.for(:ie, options: @options)
          expect(@options.instance_variable_get(:@options)['force_create_process_api'])
            .to eq({force_create_process_api: true})
        end
      end
    
      describe 'Service' do
        let(:file_name) { Tempfile.new('iedriver').path }
        let(:root_directory) { Dir.mktmpdir }
    
        after do
          FileUtils.rm_f(file_name)
          FileUtils.remove_entry root_directory
        end
    
        it 'logs to file' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = file_name
    
          @driver = Selenium::WebDriver.for :ie, service: service
          expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
        end
    
        it 'logs to console' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = $stdout
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
        end
    
        it 'sets log level' do
          service = Selenium::WebDriver::Service.ie
          service.log = $stdout
    
          service.args << '-log-level=WARN'
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
        end
    
        it 'sets location for supporting files' do
          service = Selenium::WebDriver::Service.ie
    
          service.args << "–extract-path=#{root_directory}"
    
          @driver = Selenium::WebDriver.for :ie, service: service
        end
      end
    end
    
```

```javascript
const {Builder,By, Capabilities} = require('selenium-webdriver');
let caps = Capabilities.ie();
caps.set('silent', true);

(async function example() {
    let driver = await new Builder()
        .forBrowser('internet explorer')
        .withCapabilities(caps)
        .build();
    try {
        await driver.get('http://www.google.com/ncr');
    }
    finally {
        await driver.quit();
    }
})();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.setCapability("silent", true)
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  
```

```java
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;

public class ieTest {
    public static void main(String[] args) {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.useCreateProcessApiToLaunchIe();
        options.addCommandSwitches("-k");
        InternetExplorerDriver driver = new InternetExplorerDriver(options);
        try {
            driver.get("https://google.com/ncr");
            Capabilities caps = driver.getCapabilities();
            System.out.println(caps);
        } finally {
            driver.quit();
        }
    }
}
  
```

```py
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L76-L79)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;

namespace ieTest {
 class Program {
  static void Main(string[] args) {
   InternetExplorerOptions options = new InternetExplorerOptions();
   options.ForceCreateProcessApi = true;
   options.BrowserCommandLineArguments = "-k";
   IWebDriver driver = new InternetExplorerDriver(options);
   driver.Url = "https://google.com/ncr";
  }
 }
}
  
```

```rb
      @options.add_argument('-k')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L58)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true
    
    require 'spec_helper'
    
    RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
      describe 'Options' do
        let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
        let(:url) { 'https://www.selenium.dev/selenium/web/' }
    
        before do
          @options = Selenium::WebDriver::IE::Options.new
          @options.attach_to_edge_chrome = true
          @options.edge_executable_path = edge_location
        end
    
        it 'basic options Win10' do
          options = Selenium::WebDriver::IE::Options.new
          options.attach_to_edge_chrome = true
          options.edge_executable_path = edge_location
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'basic options Win11' do
          options = Selenium::WebDriver::Options.ie
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'sets the file upload dialog timeout' do
          @options.file_upload_dialog_timeout = 2000
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ensures a clean session' do
          @options.ensure_clean_session = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the zoom setting' do
          @options.ignore_zoom_level = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the protected mode settings' do
          @options.ignore_protected_mode_settings = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'adds the silent option' do
          @options.silent = true
          expect(@options.silent).to be_truthy
        end
    
        it 'sets the command line options' do
          @options.add_argument('-k')
          Selenium::WebDriver.for(:ie, options: @options)
        end
    
        it 'launches ie with the create process api' do
          @options.force_create_process_api = true
          Selenium::WebDriver.for(:ie, options: @options)
          expect(@options.instance_variable_get(:@options)['force_create_process_api'])
            .to eq({force_create_process_api: true})
        end
      end
    
      describe 'Service' do
        let(:file_name) { Tempfile.new('iedriver').path }
        let(:root_directory) { Dir.mktmpdir }
    
        after do
          FileUtils.rm_f(file_name)
          FileUtils.remove_entry root_directory
        end
    
        it 'logs to file' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = file_name
    
          @driver = Selenium::WebDriver.for :ie, service: service
          expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
        end
    
        it 'logs to console' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = $stdout
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
        end
    
        it 'sets log level' do
          service = Selenium::WebDriver::Service.ie
          service.log = $stdout
    
          service.args << '-log-level=WARN'
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
        end
    
        it 'sets location for supporting files' do
          service = Selenium::WebDriver::Service.ie
    
          service.args << "–extract-path=#{root_directory}"
    
          @driver = Selenium::WebDriver.for :ie, service: service
        end
      end
    end
    
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options();
options.addBrowserCommandSwitches('-k');
options.addBrowserCommandSwitches('-private');
options.forceCreateProcessApi(true);

driver = await env.builder()
          .setIeOptions(options)
          .build();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.useCreateProcessApiToLaunchIe()
    options.addCommandSwitches("-k")
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  
```

```java
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;

public class ieTest {
    public static void main(String[] args) {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.useCreateProcessApiToLaunchIe();
        InternetExplorerDriver driver = new InternetExplorerDriver(options);
        try {
            driver.get("https://google.com/ncr");
            Capabilities caps = driver.getCapabilities();
            System.out.println(caps);
        } finally {
            driver.quit();
        }
    }
}
  
```

```py
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L87-L90)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;

namespace ieTest {
 class Program {
  static void Main(string[] args) {
   InternetExplorerOptions options = new InternetExplorerOptions();
   options.ForceCreateProcessApi = true;
   IWebDriver driver = new InternetExplorerDriver(options);
   driver.Url = "https://google.com/ncr";
  }
 }
}
  
```

```rb
      @options.force_create_process_api = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L63)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true
    
    require 'spec_helper'
    
    RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
      describe 'Options' do
        let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
        let(:url) { 'https://www.selenium.dev/selenium/web/' }
    
        before do
          @options = Selenium::WebDriver::IE::Options.new
          @options.attach_to_edge_chrome = true
          @options.edge_executable_path = edge_location
        end
    
        it 'basic options Win10' do
          options = Selenium::WebDriver::IE::Options.new
          options.attach_to_edge_chrome = true
          options.edge_executable_path = edge_location
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'basic options Win11' do
          options = Selenium::WebDriver::Options.ie
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'sets the file upload dialog timeout' do
          @options.file_upload_dialog_timeout = 2000
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ensures a clean session' do
          @options.ensure_clean_session = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the zoom setting' do
          @options.ignore_zoom_level = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the protected mode settings' do
          @options.ignore_protected_mode_settings = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'adds the silent option' do
          @options.silent = true
          expect(@options.silent).to be_truthy
        end
    
        it 'sets the command line options' do
          @options.add_argument('-k')
          Selenium::WebDriver.for(:ie, options: @options)
        end
    
        it 'launches ie with the create process api' do
          @options.force_create_process_api = true
          Selenium::WebDriver.for(:ie, options: @options)
          expect(@options.instance_variable_get(:@options)['force_create_process_api'])
            .to eq({force_create_process_api: true})
        end
      end
    
      describe 'Service' do
        let(:file_name) { Tempfile.new('iedriver').path }
        let(:root_directory) { Dir.mktmpdir }
    
        after do
          FileUtils.rm_f(file_name)
          FileUtils.remove_entry root_directory
        end
    
        it 'logs to file' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = file_name
    
          @driver = Selenium::WebDriver.for :ie, service: service
          expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
        end
    
        it 'logs to console' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = $stdout
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
        end
    
        it 'sets log level' do
          service = Selenium::WebDriver::Service.ie
          service.log = $stdout
    
          service.args << '-log-level=WARN'
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
        end
    
        it 'sets location for supporting files' do
          service = Selenium::WebDriver::Service.ie
    
          service.args << "–extract-path=#{root_directory}"
    
          @driver = Selenium::WebDriver.for :ie, service: service
        end
      end
    end
    
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options();
options.forceCreateProcessApi(true);

driver = await env.builder()
          .setIeOptions(options)
          .build();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.useCreateProcessApiToLaunchIe()
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  
```

```java
                .withLogFile(getLogLocation())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L53)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY`\
Property value: String representing path to log file

```py
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L97-L99)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L82)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
                .withLogOutput(System.out)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L67)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L109-L111)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L91)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L82)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGLEVEL_PROPERTY`\
Property value: String representation of `InternetExplorerDriverLogLevel.DEBUG.toString()` enum

```py
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L121-L123)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            if (_tempPath == null || !File.Exists(_tempPath))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L85)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '-log-level=WARN'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L102)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
                .withExtractPath(getTempDirectory())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L94)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

\*\*Note\*\*: Java also allows setting log level by System Property:\ Property key: \`InternetExplorerDriverService.IE\_DRIVER\_EXTRACT\_PATH\_PROPERTY\`\ Property value: String representing path to supporting files directory

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L133-L135)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L98)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << "–extract-path=#{root_directory}"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L112)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

----
url: https://www.selenium.dev/ja/documentation/webdriver/elements/information/
----

# Web要素に関する情報

```java
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L27-L29)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L12-L15)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L18-L22)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    displayed_value = driver.find_element(name: 'email_input').displayed?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L12)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L16-L17)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
 driver.get("https://www.selenium.dev/selenium/web/inputs.html")

 //returns true if element is displayed else returns false 
 val flag = driver.findElement(By.name("email_input")).isDisplayed()
```

```java
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L32-L34)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L19)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L25-L27)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    enabled_value = driver.find_element(name: 'email_input').enabled?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L17)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L23-L24)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
 //navigates to url
 driver.get("https://www.selenium.dev/selenium/web/inputs.html")

 //returns true if element is enabled else returns false 
 val attr = driver.findElement(By.name("button_input")).isEnabled()
 
```

```java
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L37-L39)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L23)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L30-L32)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    selected_value = driver.find_element(name: 'email_input').selected?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L22)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L30-L31)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//returns true if element is checked else returns false
val attr =  driver.findElement(By.name("checkbox_input")).isSelected()
```

```java
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L42-L44)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L27)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L35-L37)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    tag_name = driver.find_element(name: 'email_input').tag_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L27)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L37-L38)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//returns TagName of the element
val attr =  driver.findElement(By.name("email_input")).getTagName()
```

```java
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L47-L50)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    rect = driver.find_element(By.NAME, "range_input").rect
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L31)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L40-L43)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    size = driver.find_element(name: 'email_input').size
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L32)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    let object = await driver.findElement(By.name('range_input')).getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L45)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

// Returns height, width, x and y coordinates referenced element
val res = driver.findElement(By.name("range_input")).rect

// Rectangle class provides getX,getY, getWidth, getHeight methods
println(res.getX())
  
```

```java
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L52-L54)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L35-L37)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L49-L50)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L38)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L76-L78)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to Url
driver.get("https://www.selenium.dev/selenium/web/colorPage.html")

// Retrieves the computed style property 'color' of linktext
val cssValue = driver.findElement(By.id("namedColor")).getCssValue("background-color")
```

```java
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L58-L60)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    text = driver.find_element(By.TAG_NAME, "h1").text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L41)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L53-L55)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    text = driver.find_element(xpath: '//h1').text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L43)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L84-L86)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to URL
driver.get("https://www.selenium.dev/selenium/web/linked_image.html")

// retrieves the text of the element
val text = driver.findElement(By.id("justanotherlink")).getText()
```

```java
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L64-L68)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L44-L46)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L58-L62)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L48)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L55-L59)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to URL
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//fetch the value property associated with the textbox
val attr = driver.findElement(By.name("email_input")).getAttribute("value")
```

最終更新 April 17, 2026: [Update code block references in documentation (#2613) (5d614fcd479)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/5d614fcd479d384003f8e4dd949f6a9f4cada711)

----
url: https://www.selenium.dev/ja/documentation/legacy/
----

# レガシー

このセクションでは、Seleniumのレガシーコンポーネントに関連するすべてのドキュメントを見つけることができます。 これは、非推奨コンポーネントを使用する動機としてではなく、純粋に歴史的な理由で保持されることを意図しています。

**Most of the documentation found in this section is still in English. Please note we are not accepting pull requests to translate this content as translating documentation of legacy components does not add value to the community nor the project.

***

##### [Selenium RC (Selenium 1)](/ja/documentation/legacy/selenium_1/)

The original version of Selenium

##### [Selenium 2](/ja/documentation/legacy/selenium_2/)

Selenium 2 was a rewrite of Selenium 1 that was implemented with WebDriver code.

##### [Selenium 3](/ja/documentation/legacy/selenium_3/)

Selenium 3 was the implementation of WebDriver without the Selenium RC Code. It has since been replaced with Selenium 4, which implements the W3C WebDriver specification.

##### [レガシー Selenium IDE](/ja/documentation/legacy/selenium_ide/)

----
url: https://www.selenium.dev/pt-br/_print/documentation/ie_driver_server/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/ie_driver_server/).

# Servidor de drivers do IE

O Internet Explorer Driver é um servidor autónomo que implementa a especificação WebDriver.

* 1: [Internet Explorer Driver Internals](#pg-69f68803066d382b43f4d932ed8d7457)

| Switch                                                                                                                                                            | Significado                                                                                                                                                      |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Especifica a porta na qual o servidor HTTP do driver IE escutará os comandos das associações de idioma. O padrão é 5555.                                          |                                                                                                                                                                  |
| Especifica o endereço IP do adaptador de anfitrião no qual o servidor HTTP do controlador IE irá escutar os comandos das Language Bindings. O padrão é 127.0.0.1. |                                                                                                                                                                  |
| –log-level=`<logLevel>`                                                                                                                                           | Especifica o nível em que as mensagens de registo são emitidas. Os valores válidos são FATAL, ERROR, WARN, INFO, DEBUG e TRACE. O padrão é FATAL.                |
| –log-file=`<logFile>`                                                                                                                                             | Especifica o caminho completo e o nome do arquivo de log. O padrão é stdout.                                                                                     |
| –extract-path=`<path>`                                                                                                                                            | Especifica o caminho completo para o diretório usado para extrair arquivos de suporte usados pelo servidor. O padrão é o diretório TEMP se não for especificado. |
| –silent                                                                                                                                                           | Suprime a saída de diagnóstico quando o servidor é iniciado.                                                                                                     |

## Propriedades importantes do sistema

As seguintes propriedades do sistema (lidas usando `System.getProperty()` e definidas usando `System.setProperty()` no código Java ou o sinalizador de linha de comando “`-DpropertyName=value`”) são utilizados pelo `InternetExplorerDriver`:

| **Propriedade**                                                                                                                                                  | **O que significa**                                              |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| `webdriver.ie.driver`                                                                                                                                            | A localização do binário do driver do IE.                        |
| Especifica o endereço IP do adaptador do host no qual o driver do IE escutará.                                                                                   |                                                                  |
| Especifica o nível em que as mensagens de registo são emitidas. Os valores válidos são FATAL, ERROR, WARN, INFO, DEBUG e TRACE. O padrão é FATAL.                |                                                                  |
| Especifica o caminho completo e o nome do arquivo de log.                                                                                                        |                                                                  |
| `webdriver.ie.driver.silent`                                                                                                                                     | Suprime a saída de diagnóstico quando o driver do IE é iniciado. |
| Especifica o caminho completo para o diretório usado para extrair arquivos de suporte usados pelo servidor. O padrão é o diretório TEMP se não for especificado. |                                                                  |

----
url: https://www.selenium.dev/zh-cn/_print/documentation/grid/advanced_features/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/grid/advanced_features/).

# 高级功能

要获得高级功能的所有详细信息, 了解其工作原理, 以及如何设置自己的功能, 请浏览以下部分.

* 1: [可观测性](#pg-58fa36fce0115e0cac81fa0157f35027)
* 2: [GraphQL查询支持](#pg-5accfc3d64bfa8a3f37b3a48872e2e2d)
* 3: [Grid端点](#pg-d465290d42e97f4e216fb472ad892ff3)
* 4: [自定义Node](#pg-5072bf299379dd6eab5265a6c5e77cdf)
* 5: [External datastore](#pg-a39cd5d25428eb436570d7f73037fed5)

# 1 - 可观测性

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar standalone --log-level FINE
```

2. Jaeger UI - OpenTelemetry provides the APIs and SDKs to instrument traces in the code. Whereas Jaeger is a tracing backend, that aids in collecting the tracing telemetry data and providing querying, filtering and visualizing features for the data.

Detailed instructions of visualizing traces using Jaeger UI can be obtained by running the command :

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar info tracing
```

[A very good example and scripts to run the server and send traces to Jaeger](https://github.com/manoj9788/tracing-selenium-grid)

## Leveraging event logs

Tracing has to be enabled for event logging as well, even if one does not wish to export traces to visualize them.\
**By default, tracing is enabled. No additional parameters need to be passed to see logs on the console.** All events within a span are logged at FINE level. Error events are logged at WARN level.

All event logs have the following fields :

| Field            | Field value     | Description                                                                                                                                                                            |
| ---------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Event time       | eventId         | Timestamp of the event record in epoch nanoseconds.                                                                                                                                    |
| Trace Id         | tracedId        | Each trace is uniquely identified by a trace id.                                                                                                                                       |
| Span Id          | spanId          | Each span within a trace is uniquely identified by a span id.                                                                                                                          |
| Span Kind        | spanKind        | Span kind is a property of span indicating the type of span. It helps in understanding the nature of the unit of work done by the Span.                                                |
| Event name       | eventName       | This maps to the log message.                                                                                                                                                          |
| Event attributes | eventAttributes | This forms the crux of the event logs, based on the operation executed, it has JSON formatted key-value pairs. This also includes a handler class attribute, to show the logger class. |

Sample log

```
FINE [LoggingOptions$1.lambda$export$1] - {
  "traceId": "fc8aef1d44b3cc8bc09eb8e581c4a8eb",
  "spanId": "b7d3b9865d3ddd45",
  "spanKind": "INTERNAL",
  "eventTime": 1597819675128886121,
  "eventName": "Session request execution complete",
  "attributes": {
    "http.status_code": 200,
    "http.handler_class": "org.openqa.selenium.grid.router.HandleSession",
    "http.url": "\u002fsession\u002fdd35257f104bb43fdfb06242953f4c85",
    "http.method": "DELETE",
    "session.id": "dd35257f104bb43fdfb06242953f4c85"
  }
}
```

In addition to the above fields, based on [OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/exceptions.md) error logs consist of :

| Field                | Field value          | Description                                                                                                                   |
| -------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Exception type       | exception.type       | The class name of the exception.                                                                                              |
| Exception message    | exception.message    | Reason for the exception.                                                                                                     |
| Exception stacktrace | exception.stacktrace | Prints the call stack at the point of time when the exception was thrown. Helps in understanding the origin of the exception. |

Sample error log

```
WARN [LoggingOptions$1.lambda$export$1] - {
  "traceId": "7efa5ea57e02f89cdf8de586fe09f564",
  "spanId": "914df6bc9a1f6e2b",
  "spanKind": "INTERNAL",
  "eventTime": 1597820253450580272,
  "eventName": "exception",
  "attributes": {
    "exception.type": "org.openqa.selenium.ScriptTimeoutException",
    "exception.message": "Unable to execute request: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist ..." (full message will be printed),
    "exception.stacktrace": "org.openqa.selenium.ScriptTimeoutException: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist\nBuild info: version: '4.0.0-alpha-7', revision: 'Unknown'\nSystem info: host: 'XYZ-MacBook-Pro.local', ip: 'fe80:0:0:0:10d5:b63a:bdc6:1aff%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.7'\nDriver info: driver.version: unknown ...." (full stack will be printed),
    "http.handler_class": "org.openqa.selenium.grid.distributor.remote.RemoteDistributor",
    "http.url": "\u002fsession",
    "http.method": "POST"
  }
}
```

# 2 - GraphQL查询支持

```shell
{
    session(id: "<session-id>") : {
        id,
        capabilities,
        startTime,
        uri,
        nodeId,
        nodeUri,
        sessionDurationMillis
        slot : {
            id,
            stereotype,
            lastStarted
        }
    }
    grid: {
        uri,
        totalSlots,
        nodeCount,
        maxSession,
        sessionCount,
        version,
        sessionQueueSize
    }
    sessionsInfo: {
        sessionQueueRequests,
        sessions: [
            {
                id,
                capabilities,
                startTime,
                uri,
                nodeId,
                nodeUri,
                sessionDurationMillis
                slot : {
                    id,
                    stereotype,
                    lastStarted
                }
            }
        ]
    }
    nodesInfo: {
        nodes : [
            {
                id,
                uri,
                status,
                maxSession,
                slotCount,
                sessions: [
                    {
                        id,
                        capabilities,
                        startTime,
                        uri,
                        nodeId,
                        nodeUri,
                        sessionDurationMillis
                        slot : {
                            id,
                            stereotype,
                            lastStarted
                        }
                    }
                ],
                sessionCount,
                stereotypes,
                version,
                osInfo: {
                    arch,
                    name,
                    version
                }
            }
        ]
    }
}
```

## 查询 GraphQL

查询GraphQL的最佳方法是使用`curl`请求. GraphQL允许您仅获取所需的数据, 仅此而已.

下面给出了一些GraphQL查询的示例. 您可以根据需要构建自己的查询.

### 查询网格中 `maxSession` 和 `sessionCount` 的数量:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ grid { maxSession, sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

通常在本地机器上 `<LINK_TO_GRAPHQL_ENDPOINT>` 会是 `http://localhost:4444/graphql`

### 查询全部会话、及节点以及网格的详情 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { uri, maxSession, sessionCount }, nodesInfo { nodes { id, uri, status, sessions { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } }, slotCount, sessionCount }} }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询以获取当前网格的会话总数 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询以获取网格中的最大会话数量 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { maxSession } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询以获取网格中所有节点的全部会话详情 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, capabilities, startTime, uri, nodeId, nodeId, sessionDurationMillis } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询以获取网格中每个节点中所有会话的插槽信息 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, slot { id, stereotype, lastStarted } } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询以获取给定会话的会话信息查询以获取给定会话的会话信息 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ session (id: \"<session-id>\") { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } } } "}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询网格中每个节点的功能 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { stereotypes } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询网格中每个节点的状态 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { status } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询每个节点和网格的 URI :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { uri } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the current requests in the New Session Queue:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessionQueueRequests } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the New Session Queue size :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionQueueSize } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

# 3 - Grid端点

## Grid

### Grid 状态

Grid状态提供Grid的当前状态. 它包含每个注册节点的详细信息. 对于每个节点, 状态包括有关节点可用性、会话和插槽的信息.

```shell
curl --request GET 'http://localhost:4444/status'
```

### 删除会话

删除会话会终止 WebDriver 会话、退出驱动程序并将其从活动会话映射中删除。任何使用删除的会话标识或重新使用驱动程序实例的请求都会出错。

```shell
curl --request DELETE 'http://localhost:4444/session/<session-id>'
```

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret> '
```

在完全分布式模式下, URL是分发器的地址。

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

如果在设置Grid时未配置注册密码, 则使用

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET;'
```

### 释放节点

节点释放命令用于优雅地关闭节点。在所有正在进行的会话结束后，会停止该节点。并且，它不会接受任何新的会话请求。

在 Standalone 模式下，分发器 URL 是独立服务器地址。

在 Hub-Node 模式下, 分发器 URL 是 Hub 服务器的地址。

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret> '
```

在完全分布式模式下, URL是分发服务器的地址。

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

如果在设置Grid时未配置注册密码, 则使用

```shell
curl --request POST 'http://<Router-URL>/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET;'
```

## 节点

本节中的端点适用于 Hub-Node 模式和节点独立运行的完全分布式网格模式。在一个节点的情况下, 默认节点的URL为 http\://localhost:5555 。 如果有多个节点,请使用 [Grid 状态](/zh-cn/documentation/grid/advanced_features/endpoints/#grid-%e7%8a%b6%e6%80%81) 获取所有节点的详细信息并查找节点地址。

### 状态

节点状态本质上是节点的健康检查。分发程序会定期 ping 节点状态，并相应地更新 Grid 模型。状态包括有关可用性、会话和插槽的信息。

```shell
curl --request GET 'http://localhost:5555/status'
```

### 释放

分发器将 [释放](/zh-cn/documentation/grid/advanced_features/endpoints/#%e9%87%8a%e6%94%be%e8%8a%82%e7%82%b9) 命令传递给由node-id标识的相应节点。要直接释放节点,请使用下面列出的curl命令。 两个端点都有效并产生相同的结果。释放会等待持续中的会话完成后才停止节点。

```shell
curl --request POST 'http://localhost:5555/se/grid/node/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

如果在设置Grid时未配置注册密码,则使用

```shell
curl --request POST 'http://<node-URL>/se/grid/node/drain' --header 'X-REGISTRATION-SECRET;'
```

### 检查会话所有者

要检查会话是否属于某一节点, 请使用下面列出的curl命令.

```shell
curl --request GET 'http://localhost:5555/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

如果在设置Grid时未配置注册密码, 则使用

```shell
curl --request GET 'http://<node-URL>/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

如果会话属于该节点, 则返回true, 否则返回false。

### 删除会话

删除会话会终止 WebDriver 会话、退出驱动程序并将其从活动会话映射中删除。任何使用删除的会话标识或重新使用驱动程序实例的请求都会出错。

```shell
curl --request DELETE 'http://localhost:5555/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

如果在设置Grid时未配置注册密码, 则使用

```shell
curl --request DELETE 'http://<node-URL>/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

## 新会话队列

### 清除新会话队列

新会话请求队列保存新会话请求。要清除队列，请使用下面列出的 curl 命令。清除队列会拒绝队列中的所有请求。对于每个此类请求，服务器都会向相应的客户端返回错误响应。清除命令的结果是被删除请求的总数。

在 Standalone 模式下, 队列URL是独立服务器的地址。 在 Hub-Node 模式下, 队列URL是集线器服务器的地址。

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

在完全分布式模式下, 队列URL是新会话队列服务器的地址。

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

如果在设置Grid时未配置注册密码, 则使用

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET;'
```

### 获取新会话队列请求

新会话请求队列保存新会话请求。 要获取队列中的当前请求, 请使用下面列出的curl命令。 响应会返回队列中的请求总数以及请求内容。

在 Standalone 模式下, 队列URL是独立服务器的地址。 在 Hub-Node 模式下, 队列URL是集线器服务器的地址。

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

在完全分布式模式下, 队列URL是新会话队列服务器的地址。

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

# 4 - 自定义Node

```bash
java -jar custom_node-server.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

```bash
java -jar selenium-server-4.6.0.jar \
--ext custom_node-1.0-SNAPSHOT.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

下面是一个示例：当Node有相关活动（会话创建、会话删除、WebDriver 命令执行等）时，仅在控制台打印一些消息。

自定义Node示例

```java
package org.seleniumhq.samples;

import java.net.URI;
import java.util.UUID;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.NoSuchSessionException;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.grid.config.Config;
import org.openqa.selenium.grid.data.CreateSessionRequest;
import org.openqa.selenium.grid.data.CreateSessionResponse;
import org.openqa.selenium.grid.data.NodeId;
import org.openqa.selenium.grid.data.NodeStatus;
import org.openqa.selenium.grid.data.Session;
import org.openqa.selenium.grid.log.LoggingOptions;
import org.openqa.selenium.grid.node.HealthCheck;
import org.openqa.selenium.grid.node.Node;
import org.openqa.selenium.grid.node.local.LocalNodeFactory;
import org.openqa.selenium.grid.security.Secret;
import org.openqa.selenium.grid.security.SecretOptions;
import org.openqa.selenium.grid.server.BaseServerOptions;
import org.openqa.selenium.internal.Either;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
import org.openqa.selenium.remote.tracing.Tracer;

public class DecoratedLoggingNode extends Node {

  private Node node;

  protected DecoratedLoggingNode(Tracer tracer, NodeId nodeId, URI uri, Secret registrationSecret, Duration sessionTimeout) {
    super(tracer, nodeId, uri, registrationSecret, sessionTimeout);
  }

  public static Node create(Config config) {
    LoggingOptions loggingOptions = new LoggingOptions(config);
    BaseServerOptions serverOptions = new BaseServerOptions(config);
    URI uri = serverOptions.getExternalUri();
    SecretOptions secretOptions = new SecretOptions(config);
    NodeOptions nodeOptions = new NodeOptions(config);
    Duration sessionTimeout = nodeOptions.getSessionTimeout();

    // Refer to the foot notes for additional context on this line.
    Node node = LocalNodeFactory.create(config);

    DecoratedLoggingNode wrapper = new DecoratedLoggingNode(loggingOptions.getTracer(),
        node.getId(),
        uri,
        secretOptions.getRegistrationSecret(),
        sessionTimeout);
    wrapper.node = node;
    return wrapper;
  }

  @Override
  public Either<WebDriverException, CreateSessionResponse> newSession(
      CreateSessionRequest sessionRequest) {
    System.out.println("Before newSession()");
    try {
      return this.node.newSession(sessionRequest);
    } finally {
      System.out.println("After newSession()");
    }
  }

  @Override
  public HttpResponse executeWebDriverCommand(HttpRequest req) {
    try {
      System.out.println("Before executeWebDriverCommand(): " + req.getUri());
      return node.executeWebDriverCommand(req);
    } finally {
      System.out.println("After executeWebDriverCommand()");
    }
  }

  @Override
  public Session getSession(SessionId id) throws NoSuchSessionException {
    try {
      System.out.println("Before getSession()");
      return node.getSession(id);
    } finally {
      System.out.println("After getSession()");
    }
  }

  @Override
  public HttpResponse uploadFile(HttpRequest req, SessionId id) {
    try {
      System.out.println("Before uploadFile()");
      return node.uploadFile(req, id);
    } finally {
      System.out.println("After uploadFile()");
    }
  }

  @Override
  public void stop(SessionId id) throws NoSuchSessionException {
    try {
      System.out.println("Before stop()");
      node.stop(id);
    } finally {
      System.out.println("After stop()");
    }
  }

  @Override
  public boolean isSessionOwner(SessionId id) {
    try {
      System.out.println("Before isSessionOwner()");
      return node.isSessionOwner(id);
    } finally {
      System.out.println("After isSessionOwner()");
    }
  }

  @Override
  public boolean isSupporting(Capabilities capabilities) {
    try {
      System.out.println("Before isSupporting");
      return node.isSupporting(capabilities);
    } finally {
      System.out.println("After isSupporting()");
    }
  }

  @Override
  public NodeStatus getStatus() {
    try {
      System.out.println("Before getStatus()");
      return node.getStatus();
    } finally {
      System.out.println("After getStatus()");
    }
  }

  @Override
  public HealthCheck getHealthCheck() {
    try {
      System.out.println("Before getHealthCheck()");
      return node.getHealthCheck();
    } finally {
      System.out.println("After getHealthCheck()");
    }
  }

  @Override
  public void drain() {
    try {
      System.out.println("Before drain()");
      node.drain();
    } finally {
      System.out.println("After drain()");
    }

  }

  @Override
  public boolean isReady() {
    try {
      System.out.println("Before isReady()");
      return node.isReady();
    } finally {
      System.out.println("After isReady()");
    }
  }
}
```

***注释：***

在上述示例中，`Node node = LocalNodeFactory.create(config);` 这一行显式创建了一个 `LocalNode`。

`org.openqa.selenium.grid.node.Node` 主要有两种*面向用户的实现*。

这些类是学习如何构建自定义 Node 以及了解 Node 内部机制的良好起点。

* `org.openqa.selenium.grid.node.local.LocalNode` - 用于表示长时间运行的 Node，也是默认实现。启动 `node` 时会自动接入。

  * 可通过 `LocalNodeFactory.create(config);` 创建，其中：

    * `LocalNodeFactory` 属于 `org.openqa.selenium.grid.node.local`
    * `Config` 属于 `org.openqa.selenium.grid.config`

* `org.openqa.selenium.grid.node.k8s.OneShotNode` - 这是一个特殊的参考实现，节点在服务完一个测试会话后会自动关闭。该类目前未包含在任何预构建的 maven 包中。

  * 你可以在 [这里](https://github.com/SeleniumHQ/selenium/blob/trunk/java/src/org/openqa/selenium/grid/node/k8s/OneShotNode.java) 查看源码。

  * 参考 [这里](https://github.com/SeleniumHQ/selenium/blob/trunk/deploys/k8s/README.md) 了解本地构建方法。

  * 可通过 `OneShotNode.create(config)` 创建，其中：

    * `OneShotNode` 属于 `org.openqa.selenium.grid.node.k8s`
    * `Config` 属于 `org.openqa.selenium.grid.config`

# 5 - External datastore

```sql
CREATE TABLE IF NOT EXISTS sessions_map(
    session_ids varchar(256),
    session_caps text,
    session_uri varchar(256),
    session_stereotype text,
    session_start varchar(256)
 );
```

* In the same directory as the `init.sql`, create a file named `docker-compose.yml` with its contents as below:

```yaml
version: '3.8'
services:
  db:
    image: postgres:9.6-bullseye
    restart: always
    environment:
      - POSTGRES_USER=seluser
      - POSTGRES_PASSWORD=seluser
      - POSTGRES_DB=selenium_sessions
    ports:
      - "5432:5432"
    volumes:
    - ./init.sql:/docker-entrypoint-initdb.d/init.sql
```

We can now start our database container by running:

```bash
docker-compose up -d
```

*Our database name is `selenium_sessions` with its username and password set to `seluser`*

If you are working with an already running PostGreSQL DB instance, then you just need to create a database named `selenium_sessions` and the table `sessions_map` using the above mentioned SQL statement.

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
implementation = "org.openqa.selenium.grid.sessionmap.jdbc.JdbcBackedSessionMap"
jdbc-url = "jdbc:postgresql://localhost:5432/selenium_sessions"
jdbc-user = "seluser"
jdbc-password = "seluser"
```

*Note:* If you plan to use an existing PostGreSQL DB instance, then replace `localhost:5432` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed Grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Sessions Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

```yaml
version: '3.8'
services:
  redis:
    image: redis:bullseye
    restart: always
    ports:
      - "6379:6379"
```

We can now start our Redis container by running:

```bash
docker-compose up -d
```

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
scheme = "redis"
implementation = "org.openqa.selenium.grid.sessionmap.redis.RedisBackedSessionMap"
hostname = "localhost"
port = 6379
```

*Note:* If you plan to use an existing Redis Cache instance, then replace `localhost` and `6379` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Session Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

* At this point the current directory should contain the following files:

  * `docker-compose.yml`
  * `sessions.toml`
  * `distributed.sh`

* You can now spawn the Grid by running `distributed.sh` shell script and quickly run a test. You will notice that the Grid now stores session information into the Redis instance. You can perhaps make use of a Redis GUI such as [TablePlus](https://tableplus.com/) to see them (Make sure that you have setup a debug point in your test, because the values will get deleted as soon as the test runs to completion).

In the line which spawns a `SessionMap` on a machine:

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

----
url: https://www.selenium.dev/documentation/grid/advanced_features/endpoints/
----

# Grid endpoints

## Grid

### Grid Status

Grid status provides the current state of the Grid. It consists of details about every registered Node. For every Node, the status includes information regarding Node availability, sessions, and slots.

```shell
curl --request GET 'http://localhost:4444/status'
```

### Delete session

Deleting the session terminates the WebDriver session, quits the driver and removes it from the active sessions map. Any request using the removed session-id or reusing the driver instance will throw an error.

```shell
curl --request DELETE 'http://localhost:4444/session/<session-id>'
```

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret> '
```

In the fully distributed mode, the URL is the Router server address.

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET;'
```

### Drain Node

Node drain command is for graceful node shutdown. Draining a Node stops the Node after all the ongoing sessions are complete. However, it does not accept any new session requests.

In the Standalone mode, the Distributor URL is the Standalone server address.

In the Hub-Node mode, the Distributor URL is the Hub server address.

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret> '
```

In the fully distributed mode, the URL is the Router server address.

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request POST 'http://<Router-URL>/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET;'
```

## Node

The endpoints in this section are applicable for Hub-Node mode and fully distributed Grid mode where the Node runs independently. The default Node URL is http\://localhost:5555 in case of one Node. In case of multiple Nodes, use [Grid status](/documentation/grid/advanced_features/endpoints/#grid-status) to get all Node details and locate the Node address.

### Status

The Node status is essentially a health-check for the Node. Distributor pings the node status at regular intervals and updates the Grid Model accordingly. The status includes information regarding availability, sessions, and slots.

```shell
curl --request GET 'http://localhost:5555/status'
```

### Drain

Distributor passes the [drain](/documentation/grid/advanced_features/endpoints/#drain-node) command to the appropriate node identified by the node-id. To drain the Node directly, use the curl command enlisted below. Both endpoints are valid and produce the same result. Drain finishes the ongoing sessions before stopping the Node.

```shell
curl --request POST 'http://localhost:5555/se/grid/node/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request POST 'http://<node-URL>/se/grid/node/drain' --header 'X-REGISTRATION-SECRET;'
```

### Check session owner

To check if a session belongs to a Node, use the curl command enlisted below.

```shell
curl --request GET 'http://localhost:5555/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request GET 'http://<node-URL>/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

It will return true if the session belongs to the Node else it will return false.

### Delete session

Deleting the session terminates the WebDriver session, quits the driver and removes it from the active sessions map. Any request using the removed session-id or reusing the driver instance will throw an error.

```shell
curl --request DELETE 'http://localhost:5555/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request DELETE 'http://<node-URL>/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

## New Session Queue

### Clear New Session Queue

New Session Request Queue holds the new session requests. To clear the queue, use the curl command enlisted below. Clearing the queue rejects all the requests in the queue. For each such request, the server returns an error response to the respective client. The result of the clear command is the total number of deleted requests.

In the Standalone mode, the Queue URL is the Standalone server address.

In the Hub-Node mode, the Queue URL is the Hub server address.

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

In the fully distributed mode, the Queue URL is Router server address.

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET;'
```

### Get New Session Queue Requests

New Session Request Queue holds the new session requests. To get the current requests in the queue, use the curl command enlisted below. The response returns the total number of requests in the queue and the request payloads.

In the Standalone mode, the Queue URL is the Standalone server address.

In the Hub-Node mode, the Queue URL is the Hub server address.

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

In the fully distributed mode, the Queue URL is Router server address.

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/drivers/http_client/
----

# Configuração do Cliente HTTP

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import org.openqa.selenium.remote.http.ClientConfig;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import java.io.FileInputStream;
import java.net.URL;
import java.nio.file.Path;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.time.Duration;

import org.openqa.selenium.UsernameAndPassword;

import static java.net.http.HttpClient.Version.HTTP_1_1;

public class HttpClientTest extends BaseTest {
    URL gridUrl;

    @BeforeEach
    public void startGrid() {
        gridUrl = startStandaloneGridAdvanced();
    }

    @Test
    public void remoteWebDriverWithClientConfig() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createSSLContextWithCA(Path.of("src/test/resources/tls.crt").toAbsolutePath().toString()))
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
    }

    @Test
    public void remoteWebDriverIgnoreSSL() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createIgnoreSSLContext())
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
    }

    @Test
    public void remoteWebDriverWithEmbedAuthUrl() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createSSLContextWithCA(Path.of("src/test/resources/tls.crt").toAbsolutePath().toString()))
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(embedAuthToUrl(gridUrl, "admin", "myStrongPassword"))
                .config(clientConfig)
                .build();
    }

    private URL embedAuthToUrl(URL url, String username, String password) throws Exception {
        String userInfo = username + ":" + password;
        String urlWithAuth = url.getProtocol() + "://" + userInfo + "@" + url.getHost() + ":" + url.getPort() + url.getPath();
        return new URL(urlWithAuth);
    }

    public static SSLContext createSSLContextWithCA(String caCertPath) throws Exception {
        FileInputStream fis = new FileInputStream(caCertPath);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate caCert = (X509Certificate) cf.generateCertificate(fis);
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, null);
        keyStore.setCertificateEntry("caCert", caCert);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(keyStore);
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);
        return sslContext;
    }

    public static SSLContext createIgnoreSSLContext() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    }
                }
        };
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
        return sslContext;
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/HttpClientTest.java)

```py
import os
import pytest
import sys
from urllib3.util import Retry, Timeout
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType
from selenium.webdriver.remote.client_config import ClientConfig


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_with_client_config(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    retries = Retry(connect=2, read=2, redirect=2)
    timeout = Timeout(connect=300, read=3600)
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 init_args_for_pool_manager={
                                     "init_args_for_pool_manager": {"retries": retries, "timeout": timeout}},
                                 ca_certs=_get_resource_path("tls.crt"),
                                 username="admin", password="myStrongPassword")
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_ignore_certs(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 timeout=3600,
                                 ignore_certificates=True,
                                 username="admin", password="myStrongPassword")
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


def _get_resource_path(file_name: str):
    if os.path.abspath("").endswith("tests"):
        path = os.path.abspath(f"resources/{file_name}")
    else:
        path = os.path.abspath(f"tests/resources/{file_name}")
    return path

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_http_client.py)

[Add Example](/documentation/about/contributing/#creating-examples)

```rb

  it 'sets client configuration' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/http_client_spec.rb#L7-L8)

##### /examples/ruby/spec/drivers/http\_client\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'HTTP Client' do
  let(:url) { 'https://www.selenium.dev/selenium/web/' }

  it 'sets client configuration' do
    client = Selenium::WebDriver::Remote::Http::Default.new(open_timeout: 30, read_timeout: 30)
    expect(client.open_timeout).to eq 30
  end

  it 'uses the custom http client' do
    client = Selenium::WebDriver::Remote::Http::Default.new
    driver = Selenium::WebDriver.for :chrome, http_client: client
    driver.get(url)
    driver.quit
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/interactions/
----

# 浏览器交互

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java#L15)

##### /examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class InteractionsTest extends BaseChromeTest {
    @Test
    public void getTitle() {
        driver.get("https://www.selenium.dev/");
        // get title
        String title = driver.getTitle();
        Assertions.assertEquals(title, "Selenium");
    }

    @Test
    public void getCurrentUrl() {
        driver.get("https://www.selenium.dev/");
        // get current url
        String url = driver.getCurrentUrl();
        Assertions.assertEquals(url, "https://www.selenium.dev/");
    }
}
```

```py
title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_interactions.py#L7)

##### /examples/python/tests/interactions/test\_interactions.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")

title = driver.title
assert title == "Selenium"

url = driver.current_url
assert url == "https://www.selenium.dev/"

driver.quit()
```

```cs
            String title = driver.Title;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs#L37)

##### /examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class InteractionsTest
    {
        [TestMethod]
        public void TestInteractions()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url="https://www.selenium.dev/";
            //GetTitle
            String title = driver.Title;
            Assert.AreEqual(title, "Selenium");

            //GetCurrentURL
            String url = driver.Url;
            Assert.AreEqual(url, "https://www.selenium.dev/");

            //quitting driver
            driver.Quit(); //close all windows
        }
    }
}
```

```rb
  it 'gets the current title' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/browser_spec.rb#L8)

##### /examples/ruby/spec/interactions/browser\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'gets the current title' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_title = driver.title
    expect(current_title).to eq 'Selenium'
  end

  it 'gets the current url' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_url = driver.current_url
    expect(current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    let title = await driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/interactionsIndex.spec.js#L20)

##### /examples/javascript/test/interactions/interactionsIndex.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Should be able to get title and current url', async function () {
    const url = 'https://www.selenium.dev/';
    await driver.get(url);

    //Get Current title
    let title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Get Current url
    let currentUrl = await driver.getCurrentUrl();
    assert.equal(currentUrl, url);
  });
});
```

```kotlin
driver.title
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java#L26)

##### /examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class InteractionsTest extends BaseChromeTest {
    @Test
    public void getTitle() {
        driver.get("https://www.selenium.dev/");
        // get title
        String title = driver.getTitle();
        Assertions.assertEquals(title, "Selenium");
    }

    @Test
    public void getCurrentUrl() {
        driver.get("https://www.selenium.dev/");
        // get current url
        String url = driver.getCurrentUrl();
        Assertions.assertEquals(url, "https://www.selenium.dev/");
    }
}
```

```py
url = driver.current_url
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_interactions.py#L10)

##### /examples/python/tests/interactions/test\_interactions.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")

title = driver.title
assert title == "Selenium"

url = driver.current_url
assert url == "https://www.selenium.dev/"

driver.quit()
```

```cs
            String url = driver.Url;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs#L41)

##### /examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class InteractionsTest
    {
        [TestMethod]
        public void TestInteractions()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url="https://www.selenium.dev/";
            //GetTitle
            String title = driver.Title;
            Assert.AreEqual(title, "Selenium");

            //GetCurrentURL
            String url = driver.Url;
            Assert.AreEqual(url, "https://www.selenium.dev/");

            //quitting driver
            driver.Quit(); //close all windows
        }
    }
}
```

```rb
  it 'gets the current url' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/browser_spec.rb#L14)

##### /examples/ruby/spec/interactions/browser\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'gets the current title' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_title = driver.title
    expect(current_title).to eq 'Selenium'
  end

  it 'gets the current url' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_url = driver.current_url
    expect(current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    let currentUrl = await driver.getCurrentUrl();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/interactionsIndex.spec.js#L24)

##### /examples/javascript/test/interactions/interactionsIndex.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Should be able to get title and current url', async function () {
    const url = 'https://www.selenium.dev/';
    await driver.get(url);

    //Get Current title
    let title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Get Current url
    let currentUrl = await driver.getCurrentUrl();
    assert.equal(currentUrl, url);
  });
});
```

```kotlin
driver.currentUrl
```

***

##### [浏览器导航](/zh-cn/documentation/webdriver/interactions/navigation/)

##### [JavaScript 警告框,提示框和确认框](/zh-cn/documentation/webdriver/interactions/alerts/)

##### [同cookies一起工作](/zh-cn/documentation/webdriver/interactions/cookies/)

##### [与IFrames和frames一起工作](/zh-cn/documentation/webdriver/interactions/frames/)

##### [打印页面](/zh-cn/documentation/webdriver/interactions/print_page/)

##### [同窗口和标签一起工作](/zh-cn/documentation/webdriver/interactions/windows/)

##### [虚拟身份验证器](/zh-cn/documentation/webdriver/interactions/virtual_authenticator/)

一种Web身份验证器模型的表示形式.

----
url: https://www.selenium.dev/ja/documentation/webdriver/interactions/
----

# ブラウザのインタラクション

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java#L15)

##### /examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class InteractionsTest extends BaseChromeTest {
    @Test
    public void getTitle() {
        driver.get("https://www.selenium.dev/");
        // get title
        String title = driver.getTitle();
        Assertions.assertEquals(title, "Selenium");
    }

    @Test
    public void getCurrentUrl() {
        driver.get("https://www.selenium.dev/");
        // get current url
        String url = driver.getCurrentUrl();
        Assertions.assertEquals(url, "https://www.selenium.dev/");
    }
}
```

```py
title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_interactions.py#L7)

##### /examples/python/tests/interactions/test\_interactions.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")

title = driver.title
assert title == "Selenium"

url = driver.current_url
assert url == "https://www.selenium.dev/"

driver.quit()
```

```cs
            String title = driver.Title;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs#L37)

##### /examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class InteractionsTest
    {
        [TestMethod]
        public void TestInteractions()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url="https://www.selenium.dev/";
            //GetTitle
            String title = driver.Title;
            Assert.AreEqual(title, "Selenium");

            //GetCurrentURL
            String url = driver.Url;
            Assert.AreEqual(url, "https://www.selenium.dev/");

            //quitting driver
            driver.Quit(); //close all windows
        }
    }
}
```

```rb
  it 'gets the current title' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/browser_spec.rb#L8)

##### /examples/ruby/spec/interactions/browser\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'gets the current title' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_title = driver.title
    expect(current_title).to eq 'Selenium'
  end

  it 'gets the current url' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_url = driver.current_url
    expect(current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    let title = await driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/interactionsIndex.spec.js#L20)

##### /examples/javascript/test/interactions/interactionsIndex.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Should be able to get title and current url', async function () {
    const url = 'https://www.selenium.dev/';
    await driver.get(url);

    //Get Current title
    let title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Get Current url
    let currentUrl = await driver.getCurrentUrl();
    assert.equal(currentUrl, url);
  });
});
```

```kotlin
driver.title
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java#L26)

##### /examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class InteractionsTest extends BaseChromeTest {
    @Test
    public void getTitle() {
        driver.get("https://www.selenium.dev/");
        // get title
        String title = driver.getTitle();
        Assertions.assertEquals(title, "Selenium");
    }

    @Test
    public void getCurrentUrl() {
        driver.get("https://www.selenium.dev/");
        // get current url
        String url = driver.getCurrentUrl();
        Assertions.assertEquals(url, "https://www.selenium.dev/");
    }
}
```

```py
url = driver.current_url
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_interactions.py#L10)

##### /examples/python/tests/interactions/test\_interactions.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")

title = driver.title
assert title == "Selenium"

url = driver.current_url
assert url == "https://www.selenium.dev/"

driver.quit()
```

```cs
            String url = driver.Url;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs#L41)

##### /examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class InteractionsTest
    {
        [TestMethod]
        public void TestInteractions()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url="https://www.selenium.dev/";
            //GetTitle
            String title = driver.Title;
            Assert.AreEqual(title, "Selenium");

            //GetCurrentURL
            String url = driver.Url;
            Assert.AreEqual(url, "https://www.selenium.dev/");

            //quitting driver
            driver.Quit(); //close all windows
        }
    }
}
```

```rb
  it 'gets the current url' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/browser_spec.rb#L14)

##### /examples/ruby/spec/interactions/browser\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'gets the current title' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_title = driver.title
    expect(current_title).to eq 'Selenium'
  end

  it 'gets the current url' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_url = driver.current_url
    expect(current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    let currentUrl = await driver.getCurrentUrl();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/interactionsIndex.spec.js#L24)

##### /examples/javascript/test/interactions/interactionsIndex.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Should be able to get title and current url', async function () {
    const url = 'https://www.selenium.dev/';
    await driver.get(url);

    //Get Current title
    let title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Get Current url
    let currentUrl = await driver.getCurrentUrl();
    assert.equal(currentUrl, url);
  });
});
```

```kotlin
driver.currentUrl
```

***

##### [ブラウザー ナビゲーション](/ja/documentation/webdriver/interactions/navigation/)

##### [JavaScript アラート、プロンプトおよび確認](/ja/documentation/webdriver/interactions/alerts/)

##### [クッキーの使用](/ja/documentation/webdriver/interactions/cookies/)

##### [IFrame と Frame の操作](/ja/documentation/webdriver/interactions/frames/)

##### [Print Page](/ja/documentation/webdriver/interactions/print_page/)

##### [ウィンドウとタブの操作](/ja/documentation/webdriver/interactions/windows/)

##### [Virtual Authenticator](/ja/documentation/webdriver/interactions/virtual_authenticator/)

A representation of the Web Authenticator model.

----
url: https://www.selenium.dev/zh-cn/_print/documentation/test_practices/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/test_practices/).

# 鼓励的行为

Selenium项目的一些测试指南和建议.

* 1: [测试自动化概述](#pg-95463f9f08ab9b45822eb4db4e4f8319)
* 2: [设计模式和开发策略](#pg-6ac5cebe2b8df6bdf4a32c2ff87c8102)
* 3: [测试类型](#pg-dd0cceff6f2eda0a41e7565c12418f2e)
* 4: [指南和建议](#pg-3adeefbf55b891277e0d61644d37e819)
* * 4.1: [PO设计模式](#pg-a07d818fdd319e2c92a8acc85ef8a3e8)
  * 4.2: [领域特定语言](#pg-eff46b072335747496ab495afaa216a4)
  * 4.3: [生成应用程序状态](#pg-7c284c8ef2a809f491abaacf4bc8174e)
  * 4.4: [模拟外部服务](#pg-17499bca0a70e7307770deb1aeed0396)
  * 4.5: [改善报告](#pg-7ac05e3d898ebefa61aea590b371bb90)
  * 4.6: [避免共享状态](#pg-771c393afbab1342a428f0976ae22ab2)
  * 4.7: [使用定位器的提示](#pg-fa48c36df684f7be6ce81e5e93388b9e)
  * 4.8: [测试的独立性](#pg-dfe07108b6d0f913b964fe6e4338d5ba)
  * 4.9: [考虑使用Fluent API](#pg-40d1fd2b426846ea61f9362119eb7b4b)
  * 4.10: [每次测试都刷新浏览器](#pg-3ce2b89debe65906eae5f1da85962607)
  5: [不鼓励的行为](#pg-b71f51b4e474502507b0841f5d152d1a)
  * 5.1: [验证码](#pg-12a8f4e30343b86339acb24c22b1d4ae)
  * 5.2: [文件下载](#pg-1223ebcabcfa4c9b6ea24c5aaffbc509)
  * 5.3: [HTTP响应码](#pg-5f748c8597e92ebc444be6a9c4e7cdd3)
  * 5.4: [Gmail, email 和 Facebook 登录](#pg-9bdc1ce1d6b5b575d611d3c7acfc776b)
  * 5.5: [测试依赖](#pg-e1315c8ae4a385f5b3b8b028ce8d9ebb)
  * 5.6: [性能测试](#pg-819c58e35cb5b37daaf82700a073a9a0)
  * 5.7: [爬取链接](#pg-38d1959cdf1a7c403cb4f29ca535baa9)
  * 5.8: [双因素认证](#pg-a18a4de15d62b2cf10d163ace06e1017)

关于"最佳实践"的注解：我们有意在本文档中避免使用"最佳实践"的说辞. 没有一种方法可以适用于所有情况. 我们更喜欢"指南和建议"的想法. 我们鼓励您通读这些内容, 并仔细地确定哪种方法适用于您的特定环境.

由于许多原因, 功能测试很难正确完成. 即便应用程序的状态, 复杂性, 依赖还不够让测试变得 足够复杂, 操作浏览器（特别是跨浏览器的兼容性测试）就已经使得写一个好的测试变成一种挑战.

Selenium提供了一些工具使得功能测试用户更简单的操作浏览器, 但是这些工具并不能帮助你来写一个好的 架构的测试套件. 这章我们会针对怎么来做web页面的功能测试的自动化给出一些忠告, 指南和建议.

这章记录了很多历年来成功的使用Selenium的用户的常用的软件设计模式.

# 1 - 测试自动化概述

```java
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
User user = UserFactory.createCommonUser(); //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
AccountPage accountPage = loginAs(user.getEmail(), user.getPassword());
  
```

```python
# Create a user who has read-only permissions--they can configure a unicorn,
# but they do not have payment information set up, nor do they have
# administrative privileges. At the time the user is created, its email
# address and password are randomly generated--you don't even need to
# know them.
user = user_factory.create_common_user() #This method is defined elsewhere.

# Log in as this user.
# Logging in on this site takes you to your personal "My Account" page, so the
# AccountPage object is returned by the loginAs method, allowing you to then
# perform actions from the AccountPage.
account_page = login_as(user.get_email(), user.get_password())
  
```

```csharp
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
User user = UserFactory.CreateCommonUser(); //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
AccountPage accountPage = LoginAs(user.Email, user.Password);
  
```

```ruby
# Create a user who has read-only permissions--they can configure a unicorn,
# but they do not have payment information set up, nor do they have
# administrative privileges. At the time the user is created, its email
# address and password are randomly generated--you don't even need to
# know them.
user = UserFactory.create_common_user #This method is defined elsewhere.

# Log in as this user.
# Logging in on this site takes you to your personal "My Account" page, so the
# AccountPage object is returned by the loginAs method, allowing you to then
# perform actions from the AccountPage.
account_page = login_as(user.email, user.password)
  
```

```javascript
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
var user = userFactory.createCommonUser(); //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
var accountPage = loginAs(user.email, user.password);
  
```

```kotlin
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
val user = UserFactory.createCommonUser() //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
val accountPage = loginAs(user.getEmail(), user.getPassword())
  
```

```java
// The Unicorn is a top-level Object--it has attributes, which are set here.
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
Unicorn sparkles = new Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS);

// Since we're already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.
AddUnicornPage addUnicornPage = accountPage.addUnicorn();

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
UnicornConfirmationPage unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles);
  
```

```python
# The Unicorn is a top-level Object--it has attributes, which are set here.
# This only stores the values; it does not fill out any web forms or interact
# with the browser in any way.
sparkles = Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

# Since we're already "on" the account page, we have to use it to get to the
# actual place where you configure unicorns. Calling the "Add Unicorn" method
# takes us there.
add_unicorn_page = account_page.add_unicorn()

# Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
# its createUnicorn() method. This method will take Sparkles' attributes,
# fill out the form, and click submit.
unicorn_confirmation_page = add_unicorn_page.create_unicorn(sparkles)
  
```

```csharp
// The Unicorn is a top-level Object--it has attributes, which are set here. 
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
Unicorn sparkles = new Unicorn("Sparkles", UnicornColors.Purple, UnicornAccessories.Sunglasses, UnicornAdornments.StarTattoos);

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.
AddUnicornPage addUnicornPage = accountPage.AddUnicorn();

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
UnicornConfirmationPage unicornConfirmationPage = addUnicornPage.CreateUnicorn(sparkles);
  
```

```ruby
# The Unicorn is a top-level Object--it has attributes, which are set here.
# This only stores the values; it does not fill out any web forms or interact
# with the browser in any way.
sparkles = Unicorn.new('Sparkles', UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

# Since we're already "on" the account page, we have to use it to get to the
# actual place where you configure unicorns. Calling the "Add Unicorn" method
# takes us there.
add_unicorn_page = account_page.add_unicorn

# Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
# its createUnicorn() method. This method will take Sparkles' attributes,
# fill out the form, and click submit.
unicorn_confirmation_page = add_unicorn_page.create_unicorn(sparkles)
  
```

```javascript
// The Unicorn is a top-level Object--it has attributes, which are set here.
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
var sparkles = new Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS);

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.

var addUnicornPage = accountPage.addUnicorn();

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
var unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles);

  
```

```kotlin
// The Unicorn is a top-level Object--it has attributes, which are set here. 
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
val sparkles = Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.
val addUnicornPage = accountPage.addUnicorn()

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles)

  
```

```java
// The exists() method from UnicornConfirmationPage will take the Sparkles
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
Assert.assertTrue("Sparkles should have been created, with all attributes intact", unicornConfirmationPage.exists(sparkles));
  
```

```python
# The exists() method from UnicornConfirmationPage will take the Sparkles
# object--a specification of the attributes you want to see, and compare
# them with the fields on the page.
assert unicorn_confirmation_page.exists(sparkles), "Sparkles should have been created, with all attributes intact"
  
```

```csharp
// The exists() method from UnicornConfirmationPage will take the Sparkles 
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
Assert.True(unicornConfirmationPage.Exists(sparkles), "Sparkles should have been created, with all attributes intact");
  
```

```ruby
# The exists() method from UnicornConfirmationPage will take the Sparkles
# object--a specification of the attributes you want to see, and compare
# them with the fields on the page.
expect(unicorn_confirmation_page.exists?(sparkles)).to be, 'Sparkles should have been created, with all attributes intact'
  
```

```javascript
// The exists() method from UnicornConfirmationPage will take the Sparkles
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
assert(unicornConfirmationPage.exists(sparkles), "Sparkles should have been created, with all attributes intact");

  
```

```kotlin
// The exists() method from UnicornConfirmationPage will take the Sparkles 
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
assertTrue("Sparkles should have been created, with all attributes intact", unicornConfirmationPage.exists(sparkles))
  
```

请注意，测试人员在这段代码中除了谈论独角兽之外还没有做任何事情 — 没有按钮、定位器和浏览器控件。 这种对应用程序建模的方法允许您保持这些测试级别的命令不变， 即使 Larry 下周决定不再喜欢 Ruby-on-Rails， 并决定用最新的带有 Fortran 前端的 Haskell 绑定重新实现整个站点。

为了符合站点的重新设计，您的页面对象需要进行一些小的维护，但是这些测试将保持不变。 采用这一基本设计，您将希望继续使用尽可能少的面向浏览器的步骤来完成您的工作流。 您的下一个工作流程将包括在购物车中添加独角兽。 您可能需要多次迭代此测试，以确保购物车正确地保持其状态： 在开始之前，购物车中是否有多个独角兽? 购物车能装多少? 如果您创建多个具有相同名称或特性，它会崩溃吗? 它将只保留现有的一个还是添加另一个?

每次通过工作流时，您都希望尽量避免创建帐户、以用户身份登录和配置独角兽。 理想情况下，您将能够创建一个帐户，并通过 API 或数据库预先配置独角兽。 然后，您只需作为用户登录，找到 Sparkles，并将它添加到购物车中。

### 是否自动化?

自动化总是有优势吗? 什么时候应该决定去自动化测试用例?

自动化测试用例并不总是有利的. 有时候手动测试可能更合适. 例如，如果应用程序的用户界面，在不久的将来会发生很大变化，那么任何自动化都可能需要重写. 此外，有时根本没有足够的时间来构建自动化测试. 从短期来看，手动测试可能更有效. 如果应用程序的截止日期非常紧迫，当前没有可用的自动化测试，并且必须在特定时间范围内完成，那么手动测试是最好的解决方案.

# 2 - 设计模式和开发策略

```java
package com.example.webdriver;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class EditIssue {

  private final WebDriver driver;

  public EditIssue(WebDriver driver) {
    this.driver = driver;
  }

  public void setTitle(String title) {
    WebElement field = driver.findElement(By.id("issue_title")));
    clearAndType(field, title);
  }

  public void setBody(String body) {
    WebElement field = driver.findElement(By.id("issue_body"));
    clearAndType(field, body);
  }

  public void setHowToReproduce(String howToReproduce) {
    WebElement field = driver.findElement(By.id("issue_form_repro-command"));
    clearAndType(field, howToReproduce);
  }

  public void setLogOutput(String logOutput) {
    WebElement field = driver.findElement(By.id("issue_form_logs"));
    clearAndType(field, logOutput);
  }

  public void setOperatingSystem(String operatingSystem) {
    WebElement field = driver.findElement(By.id("issue_form_operating-system"));
    clearAndType(field, operatingSystem);
  }

  public void setSeleniumVersion(String seleniumVersion) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-version"));
    clearAndType(field, logOutput);
  }

  public void setBrowserVersion(String browserVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-versions"));
    clearAndType(field, browserVersion);
  }

  public void setDriverVersion(String driverVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-driver-versions"));
    clearAndType(field, driverVersion);
  }

  public void setUsingGrid(String usingGrid) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-grid-version"));
    clearAndType(field, usingGrid);
  }

  public IssueList submit() {
    driver.findElement(By.cssSelector("button[type='submit']")).click();
    return new IssueList(driver);
  }

  private void clearAndType(WebElement field, String text) {
    field.clear();
    field.sendKeys(text);
  }
}
```

In order to turn this into a LoadableComponent, all we need to do is to set that as the base type:

```java
public class EditIssue extends LoadableComponent<EditIssue> {
  // rest of class ignored for now
}
```

This signature looks a little unusual, but it all means is that this class represents a LoadableComponent that loads the EditIssue page.

By extending this base class, we need to implement two new methods:

```java
  @Override
  protected void load() {
    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();
    assertTrue("Not on the issue entry page: " + url, url.endsWith("/new"));
  }
```

The `load` method is used to navigate to the page, whilst the `isLoaded` method is used to determine whether we are on the right page. Although the method looks like it should return a boolean, instead it performs a series of assertions using JUnit’s Assert class. There can be as few or as many assertions as you like. By using these assertions it’s possible to give users of the class clear information that can be used to debug tests.

With a little rework, our PageObject looks like:

```java
package com.example.webdriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

import static junit.framework.Assert.assertTrue;

public class EditIssue extends LoadableComponent<EditIssue> {

  private final WebDriver driver;
  
  // By default the PageFactory will locate elements with the same name or id
  // as the field. Since the issue_title element has an id attribute of "issue_title"
  // we don't need any additional annotations.
  private WebElement issue_title;
  
  // But we'd prefer a different name in our code than "issue_body", so we use the
  // FindBy annotation to tell the PageFactory how to locate the element.
  @FindBy(id = "issue_body") private WebElement body;
  
  public EditIssue(WebDriver driver) {
    this.driver = driver;
    
    // This call sets the WebElement fields.
    PageFactory.initElements(driver, this);
  }

  @Override
  protected void load() {
    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();
    assertTrue("Not on the issue entry page: " + url, url.endsWith("/new"));
  }

  public void setHowToReproduce(String howToReproduce) {
    WebElement field = driver.findElement(By.id("issue_form_repro-command"));
    clearAndType(field, howToReproduce);
  }

  public void setLogOutput(String logOutput) {
    WebElement field = driver.findElement(By.id("issue_form_logs"));
    clearAndType(field, logOutput);
  }

  public void setOperatingSystem(String operatingSystem) {
    WebElement field = driver.findElement(By.id("issue_form_operating-system"));
    clearAndType(field, operatingSystem);
  }

  public void setSeleniumVersion(String seleniumVersion) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-version"));
    clearAndType(field, logOutput);
  }

  public void setBrowserVersion(String browserVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-versions"));
    clearAndType(field, browserVersion);
  }

  public void setDriverVersion(String driverVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-driver-versions"));
    clearAndType(field, driverVersion);
  }

  public void setUsingGrid(String usingGrid) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-grid-version"));
    clearAndType(field, usingGrid);
  }

  public IssueList submit() {
    driver.findElement(By.cssSelector("button[type='submit']")).click();
    return new IssueList(driver);
  }

  private void clearAndType(WebElement field, String text) {
    field.clear();
    field.sendKeys(text);
  }
}
```

That doesn’t seem to have bought us much, right? One thing it has done is encapsulate the information about how to navigate to the page into the page itself, meaning that this information’s not scattered through the code base. It also means that we can do this in our tests:

```java
EditIssue page = new EditIssue(driver).get();
```

This call will cause the driver to navigate to the page if that’s necessary.

### Nested Components

LoadableComponents start to become more useful when they are used in conjunction with other LoadableComponents. Using our example, we could view the “edit issue” page as a component within a project’s website (after all, we access it via a tab on that site). You also need to be logged in to file an issue. We could model this as a tree of nested components:

```
 + ProjectPage
 +---+ SecuredPage
     +---+ EditIssue
```

What would this look like in code? For a start, each logical component would have its own class. The “load” method in each of them would “get” the parent. The end result, in addition to the EditIssue class above is:

ProjectPage.java:

```java
package com.example.webdriver;

import org.openqa.selenium.WebDriver;

import static org.junit.Assert.assertTrue;

public class ProjectPage extends LoadableComponent<ProjectPage> {

  private final WebDriver driver;
  private final String projectName;

  public ProjectPage(WebDriver driver, String projectName) {
    this.driver = driver;
    this.projectName = projectName;
  }

  @Override
  protected void load() {
    driver.get("http://" + projectName + ".googlecode.com/");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();

    assertTrue(url.contains(projectName));
  }
}
```

and SecuredPage.java:

```java
package com.example.webdriver;

import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import static org.junit.Assert.fail;

public class SecuredPage extends LoadableComponent<SecuredPage> {

  private final WebDriver driver;
  private final LoadableComponent<?> parent;
  private final String username;
  private final String password;

  public SecuredPage(WebDriver driver, LoadableComponent<?> parent, String username, String password) {
    this.driver = driver;
    this.parent = parent;
    this.username = username;
    this.password = password;
  }

  @Override
  protected void load() {
    parent.get();

    String originalUrl = driver.getCurrentUrl();

    // Sign in
    driver.get("https://www.google.com/accounts/ServiceLogin?service=code");
    driver.findElement(By.name("Email")).sendKeys(username);
    WebElement passwordField = driver.findElement(By.name("Passwd"));
    passwordField.sendKeys(password);
    passwordField.submit();

    // Now return to the original URL
    driver.get(originalUrl);
  }

  @Override
  protected void isLoaded() throws Error {
    // If you're signed in, you have the option of picking a different login.
    // Let's check for the presence of that.

    try {
      WebElement div = driver.findElement(By.id("multilogin-dropdown"));
    } catch (NoSuchElementException e) {
      fail("Cannot locate user name link");
    }
  }
}
```

The “load” method in EditIssue now looks like:

```java
  @Override
  protected void load() {
    securedPage.get();

    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }
```

This shows that the components are all “nested” within each other. A call to `get()` in EditIssue will cause all its dependencies to load too. The example usage:

```java
public class FooTest {
  private EditIssue editIssue;

  @Before
  public void prepareComponents() {
    WebDriver driver = new FirefoxDriver();

    ProjectPage project = new ProjectPage(driver, "selenium");
    SecuredPage securedPage = new SecuredPage(driver, project, "example", "top secret");
    editIssue = new EditIssue(driver, securedPage);
  }

  @Test
  public void demonstrateNestedLoadableComponents() {
    editIssue.get();

    editIssue.title.sendKeys('Title');
    editIssue.body.sendKeys('What Happened');
    editIssue.setHowToReproduce('How to Reproduce');
    editIssue.setLogOutput('Log Output');
    editIssue.setOperatingSystem('Operating System');
    editIssue.setSeleniumVersion('Selenium Version');
    editIssue.setBrowserVersion('Browser Version');
    editIssue.setDriverVersion('Driver Version');
    editIssue.setUsingGrid('I Am Using Grid');
  }
}
```

If you’re using a library such as [Guiceberry](https://github.com/zorzella/guiceberry) in your tests, the preamble of setting up the PageObjects can be omitted leading to nice, clear, readable tests.

## Bot Pattern

(previously located: <https://github.com/SeleniumHQ/selenium/wiki/Bot-Style-Tests>)

Although PageObjects are a useful way of reducing duplication in your tests, it’s not always a pattern that teams feel comfortable following. An alternative approach is to follow a more “command-like” style of testing.

A “bot” is an action-oriented abstraction over the raw Selenium APIs. This means that if you find that commands aren’t doing the Right Thing for your app, it’s easy to change them. As an example:

```java
public class ActionBot {
  private final WebDriver driver;

  public ActionBot(WebDriver driver) {
    this.driver = driver;
  }

  public void click(By locator) {
    driver.findElement(locator).click();
  }

  public void submit(By locator) {
    driver.findElement(locator).submit();
  }

  /** 
   * Type something into an input field. WebDriver doesn't normally clear these
   * before typing, so this method does that first. It also sends a return key
   * to move the focus out of the element.
   */
  public void type(By locator, String text) { 
    WebElement element = driver.findElement(locator);
    element.clear();
    element.sendKeys(text + "\n");
  }
}
```

```py
import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L6-L26)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L28-L65)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L67-L80)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L82-L172)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L174-L240)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

# 3 - 测试类型

### 验收测试

进行这种类型的测试以确定功能或系统是否满足客户的期望和要求. 这种测试通常涉及客户的合作或反馈, 是一种验证活动, 可以用于回答以下问题：

> 我们是否在制造 ***正确的*** 产品?

对于Web应用程序, 可以通过模拟用户期望的行为 直接使用Selenium来完成此测试的自动化. 可以通过记录/回放, 或通过本文档中介绍的各种支持的语言来完成此类模拟. 注意：有些人可能还会提到, 验收测试是 ***功能测试*** 的子类型.

### 功能测试

进行这种类型的测试是为了确定功能或系统是否正常运行而没有问题. 它会在不同级别检查系统, 以确保涵盖所有方案并且系统能够执行预期的 *工作* . 这是一个验证活动, 它回答了以下问题：

> 我们是否在 ***正确地*** 制造产品？

> For example, ***Testing that the site can handle numerous orders/users at once.***

#### 压力测试

进行压力测试, 以验证应用程序在压力 (或高于最大支持负载) 下的运行状况.

> For example, ***Testing that your ecommerce site can handle Black Friday***

> For example, ***Testing that your new search bar doesn’t break the other buttons on the menu***

# 4 - 指南和建议

Selenium项目的一些测试指南和建议.

关于"最佳实践"的注解：我们有意在本文档中避免使用"最佳实践"的说辞. 没有一种方法可以适用于所有情况. 我们更喜欢"指南和建议"的想法. 我们鼓励您通读这些内容, 并仔细地确定哪种方法适用于您的特定环境.

由于许多原因, 功能测试很难正确完成. 即便应用程序的状态, 复杂性, 依赖还不够让测试变得 足够复杂, 操作浏览器（特别是跨浏览器的兼容性测试）就已经使得写一个好的测试变成一种挑战.

Selenium提供了一些工具使得功能测试用户更简单的操作浏览器, 但是这些工具并不能帮助你来写一个好的 架构的测试套件. 这章我们会针对怎么来做web页面的功能测试的自动化给出一些忠告, 指南和建议.

这章记录了很多历年来成功的使用Selenium的用户的常用的软件设计模式.

# 4.1 - PO设计模式

```java
/***
 * Tests login feature
 */
public class Login {

  public void testLogin() {
    // fill login data on sign-in page
    driver.findElement(By.name("user_name")).sendKeys("userName");
    driver.findElement(By.name("password")).sendKeys("my supersecret password");
    driver.findElement(By.name("sign-in")).click();

    // verify h1 tag is "Hello userName" after login
    driver.findElement(By.tagName("h1")).isDisplayed();
    assertThat(driver.findElement(By.tagName("h1")).getText(), is("Hello userName"));
  }
}
```

There are two problems with this approach.

* There is no separation between the test method and the AUT’s locators (IDs in this example); both are intertwined in a single method. If the AUT’s UI changes its identifiers, layout, or how a login is input and processed, the test itself must change.
* The ID-locators would be spread in multiple tests, in all tests that had to use this login page.

Applying the page object model, this example could be rewritten like this in the following example of a page object for a Sign-in page.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Sign-in page.
 */
public class SignInPage {
  protected WebDriver driver;

  // <input name="user_name" type="text" value="">
  private By usernameBy = By.name("user_name");
  // <input name="password" type="password" value="">
  private By passwordBy = By.name("password");
  // <input name="sign_in" type="submit" value="SignIn">
  private By signinBy = By.name("sign_in");

  public SignInPage(WebDriver driver){
    this.driver = driver;
     if (!driver.getTitle().equals("Sign In Page")) {
      throw new IllegalStateException("This is not Sign In Page," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Login as valid user
    *
    * @param userName
    * @param password
    * @return HomePage object
    */
  public HomePage loginValidUser(String userName, String password) {
    driver.findElement(usernameBy).sendKeys(userName);
    driver.findElement(passwordBy).sendKeys(password);
    driver.findElement(signinBy).click();
    return new HomePage(driver);
  }
}
```

and page object for a Home page could look like this.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Home Page
 */
public class HomePage {
  protected WebDriver driver;

  // <h1>Hello userName</h1>
  private By messageBy = By.tagName("h1");

  public HomePage(WebDriver driver){
    this.driver = driver;
    if (!driver.getTitle().equals("Home Page of logged in user")) {
      throw new IllegalStateException("This is not Home Page of logged in user," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Get message (h1 tag)
    *
    * @return String message text
    */
  public String getMessageText() {
    return driver.findElement(messageBy).getText();
  }

  public HomePage manageProfile() {
    // Page encapsulation to manage profile functionality
    return new HomePage(driver);
  }
  /* More methods offering the services represented by Home Page
  of Logged User. These methods in turn might return more Page Objects
  for example click on Compose mail button could return ComposeMail class object */
}
```

So now, the login test would use these two page objects as follows.

```java
/***
 * Tests login feature
 */
public class TestLogin {

  @Test
  public void testLogin() {
    SignInPage signInPage = new SignInPage(driver);
    HomePage homePage = signInPage.loginValidUser("userName", "password");
    assertThat(homePage.getMessageText(), is("Hello userName"));
  }

}
```

```html
<!-- Products Page -->
<div class="header_container">
    <span class="title">Products</span>
</div>

<div class="inventory_list">
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
</div>
```

Each product is a component of the Products page.

```html
<!-- Inventory Item -->
<div class="inventory_item">
    <div class="inventory_item_name">Backpack</div>
    <div class="pricebar">
        <div class="inventory_item_price">$29.99</div>
        <button id="add-to-cart-backpack">Add to cart</button>
    </div>
</div>
```

The Products page HAS-A list of products. This object relationship is called Composition. In simpler terms, something is *composed of* another thing.

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

// Page Object
public class ProductsPage extends BasePage {
    public ProductsPage(WebDriver driver) {
        super(driver);
        // No assertions, throws an exception if the element is not loaded
        new WebDriverWait(driver, Duration.ofSeconds(3))
            .until(d -> d.findElement(By.className​("header_container")));
    }

    // Returning a list of products is a service of the page
    public List<Product> getProducts() {
        return driver.findElements(By.className​("inventory_item"))
            .stream()
            .map(e -> new Product(e)) // Map WebElement to a product component
            .toList();
    }

    // Return a specific product using a boolean-valued function (predicate)
    // This is the behavioral Strategy Pattern from GoF
    public Product getProduct(Predicate<Product> condition) {
        return getProducts()
            .stream()
            .filter(condition) // Filter by product name or price
            .findFirst()
            .orElseThrow(() -> new RuntimeException("Product not found")); // Error thrown during actual test run
    }
}
```

The Product component object is used inside the Products page object.

```java
public abstract class BaseComponent {
    protected WebElement root;

    public BaseComponent(WebElement root) {
        this.root = root;
    }
}

// Page Component Object
public class Product extends BaseComponent {
    // The root element contains the entire component
    public Product(WebElement root) {
        super(root); // inventory_item
    }

    public String getName() {
        // Locating an element begins at the root of the component
        return root.findElement(By.className("inventory_item_name")).getText();
    }

    public BigDecimal getPrice() {
        return new BigDecimal(
                root.findElement(By.className("inventory_item_price"))
                    .getText()
                    .replace("$", "")
            ).setScale(2, RoundingMode.UNNECESSARY); // Sanitation and formatting
    }

    public void addToCart() {
        root.findElement(By.id("add-to-cart-backpack")).click();
    }
}
```

So now, the products test would use the page object and the page component object as follows.

```java
public class ProductsTest {
    @Test
    public void testProductInventory() {
        var productsPage = new ProductsPage(driver); // page object
        var products = productsPage.getProducts();
        assertEquals(6, products.size()); // expected, actual
    }
    
    @Test
    public void testProductPrices() {
        var productsPage = new ProductsPage(driver);

        // Pass a lambda expression (predicate) to filter the list of products
        // The predicate or "strategy" is the behavior passed as parameter
        var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); // page component object
        var bikeLight = productsPage.getProduct(p -> p.getName().equals("Bike Light"));

        assertEquals(new BigDecimal("29.99"), backpack.getPrice());
        assertEquals(new BigDecimal("9.99"), bikeLight.getPrice());
    }
}
```

```java
public class LoginPage {
    public HomePage loginAs(String username, String password) {
        // ... clever magic happens here
    }
    
    public LoginPage loginAsExpectingError(String username, String password) {
        //  ... failed login here, maybe because one or both of the username and password are wrong
    }
    
    public String getErrorMessage() {
        // So we can verify that the correct error is shown
    }
}
```

The code presented above shows an important point: the tests, not the Page Objects, should be responsible for making assertions about the state of a page. For example:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    inbox.assertMessageWithSubjectIsUnread("I like cheese");
    inbox.assertMessageWithSubjectIsNotUnread("I'm not fond of tofu");
}
```

could be re-written as:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    assertTrue(inbox.isMessageWithSubjectIsUnread("I like cheese"));
    assertFalse(inbox.isMessageWithSubjectIsUnread("I'm not fond of tofu"));
}
```

```java
public class LoginPage {
    private final WebDriver driver;

    public LoginPage(WebDriver driver) {
        this.driver = driver;

        // Check that we're on the right page.
        if (!"Login".equals(driver.getTitle())) {
            // Alternatively, we could navigate to the login page, perhaps logging out first
            throw new IllegalStateException("This is not the login page");
        }
    }

    // The login page contains several HTML elements that will be represented as WebElements.
    // The locators for these elements should only be defined once.
        By usernameLocator = By.id("username");
        By passwordLocator = By.id("passwd");
        By loginButtonLocator = By.id("login");

    // The login page allows the user to type their username into the username field
    public LoginPage typeUsername(String username) {
        // This is the only place that "knows" how to enter a username
        driver.findElement(usernameLocator).sendKeys(username);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to type their password into the password field
    public LoginPage typePassword(String password) {
        // This is the only place that "knows" how to enter a password
        driver.findElement(passwordLocator).sendKeys(password);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to submit the login form
    public HomePage submitLogin() {
        // This is the only place that submits the login form and expects the destination to be the home page.
        // A seperate method should be created for the instance of clicking login whilst expecting a login failure. 
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the login page ever
        // go somewhere else (for example, a legal disclaimer) then changing the method signature
        // for this method will mean that all tests that rely on this behaviour won't compile.
        return new HomePage(driver);	
    }

    // The login page allows the user to submit the login form knowing that an invalid username and / or password were entered
    public LoginPage submitLoginExpectingFailure() {
        // This is the only place that submits the login form and expects the destination to be the login page due to login failure.
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the user ever be navigated to the home page after submiting a login with credentials 
        // expected to fail login, the script will fail when it attempts to instantiate the LoginPage PageObject.
        return new LoginPage(driver);	
    }

    // Conceptually, the login page offers the user the service of being able to "log into"
    // the application using a user name and password. 
    public HomePage loginAs(String username, String password) {
        // The PageObject methods that enter username, password & submit login have already defined and should not be repeated here.
        typeUsername(username);
        typePassword(password);
        return submitLogin();
    }
}
```

# 4.2 - 领域特定语言

```java
/**
 * Takes a username and password, fills out the fields, and clicks "login".
 * @return An instance of the AccountPage
 */
public AccountPage loginAsUser(String username, String password) {
  WebElement loginField = driver.findElement(By.id("loginField"));
  loginField.clear();
  loginField.sendKeys(username);

  // Fill out the password field. The locator we're using is "By.id", and we should
  // have it defined elsewhere in the class.
  WebElement passwordField = driver.findElement(By.id("password"));
  passwordField.clear();
  passwordField.sendKeys(password);

  // Click the login button, which happens to have the id "submit".
  driver.findElement(By.id("submit")).click();

  // Create and return a new instance of the AccountPage (via the built-in Selenium
  // PageFactory).
  return PageFactory.newInstance(AccountPage.class);
}
```

此方法完全从测试代码中抽象出输入字段, 按钮, 单击甚至页面的概念. 使用这种方法, 测试人员要做的就是调用此方法. 这给您带来了维护方面的优势: 如果登录字段曾经更改过, 则只需更改此方法-而非您的测试.

```java
public void loginTest() {
    loginAsUser("cbrown", "cl0wn3");

    // Now that we're logged in, do some other stuff--since we used a DSL to support
    // our testers, it's as easy as choosing from available methods.
    do.something();
    do.somethingElse();
    Assert.assertTrue("Something should have been done!", something.wasDone());

    // Note that we still haven't referred to a button or web control anywhere in this
    // script...
}
```

郑重强调: 您的主要目标之一应该是编写一个API, 该API允许您的测试解决 **当前的问题, 而不是UI的问题**. 用户界面是用户的次要问题–用户并不关心用户界面, 他们只是想完成工作. 您的测试脚本应该像用户希望做的事情以及他们想知道的事情的完整清单那样易于阅读. 测试不应该考虑UI如何要求您去做.

\***AUT**: 待测系统

# 4.3 - 生成应用程序状态

Selenium不应用于准备测试用例. 测试用例中所有重复性动作和准备工作, 都应通过其他方法来完成.\
例如, 大多数Web UI都具有身份验证 (诸如一个登录表单) . 在每次测试之前通过Web浏览器进行登录的消除, 将提高测试的速度和稳定性. 应该创建一种方法来获取对 AUT\* 的访问权限 (例如, 使用API登录并设置Cookie) . 此外, 不应使用Selenium创建预加载数据来进行测试的方法.\
如前所述, 应利用现有的API为 AUT\* 创建数据. \***AUT**: 待测系统

# 4.4 - 模拟外部服务

消除对外部服务的依赖性将大大提高测试的速度和稳定性.

# 4.5 - 改善报告

Selenium并非旨在报告测试用例的运行状态. 利用单元测试框架的内置报告功能是一个好的开始. 大多数单元测试框架都有可以生成xUnit或HTML格式的报告. xUnit报表很受欢迎, 可以将其结果导入到持续集成（CI）服务器, 例如Jenkins、Travis、Bamboo等. 以下是一些链接, 可获取关于几种语言报表输出的更多信息.

[NUnit 3 Console Runner](//github.com/nunit/docs/wiki/Console-Runner)

[NUnit 3 Console Command Line](//github.com/nunit/docs/wiki/Console-Command-Line)

[xUnit getting test results in TeamCity](//xunit.net/docs/getting-test-results-in-teamcity)

[xUnit getting test results in CruiseControl.NET](//xunit.net/docs/getting-test-results-in-ccnet)

[xUnit getting test results in Azure DevOps](//xunit.net/docs/getting-test-results-in-azure-devops)

# 4.6 - 避免共享状态

尽管在多个地方都提到过, 但这点仍值得被再次提及. 确保测试相互隔离.

* 不要共享测试数据. 想象一下有几个测试, 每个测试都会在选择操作执行之前查询数据库中的有效订单. 如果两个测试采用相同的顺序, 则很可能会出现意外行为.

* 清理应用程序中过时的数据, 这些数据可能会被其他测试. 例如无效的订单记录.

* 每次测试都创建一个新的WebDriver实例. 这在确保测试隔离的同时可以保障并行化更为简单.

  * If you choose [pytest](https://pytest.org/) as your test runner, this can be easily done by yielding your driver in a global fixture. This way each test gets its own driver instance, and you can ensure that drivers always quit after a test is finished (pass or fail).

# 4.7 - 使用定位器的提示

# 4.8 - 测试的独立性

将每个测试编写为独立的单元. 以不依赖于其他测试完成的方式编写测试:

例如有一个内容管理系统, 您可以借助其创建一些自定义内容, 这些内容在发布后作为模块显示在您的网站上, 并且CMS和应用程序之间的同步可能需要一些时间.

测试模块的一种错误方法是在测试中创建并发布内容, 然后在另一测试中检查该模块. 这是不可取的, 因为发布后内容可能无法立即用于其他测试.

与之相反的事, 您可以创建在受影响的测试中打开和关闭的打桩内容, 并将其用于验证模块. 而且, 对于内容的创建, 您仍然可以进行单独的测试.

# 4.9 - 考虑使用Fluent API

Martin Fowler创造了术语 [“Fluent API”](//www.martinfowler.com/bliki/FluentInterface.html). Selenium已经在其 `FluentWait` 类中实现了类似的东西, 这是对标准 `Wait` 类的替代. 您可以在页面对象中启用Fluent API设计模式, 然后使用如下代码段查询Google搜索页面:

```java
driver.get( "http://www.google.com/webhp?hl=en&amp;tab=ww" );
GoogleSearchPage gsp = new GoogleSearchPage(driver);
gsp.setSearchString().clickSearchButton();
```

Google页面对象类具有这种流畅行为后可能看起来像这样:

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

public class GoogleSearchPage extends BasePage {
    public GoogleSearchPage(WebDriver driver) {
        super(driver);
        // Generally do not assert within pages or components.
        // Effectively throws an exception if the lambda condition is not met.
        new WebDriverWait(driver, Duration.ofSeconds(3)).until(d -> d.findElement(By.id("logo")));
    }

    public GoogleSearchPage setSearchString(String sstr) {
        driver.findElement(By.id("gbqfq")).sendKeys(sstr);
        return this;
    }

    public void clickSearchButton() {
        driver.findElement(By.id("gbqfb")).click();
    }
}
```

# 4.10 - 每次测试都刷新浏览器

每次测试都从一个干净的已知状态开始. 理想情况下, 为每次测试打开一个新的虚拟机. 如果打开新虚拟机不切实际, 则至少应为每次测试启动一个新的WebDriver. 对于Firefox, 请使用您已知的配置文件去启动WebDriver. 大多数浏览器驱动器，像GeckoDriver和ChromeDriver那样，默认都会以干净的已知状态和一个新的用户配置文件开始。

```java
WebDriver driver = new FirefoxDriver();
```

# 5 - 不鼓励的行为

使用Selenium自动化浏览器时应避免的事项.

# 5.1 - 验证码

验证码 (CAPTCHA), 是 *全自动区分计算机和人类的图灵测试* *(Completely Automated Public Turing test to tell Computers and Humans Apart)* 的简称, 是被明确地设计用于阻止自动化的, 所以不要尝试!\
规避验证码的检查, 主要有两个策略:

* 在测试环境中禁用验证码
* 添加钩子以允许测试绕过验证码

# 5.2 - 文件下载

虽然可以通过在Selenium的控制下单击浏览器的链接来开始下载, 但是API并不会暴露下载进度, 因此这是一种不理想的测试下载文件的方式. 因为下载文件并非模拟用户与Web平台交互的重要方面. 取而代之的是, 应使用Selenium(以及任何必要的cookie)查找链接, 并将其传递给例如[curl](/zh-cn/)这样的HTTP请求库.

[HtmlUnit driver](https://github.com/SeleniumHQ/htmlunit-driver) 可以通过实现[AttachmentHandler](https://htmlunit.sourceforge.io/apidocs/com/gargoylesoftware/htmlunit/attachment/AttachmentHandler.html) 接口将附件作为输入流进行访问来下载附件. 可以将AttachmentHandler添加到 [HtmlUnit](https://htmlunit.sourceforge.io/) WebClient.

# 5.3 - HTTP响应码

对于Selenium RC中的某些浏览器配置， Selenium充当了浏览器和自动化站点之间的代理. 这意味着可以捕获或操纵通过Selenium传递的所有浏览器流量. `captureNetworkTraffic()` 方法旨在捕获浏览器和自动化站点之间的所有网络流量，包括HTTP响应码.

Selenium WebDriver是一种完全不同的浏览器自动化实现， 它更喜欢表现得像用户一样，这种方式来自于基于WebDriver编写测试的方式. 在自动化功能测试中，检查状态码并不是测试失败的特别重要的细节, 之前的步骤更重要.

浏览器将始终呈现HTTP状态代码，例如404或500错误页面. 遇到这些错误页面时，一种“快速失败”的简单方法是 在每次加载页面后检查页面标题或可信赖点的内容（例如 `<h1>` 标签）. 如果使用的是页面对象模型，则可以将此检查置于类构造函数中或类似于期望的页面加载的位置. 有时，HTTP代码甚至可能出现在浏览器的错误页面中， 您可以使用WebDriver读取此信息并改善调试输出.

检查网页本身的一种理想实践是符合WebDriver的呈现以及用户的视角.

如果您坚持，捕获HTTP状态代码的高级解决方案是复刻Selenium RC的行为去使用代理. WebDriver API提供了为浏览器设置代理的功能， 并且有许多代理可以通过编程方式来操纵发送到Web服务器和从Web服务器接收的请求的内容. 使用代理可以决定如何响应重定向响应代码. 此外，并非每个浏览器都将响应代码提供给WebDriver， 因此选择使用代理可以使您拥有适用于每个浏览器的解决方案.

# 5.4 - Gmail, email 和 Facebook 登录

由于多种原因, 不建议使用WebDriver登录Gmail和Facebook等网站. 除了违反这些网站的使用条款之外 (您可能会面临帐户被关闭的风险) , 还有其运行速度缓慢且不可靠的因素.

理想的做法是使用电子邮件供应商提供的API, 或者对于Facebook, 使用开发者工具的服务, 该服务是被用于创建测试帐户、朋友等内容的API. 尽管使用API可能看起来有些额外的工作量, 但是您将获得基于速度、可靠性和稳定性的回报. API不会频繁更改, 但是网页和HTML定位符经常变化, 并且需要您更新测试框架的代码.

在任何时候测试使用WebDriver登录第三方站点, 都会增加测试失败的风险, 因为这会使您的测试时间更长. 通常的经验是, 执行时间较长的测试会更加脆弱和不可靠.

符合[W3C conformant](//w3c.github.io/webdriver/webdriver-spec.html) 的WebDriver实现, 也会使用 `WebDriver` 的属性对 `navigator` 对象进行注释, 用于缓解拒绝服务的攻击.

# 5.5 - 测试依赖

关于自动化测试的一个常见想法和误解是关于特定的测试顺序. 您的测试应该能够以**任何**顺序运行，而不是依赖于完成其他测试才能成功.

# 5.6 - 性能测试

通常不建议使用Selenium和WebDriver进行性能测试. 并非因为不能做, 只是缺乏针对此类工作的优化, 因而难以得到乐观的结果.

对于用户而言, 在用户上下文中执行性能测试似乎是自然而然的选择, 但是WebDriver的测试会受到许多外部和内部的影响而变得脆弱, 这是您无法控制的. 例如, 浏览器的启动速度, HTTP服务器的速度, 托管JavaScript或CSS的第三方服务器的响应 以及WebDriver实现本身检测的损失. 这些因素的变化会影响结果. 很难区分网站自身与外部资源之间的性能差异, 并且也很难明确浏览器中使用WebDriver对性能的影响, 尤其是在注入脚本时.

另一个潜在的吸引点是"节省时间"-同时执行功能和性能测试. 但是, 功能和性能测试分别具有截然不同的目标. 要测试功能, 测试人员可能需要耐心等待加载, 但这会使性能测试结果蒙上阴影, 反之亦然.

为了提高网站的性能, 您需要不依赖于环境的差异来分析整体性能, 识别不良代码的实践, 对单个资源 (即CSS或JavaScript) 的性能进行细分 以了解需要改进的地方. 有很多性能测试工具已经可以完成这项工作, 并且提供了报告和分析结果, 甚至可以提出改进建议.

例如一种易于使用的 (开源) 软件包是: [JMeter](/zh-cn/)

# 5.7 - 爬取链接

建议您不要使用WebDriver来通过链接进行爬网， 并非因为无法完成，而是因为它绝对不是最理想的工具。 WebDriver需要一些时间来启动，并且可能要花几秒钟到一分钟的时间， 具体取决于测试的编写方式，仅仅是为了获取页面并遍历DOM.

除了使用WebDriver之外， 您还可以通过执行 [curl](https://curl.se/) 命令或 使用诸如BeautifulSoup之类的库来节省大量时间， 因为这些方法不依赖于创建浏览器和导航至页面. 通过不使用WebDriver可以节省大量时间.

# 5.8 - 双因素认证

----
url: https://www.selenium.dev/documentation/
----

# The Selenium Browser Automation Project

Selenium is an umbrella project for a range of tools and libraries that enable and support the automation of web browsers.

It provides extensions to emulate user interaction with browsers, a distribution server for scaling browser allocation, and the infrastructure for implementations of the [W3C WebDriver specification](//www.w3.org/TR/webdriver/) that lets you write interchangeable code for all major web browsers.

This project is made possible by volunteer contributors who have put in thousands of hours of their own time, and made the source code [freely available](https://www.selenium.dev/documentation/about/copyright/#license) for anyone to use, enjoy, and improve.

Selenium brings together browser vendors, engineers, and enthusiasts to further an open discussion around automation of the web platform. The project organises [an annual conference](/) to teach and nurture the community.

At the core of Selenium is [WebDriver](https://www.selenium.dev/documentation/webdriver/), an interface to write instruction sets that can be run interchangeably in many browsers. Once you’ve installed everything, only a few lines of code get you inside a browser. You can find a more comprehensive example in [Writing your first Selenium script](https://www.selenium.dev/documentation/webdriver/getting_started/first_script/)

*
*
*
*
*
*

```java
package dev.selenium.hello;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class HelloSelenium {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://selenium.dev");

        driver.quit();
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/hello/HelloSelenium.java)

```py
from selenium import webdriver


driver = webdriver.Chrome()

driver.get("http://selenium.dev")

driver.quit()
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/hello/hello_selenium.py)

```cs
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Hello;

public static class HelloSelenium
{
    public static void Main()
    {
        var driver = new ChromeDriver();
            
        driver.Navigate().GoToUrl("https://selenium.dev");
            
        driver.Quit();
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/HelloSelenium.cs)

```rb
# frozen_string_literal: true

require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get 'https://selenium.dev'

driver.quit
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/hello/hello_selenium.rb)

```js
const {Builder, Browser} = require('selenium-webdriver');

(async function helloSelenium() {
  let driver = await new Builder().forBrowser(Browser.CHROME).build();

  await driver.get('https://selenium.dev');

  await driver.quit();
})();
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/hello/helloSelenium.js)

```kt
package dev.selenium.hello

import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()

    driver.get("https://selenium.dev")

    driver.quit()
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/hello/HelloSelenium.kt)

See the [Overview](https://www.selenium.dev/documentation/overview/) to check the different project components and decide if Selenium is the right tool for you.

You should continue on to [Getting Started](https://www.selenium.dev/documentation/webdriver/getting_started/) to understand how you can install Selenium and successfully use it as a test automation tool, and scaling simple tests like this to run in large, distributed environments on multiple browsers, on several different operating systems.

***

##### [Selenium Overview](/documentation/overview/)

Is Selenium for you? See an overview of the different project components.

##### [WebDriver](/documentation/webdriver/)

WebDriver drives a browser natively; learn more about it.

##### [Selenium Manager (Beta)](/documentation/selenium_manager/)

Selenium Manager is a command-line tool implemented in Rust that provides automated driver and browser management for Selenium. Selenium bindings use this tool by default, so you do not need to download it or add anything to your code or do anything else to use it.

##### [Grid](/documentation/grid/)

Want to run tests in parallel across multiple machines? Then, Grid is for you.

##### [IE Driver Server](/documentation/ie_driver_server/)

The Internet Explorer Driver is a standalone server that implements the WebDriver specification.

##### [Selenium IDE](/documentation/ide/)

The Selenium IDE is a browser extension that records and plays back a user’s actions.

##### [Test Practices](/documentation/test_practices/)

Some guidelines and recommendations on testing from the Selenium project.

##### [Legacy](/documentation/legacy/)

Documentation related to the legacy components of Selenium. Meant to be kept purely for historical reasons and not as a incentive to use deprecated components.

##### [About this documentation](/documentation/about/)

Last modified April 6, 2025: [\[rb\] do not run hello selenium in examples (efaae63f2b6)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/efaae63f2b66029b5022e5b0348414a1a29c631f)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/interactions/virtual_authenticator/
----

# Virtual Authenticator

```java
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L55-L61)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L48-55)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L40-L46)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setHasUserVerification(true);
    options.setIsUserConsenting(true);
    options.setTransport(Transport['USB']);
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    assert(Object.keys(options).length === 6);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticatorOptions.spec.js#L11-L17)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticatorOptions.spec.js

```js
const {VirtualAuthenticatorOptions, Transport, Protocol} = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')


describe('Virtual authenticator options', function () {
  let options;

  it('Virtual options', async function () {
    options = new VirtualAuthenticatorOptions();
    options.setIsUserVerified(true);
    options.setHasUserVerification(true);
    options.setIsUserConsenting(true);
    options.setTransport(Transport['USB']);
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    assert(Object.keys(options).length === 6);
  });

  it('User verified', async function () {
    options.setIsUserVerified(true);

    assert(options.toDict()['isUserVerified']);
  });
});
```

```java
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L68-L73)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L63-71)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L53-L58)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L51-L55)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L86)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#80-86)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L68-L74)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L62-L63)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L100-L103)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#103-107)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L89-L97)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L80-L94)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L143-L145)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L145-148)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L140-L147)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L136-L140)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L137-L146)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L139-150)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.add_credential(credential)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L150)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L131-L142)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L157-L171)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L162-178)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    credential_list = driver.get_credentials()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L183)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L154-L170)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

## Remove Credential

Remove a credencial do autenticador baseado na id da credencial passado.

```cs
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L189-198)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

*
*
*
*
*
*

```java
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L181-L190)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.remove_credential(credential.id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L209)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```java
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L196-L205)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L207-216)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.remove_all_credentials()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L239)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L181-L190)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L211-L212)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L224-225)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L245-L247)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setIsUserVerified(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L197-L197)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/actions_api/mouse/
----

# Ações do Mouse

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L22-L25)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L14-L17)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L11-L14)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    let clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.move({origin: clickable}).press().perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/clickAndHold.spec.js#L14-L16)

##### /examples/javascript/test/actionsApi/mouse/clickAndHold.spec.js

```js
const {By, Builder} = require('selenium-webdriver');

describe('Click and hold', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and mouseDown on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    let clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.move({origin: clickable}).press().perform();
  });
});
```

```kt
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L23-L26)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L34-L37)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L26-L29)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L30-L33)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L22-L25)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    let click = driver.findElement(By.id("click"));
    const actions = driver.actions({async: true});
    await actions.move({origin: click}).click().perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/clickAndRelease.spec.js#L14-L16)

##### /examples/javascript/test/actionsApi/mouse/clickAndRelease.spec.js

```js
const {By,Builder} = require('selenium-webdriver');

describe('Click and release', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    let click = driver.findElement(By.id("click"));
    const actions = driver.actions({async: true});
    await actions.move({origin: click}).click().perform();
  });
});
```

```kt
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L35-L38)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L46-L49)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L37-L40)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L43-L46)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L34-L37)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.contextClick(clickable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/rightClick.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/rightClick.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Right click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and right click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.contextClick(clickable).perform();

    await driver.sleep(500);
    const clicked = await driver.findElement(By.id('click-status')).getText();
    assert.deepStrictEqual(clicked, `context-clicked`)
  });
});
```

```kt
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L47-L50)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L60-L66)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L51-L54)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L59-L63)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L47-L50)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js#L19-L20)

##### /examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js

```js
const {By, Button, Browser, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Should be able to perform BACK click and FORWARD click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Back click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)

    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)
  });

  it('Forward click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();
    await driver.navigate().back();

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)

    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L61-L67)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L78-L84)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L65-L68)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L77-L81)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L61-L64)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js#L32-L33)

##### /examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js

```js
const {By, Button, Browser, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Should be able to perform BACK click and FORWARD click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Back click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)

    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)
  });

  it('Forward click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();
    await driver.navigate().back();

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)

    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L79-L85)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L93-L96)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L76-L79)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L91-L94)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L73-L76)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.doubleClick(clickable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/doubleClick.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/doubleClick.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Double click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Double-click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.doubleClick(clickable).perform();

    await driver.sleep(500);
    const status = await driver.findElement(By.id('click-status')).getText();
    assert.deepStrictEqual(status, `double-clicked`)
  });
});
```

```kt
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L94-L97)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L105-L108)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L87-L90)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L104-L107)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L84-L87)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const hoverable = driver.findElement(By.id("hover"));
    const actions = driver.actions({async: true});
    await actions.move({origin: hoverable}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveToElement.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/moveToElement.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Move to element', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move into an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const hoverable = driver.findElement(By.id("hover"));
    const actions = driver.actions({async: true});
    await actions.move({origin: hoverable}).perform();

    const status = await driver.findElement(By.id('move-status')).getText();
    assert.deepStrictEqual(status, `hovered`)
  });
});
```

```kt
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L106-L109)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L118-L121)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L98-L101)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L132-L135)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L97-L100)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L119-L122)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L131-L136)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L110-L112)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L146-L150)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      driver.action
            .move_to_location(8, 12)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L114-L116)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L27-L28)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L132-L137)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L153-L155)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L126-L128)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L167-L169)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      driver.action
            .move_by(13, 15)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L128-L130)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L40)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L154-L156)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L166-L170)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L139-L143)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L181-L185)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L141-L145)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js#L27-L30)

##### /examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Drag and Drop', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('By Offset', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });

  it('Onto Element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });
});
```

```kt
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L167-L171)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L179-L184)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L151-L156)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L195-L200)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L153-L158)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js#L15-L19)

##### /examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Drag and Drop', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('By Offset', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });

  it('Onto Element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });
});
```

```kt
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L180-L185)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

----
url: https://www.selenium.dev/zh-cn/_print/documentation/test_practices/discouraged/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/test_practices/discouraged/).

# 不鼓励的行为

使用Selenium自动化浏览器时应避免的事项.

* 1: [验证码](#pg-12a8f4e30343b86339acb24c22b1d4ae)
* 2: [文件下载](#pg-1223ebcabcfa4c9b6ea24c5aaffbc509)
* 3: [HTTP响应码](#pg-5f748c8597e92ebc444be6a9c4e7cdd3)
* 4: [Gmail, email 和 Facebook 登录](#pg-9bdc1ce1d6b5b575d611d3c7acfc776b)
* 5: [测试依赖](#pg-e1315c8ae4a385f5b3b8b028ce8d9ebb)
* 6: [性能测试](#pg-819c58e35cb5b37daaf82700a073a9a0)
* 7: [爬取链接](#pg-38d1959cdf1a7c403cb4f29ca535baa9)
* 8: [双因素认证](#pg-a18a4de15d62b2cf10d163ace06e1017)

# 1 - 验证码

验证码 (CAPTCHA), 是 *全自动区分计算机和人类的图灵测试* *(Completely Automated Public Turing test to tell Computers and Humans Apart)* 的简称, 是被明确地设计用于阻止自动化的, 所以不要尝试!\
规避验证码的检查, 主要有两个策略:

* 在测试环境中禁用验证码
* 添加钩子以允许测试绕过验证码

# 2 - 文件下载

虽然可以通过在Selenium的控制下单击浏览器的链接来开始下载, 但是API并不会暴露下载进度, 因此这是一种不理想的测试下载文件的方式. 因为下载文件并非模拟用户与Web平台交互的重要方面. 取而代之的是, 应使用Selenium(以及任何必要的cookie)查找链接, 并将其传递给例如[curl](/zh-cn/)这样的HTTP请求库.

[HtmlUnit driver](https://github.com/SeleniumHQ/htmlunit-driver) 可以通过实现[AttachmentHandler](https://htmlunit.sourceforge.io/apidocs/com/gargoylesoftware/htmlunit/attachment/AttachmentHandler.html) 接口将附件作为输入流进行访问来下载附件. 可以将AttachmentHandler添加到 [HtmlUnit](https://htmlunit.sourceforge.io/) WebClient.

# 3 - HTTP响应码

对于Selenium RC中的某些浏览器配置， Selenium充当了浏览器和自动化站点之间的代理. 这意味着可以捕获或操纵通过Selenium传递的所有浏览器流量. `captureNetworkTraffic()` 方法旨在捕获浏览器和自动化站点之间的所有网络流量，包括HTTP响应码.

Selenium WebDriver是一种完全不同的浏览器自动化实现， 它更喜欢表现得像用户一样，这种方式来自于基于WebDriver编写测试的方式. 在自动化功能测试中，检查状态码并不是测试失败的特别重要的细节, 之前的步骤更重要.

浏览器将始终呈现HTTP状态代码，例如404或500错误页面. 遇到这些错误页面时，一种“快速失败”的简单方法是 在每次加载页面后检查页面标题或可信赖点的内容（例如 `<h1>` 标签）. 如果使用的是页面对象模型，则可以将此检查置于类构造函数中或类似于期望的页面加载的位置. 有时，HTTP代码甚至可能出现在浏览器的错误页面中， 您可以使用WebDriver读取此信息并改善调试输出.

检查网页本身的一种理想实践是符合WebDriver的呈现以及用户的视角.

如果您坚持，捕获HTTP状态代码的高级解决方案是复刻Selenium RC的行为去使用代理. WebDriver API提供了为浏览器设置代理的功能， 并且有许多代理可以通过编程方式来操纵发送到Web服务器和从Web服务器接收的请求的内容. 使用代理可以决定如何响应重定向响应代码. 此外，并非每个浏览器都将响应代码提供给WebDriver， 因此选择使用代理可以使您拥有适用于每个浏览器的解决方案.

# 4 - Gmail, email 和 Facebook 登录

由于多种原因, 不建议使用WebDriver登录Gmail和Facebook等网站. 除了违反这些网站的使用条款之外 (您可能会面临帐户被关闭的风险) , 还有其运行速度缓慢且不可靠的因素.

理想的做法是使用电子邮件供应商提供的API, 或者对于Facebook, 使用开发者工具的服务, 该服务是被用于创建测试帐户、朋友等内容的API. 尽管使用API可能看起来有些额外的工作量, 但是您将获得基于速度、可靠性和稳定性的回报. API不会频繁更改, 但是网页和HTML定位符经常变化, 并且需要您更新测试框架的代码.

在任何时候测试使用WebDriver登录第三方站点, 都会增加测试失败的风险, 因为这会使您的测试时间更长. 通常的经验是, 执行时间较长的测试会更加脆弱和不可靠.

符合[W3C conformant](//w3c.github.io/webdriver/webdriver-spec.html) 的WebDriver实现, 也会使用 `WebDriver` 的属性对 `navigator` 对象进行注释, 用于缓解拒绝服务的攻击.

# 5 - 测试依赖

关于自动化测试的一个常见想法和误解是关于特定的测试顺序. 您的测试应该能够以**任何**顺序运行，而不是依赖于完成其他测试才能成功.

# 6 - 性能测试

通常不建议使用Selenium和WebDriver进行性能测试. 并非因为不能做, 只是缺乏针对此类工作的优化, 因而难以得到乐观的结果.

对于用户而言, 在用户上下文中执行性能测试似乎是自然而然的选择, 但是WebDriver的测试会受到许多外部和内部的影响而变得脆弱, 这是您无法控制的. 例如, 浏览器的启动速度, HTTP服务器的速度, 托管JavaScript或CSS的第三方服务器的响应 以及WebDriver实现本身检测的损失. 这些因素的变化会影响结果. 很难区分网站自身与外部资源之间的性能差异, 并且也很难明确浏览器中使用WebDriver对性能的影响, 尤其是在注入脚本时.

另一个潜在的吸引点是"节省时间"-同时执行功能和性能测试. 但是, 功能和性能测试分别具有截然不同的目标. 要测试功能, 测试人员可能需要耐心等待加载, 但这会使性能测试结果蒙上阴影, 反之亦然.

为了提高网站的性能, 您需要不依赖于环境的差异来分析整体性能, 识别不良代码的实践, 对单个资源 (即CSS或JavaScript) 的性能进行细分 以了解需要改进的地方. 有很多性能测试工具已经可以完成这项工作, 并且提供了报告和分析结果, 甚至可以提出改进建议.

例如一种易于使用的 (开源) 软件包是: [JMeter](/zh-cn/)

# 7 - 爬取链接

建议您不要使用WebDriver来通过链接进行爬网， 并非因为无法完成，而是因为它绝对不是最理想的工具。 WebDriver需要一些时间来启动，并且可能要花几秒钟到一分钟的时间， 具体取决于测试的编写方式，仅仅是为了获取页面并遍历DOM.

除了使用WebDriver之外， 您还可以通过执行 [curl](https://curl.se/) 命令或 使用诸如BeautifulSoup之类的库来节省大量时间， 因为这些方法不依赖于创建浏览器和导航至页面. 通过不使用WebDriver可以节省大量时间.

# 8 - 双因素认证

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/support_features/listeners/
----

----
url: https://www.selenium.dev/documentation/test_practices/discouraged/file_downloads/
----

# File downloads

Whilst it is possible to start a download by clicking a link with a browser under Selenium’s control, the API does not expose download progress, making it less than ideal for testing downloaded files. This is because downloading files is not considered an important aspect of emulating user interaction with the web platform. Instead, find the link using Selenium (and any required cookies) and pass it to a HTTP request library like [curl](https:////curl.se/).

The [HtmlUnit driver](https://github.com/SeleniumHQ/htmlunit-driver) can download attachments by accessing them as input streams by implementing the [AttachmentHandler](https://htmlunit.sourceforge.io/apidocs/com/gargoylesoftware/htmlunit/attachment/AttachmentHandler.html) interface. The AttachmentHandler can then be added to the [HtmlUnit](https://htmlunit.sourceforge.io/) WebClient.

----
url: https://www.selenium.dev/ja/documentation/webdriver/bidi/w3c/network/
----

# Network

```java
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L36-L38)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    assert.notEqual(intercept, null)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L29)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L46-L50)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L34-L35)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                    responseDetails ->
                            network.continueWithAuth(
                                    responseDetails.getRequest().getRequestId(),
                                    new UsernameAndPassword("admin", "admin")));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L57-L64)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L42-L46)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                            // Does not handle the alert
                            network.continueWithAuthNoCredentials(responseDetails.getRequest().getRequestId()));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L74-L80)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L56-L60)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                            network.cancelAuth(responseDetails.getRequest().getRequestId()));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L90-L96)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L71-L75)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
            }
    }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L104-L108)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L30-L35)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L23-L29)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L45-L51)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L82-L88)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L62-L68)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L96-L102)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L101-L106)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

最終更新 May 27, 2025: [Update dependency selenium-webdriver to v4.33.0 (#2316) (5f5285aba17)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/5f5285aba177977a839ac8377929dc999623a4bb)

----
url: https://www.selenium.dev/pt-br/_print/documentation/test_practices/discouraged/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/test_practices/discouraged/).

# Piores práticas

Temas a evitar quando automatizar navegadores com Selenium.

* 1: [Captchas](#pg-b9472460f277ae413b03898b8ebef6b7)
* 2: [Downloads de arquivo](#pg-c79dca2107c3188889176374ce3f58ff)
* 3: [Códigos de respostas HTTP](#pg-2d5ad114868779f863121d44ce8df24f)
* 4: [Login via Gmail, email e Facebook](#pg-3a9d097074ef98e8fa2e2aacf6e14dc2)
* 5: [Dependência entre testes](#pg-69552aacfd36f7ebd616975dfd16cc9c)
* 6: [Teste de performance/desempenho](#pg-c613ed467d082d32cb7c5294b94a1280)
* 7: [Navegação por links](#pg-559e8e8a1ac67ab5eeb8d552a7c78c22)
* 8: [Autenticação de Dois Fatores (2FA)](#pg-434101f95bfac0d5faefe0b450574456)

# 1 - Captchas

CAPTCHA, abreviação de *Completely Automated Public Turing test to tell Computers and Humans Apart*, foi projetado explicitamente para impedir a automação, portanto, não tente! Existem duas estratégias principais para contornar as verificações CAPTCHA:

* Desative CAPTCHAs em seu ambiente de teste
* Adicione um hook para permitir que os testes ignorem o CAPTCHA

# 2 - Downloads de arquivo

Embora seja possível iniciar um download clicando em um link com um navegador sob o controle do Selenium, a API não expõe o progresso do download, tornando-o menos do que ideal para testar arquivos baixados. Isso ocorre porque o download de arquivos não é considerado um aspecto importante de emular a interação do usuário com a plataforma da web. Em vez disso, encontre o link usando Selenium (e todos os cookies necessários) e passe este cookie para uma biblioteca de solicitação HTTP como [curl](https://curl.se/).

O [driver HtmlUnit](https://github.com/SeleniumHQ/htmlunit-driver) pode baixar anexos acessando-os como fluxos de entrada, implementando o [AttachmentHandler](https://htmlunit.sourceforge.io/apidocs/com/gargoylesoftware/htmlunit/attachment/AttachmentHandler.html). O AttachmentHandler pode ser adicionado ao WebClient [HtmlUnit](https://htmlunit.sourceforge.io/).

# 3 - Códigos de respostas HTTP

Para algumas configurações de navegador no Selenium RC, Selenium atuou como um proxy entre o navegador e o site sendo automatizado. Isso significa que todo o tráfego do navegador que passou pelo Selenium poderia ser capturado ou manipulado. O método `captureNetworkTraffic()` pretendia capturar todo o tráfego de rede entre o navegador e o site sendo automatizado, incluindo códigos de resposta HTTP.

Selenium WebDriver é uma abordagem completamente diferente para a automação do navegador, preferindo agir mais como um usuário. Isso é representado na maneira como você escreve testes com o WebDriver. Em testes funcionais automatizados, verificar o código de status não é um detalhe particularmente importante da falha de um teste; as etapas que o precederam são mais importantes.

O navegador sempre representará o código de status HTTP, imagine, por exemplo, uma página de erro 404 ou 500. Uma maneira simples de “falhar rapidamente” quando você encontrar uma dessas páginas de erro é verificar o título da página ou o conteúdo de um ponto confiável (por exemplo, a tag `<h1>`) após cada carregamento de página. Se você estiver usando o modelo de objeto de página, você pode incluir esta verificação em seu construtor de classe ou ponto semelhante onde o carregamento da página é esperado. Ocasionalmente, o código HTTP pode até ser representado na página de erro do navegador e você pode usar o WebDriver para ler isso e melhorar sua saída de depuração.

Verificar se a própria página da web está alinhada com a prática ideal do WebDriver de representar a visão do usuário do site.

Se você insiste, uma solução avançada para capturar códigos de status HTTP é replicar o comportamento do Selenium RC usando um proxy. A API WebDriver fornece a capacidade de definir um proxy para o navegador, e há uma série de proxies que irão permitir que você manipule de forma programática o conteúdo das solicitações enviadas e recebidas do servidor da web. Usar um proxy permite que você decida como deseja responder para códigos de resposta de redirecionamento. Além disso, nem todo navegador torna os códigos de resposta disponíveis para WebDriver, então optar por usar um proxy permite que você tenha uma solução que funciona para todos os navegadores.

# 4 - Login via Gmail, email e Facebook

Por vários motivos, fazer login em sites como Gmail e Facebook usando do WebDriver não é recomendado. Além de ser contra os termos de uso desses sites (onde você corre o risco de ter a conta encerrada), é lento e não confiável.

A prática ideal é usar as APIs que os provedores de e-mail oferecem, ou no caso do Facebook, o serviço de ferramentas para desenvolvedores que expõe uma API para criar contas de teste, amigos e assim por diante. Embora usar uma API possa parecer um pouco trabalhoso, você será recompensado em velocidade, confiabilidade e estabilidade. A API também não deve mudar, enquanto as páginas da web e os localizadores de HTML mudam frequentemente e exigem que você atualize sua estrutura de teste.

Login em sites de terceiros usando WebDriver em qualquer ponto do seu teste aumenta o risco de seu teste falhar porque torna o teste mais longo. Uma regra geral é que testes mais longos são mais frágeis e não confiáveis.

Implementações WebDriver que estão [em conformidade com W3C](//w3c.github.io/webdriver/webdriver-spec.html) também anotam o objeto `navigator` com uma propriedade `WebDriver` para que os ataques de negação de serviço possam ser mitigados.

# 5 - Dependência entre testes

Uma ideia comum e um equívoco sobre o teste automatizado é sobre uma ordem de testes específica. Seus testes devem ser executados em **qualquer** ordem, e não depender da conclusão de outros testes para ter sucesso.

# 6 - Teste de performance/desempenho

Teste de desempenho usando Selenium e WebDriver geralmente não é recomendado. Não porque é incapaz, mas porque não é otimizado para o trabalho e é improvável que você obtenha bons resultados.

Pode parecer ideal para teste de desempenho no contexto do usuário, mas um conjunto de testes WebDriver estão sujeitos a muitos pontos de fragilidade externa e interna que estão além do seu controle; por exemplo, velocidade de inicialização do navegador, velocidade dos servidores HTTP, resposta de servidores de terceiros que hospedam JavaScript ou CSS, e a penalidade de instrumentação da própria implementação do WebDriver. A variação nesses pontos causará variação em seus resultados. É difícil separar a diferença entre o desempenho do seu site e o desempenho de recursos externos, e também é difícil dizer qual é a penalidade de desempenho para usar WebDriver no navegador, especialmente se você estiver injetando scripts.

A outra atração potencial é “economizar tempo” - execução de testes funcionais e de desempenho ao mesmo tempo. No entanto, os testes funcionais e de desempenho têm objetivos opostos. Para testar a funcionalidade, um testador pode precisar ser paciente e aguarde o carregamento, mas isso irá turvar os resultados do teste de desempenho e vice-versa.

Para melhorar o desempenho do seu site, você precisará ser capaz de analisar o desempenho geral independente das diferenças de ambiente, identificar práticas de código ruins, repartição do desempenho de recursos individuais (ou seja, CSS ou JavaScript), para saber o que melhorar. Existem ferramentas de teste de desempenho disponíveis que podem fazer este trabalho, que fornecem relatórios e análises, e podem até fazer sugestões de melhorias.

Pacotes de exemplo (código aberto) a serem usados ​​são: [JMeter](/pt-br/)

# 7 - Navegação por links

Usar o WebDriver para navegar por links não é uma prática recomendada. Não porque não pode ser feito, mas porque WebDriver definitivamente não é a ferramenta ideal para isso. O WebDriver precisa de tempo para inicializar, e pode levar vários segundos, até um minuto dependendo de como seu teste é escrito, apenas para chegar à página e atravessar o DOM.

Em vez de usar o WebDriver para isso, você poderia economizar muito tempo executando um comando [curl](https://curl.se/), ou usando uma biblioteca como BeautifulSoup uma vez que esses métodos não dependem em criar um navegador e navegar para uma página. Você está economizando muito tempo por não usar o WebDriver para essa tarefa.

# 8 - Autenticação de Dois Fatores (2FA)

----
url: https://www.selenium.dev/pt-br/_print/documentation/webdriver/troubleshooting/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/webdriver/troubleshooting/).

# Troubleshooting Assistance

How to solve WebDriver problems.

* 1: [Understanding Common Errors](#pg-374c5589847d9c315b992c97b3556906)
* * 1.1: [Unable to Locate Driver Error](#pg-1a041d40202643eaad1eb71b29cd7b9b)
  2: [Logging Selenium commands](#pg-fa32a7153ab2cd742d4f8d2581c154c1)
* 3: [Como atualizar para Selenium 4](#pg-f92e71f8994e995dce93bc1f7a5fd2cc)

It is not always obvious the root cause of errors in Selenium.

1. The most common Selenium-related error is a result of poor synchronization. Read about [Waiting Strategies](https://www.selenium.dev/pt-br/documentation/webdriver/waits/). If you aren’t sure if it is a synchronization strategy you can try *temporarily* hard coding a large sleep where you see the issue, and you’ll know if adding an explicit wait can help.

2. Note that many errors that get reported to the project are actually caused by issues in the underlying drivers that Selenium sends the commands to. You can rule out a driver problem by executing the command in multiple [browsers](https://www.selenium.dev/pt-br/documentation/webdriver/browsers/).

3. If you have questions about how to do things, check out the [Support options](/support/) for ways get assistance.

4. If you think you’ve found a problem with Selenium code, go ahead and file a [Bug Report](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=I-defect%2Cneeds-triaging\&template=bug-report.yml\&title=%5B%F0%9F%90%9B+Bug%5D%3A+) on GitHub.

# 1 - Understanding Common Errors

# 1.1 - Unable to Locate Driver Error

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.bash_profile
source ~/.bash_profile
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Terminal and execute:

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.zshenv
source ~/.zshenv
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Command Prompt and execute:

```shell
echo %PATH%
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
setx PATH "%PATH%;C:\WebDriver\bin"
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver.exe --version
```

| Navegador         | OS Suportado                   | Mantido por      | Download                                                                     | Rastreador de Problemas                                             |
| ----------------- | ------------------------------ | ---------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| Chromium/Chrome   | Windows/macOS/Linux            | Google           | [Downloads](//chromedriver.chromium.org/downloads)                           | [Problemas](//bugs.chromium.org/p/chromedriver/issues/list)         |
| Firefox           | Windows/macOS/Linux            | Mozilla          | [Downloads](//github.com/mozilla/geckodriver/releases)                       | [Problemas](//github.com/mozilla/geckodriver/issues)                |
| Edge              | Windows/macOS/Linux            | Microsoft        | [Downloads](//developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/) | [Problemas](https://github.com/MicrosoftDocs/edge-developer/issues) |
| Internet Explorer | Windows                        | Projeto Selenium | [Downloads](/downloads)                                                      | [Problemas](//github.com/SeleniumHQ/selenium/labels/D-IE)           |
| Safari            | macOS High Sierra e superiores | Apple            | Integrado no Sistema                                                         | [Problemas](//bugreport.apple.com/logon)                            |

Nota: O Opera driver já não inclui as funcionalidades mais recentes do Selenium e oficialmente deixou de ser suportado.

# 2 - Logging Selenium commands

```java
    public void logging() throws IOException {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Java Logging is not exactly straightforward, and if you are just looking for an easy way to look at the important Selenium logs, take a look at the [Selenium Logger project](https://github.com/titusfortner/selenium-logger#selenium-logger)

Python logs are typically created per module. You can match all submodules by referencing the top level module. So to work with all loggers in selenium module, you can do this:

```py
    logger = logging.getLogger('selenium')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L5)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

You must also create and add a log handler (`StreamHandler`, `FileHandler`, etc).

To save logs to a file, you can do this:

```py
log_path = '/path/to/log'
handler = logging.FileHandler(log_path)
logger.addHandler(handler)
```

To display logs in the console, you can do this:

```py
handler = logging.StreamHandler()
logger.addHandler(handler)
```

.NET logger is managed with a static class, so all access to logging is managed simply by referencing `Log` from the `OpenQA.Selenium.Internal.Logging` namespace.

If you want to see as much debugging as possible in all the classes, you can turn on debugging globally in Ruby by setting `$DEBUG = true`.

For more fine-tuned control, Ruby Selenium created its own Logger class to wrap the default `Logger` class. This implementation provides some interesting additional features. Obtain the logger directly from the `#logger`class method on the `Selenium::WebDriver` module:

```rb
    logger = Selenium::WebDriver.logger
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L11)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

```javascript
const logging = require('selenium-webdriver/lib/logging')
logger = logging.getLogger('webdriver')
```

```java
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L32-L35)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Python has 6 logger levels: `CRITICAL`, `ERROR`, `WARNING`, `INFO`, `DEBUG`, and `NOTSET`. The default is `WARNING`

To change the level of the logger:

```py
    logger.setLevel(logging.DEBUG)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L7)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

Things get complicated when you use PyTest, though. By default, PyTest hides logging unless the test fails. You need to set 3 things to get PyTest to display logs on passing tests.

To always output logs with PyTest you need to run with additional arguments. First, `-s` to prevent PyTest from capturing the console. Second, `-p no:logging`, which allows you to override the default PyTest logging settings so logs can be displayed regardless of errors.

So you need to set these flags in your IDE, or run PyTest on command line like:

```bash
pytest -s -p no:logging
```

Finally, since you turned off logging in the arguments above, you now need to add configuration to turn it back on:

```py
logging.basicConfig(level=logging.WARN)
```

.NET has 6 logger levels: `Error`, `Warn`, `Info`, `Debug`, `Trace` and `None`. The default level is `Warn`.

To change the level of the logger:

```cs
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L18)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

Ruby logger has 5 logger levels: `:debug`, `:info`, `:warn`, `:error`, `:fatal`. As of Selenium v4.9.1, The default is `:info`.

To change the level of the logger:

```rb
    logger.level = :debug
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L13)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

JavaScript has 9 logger levels: `OFF`, `SEVERE`, `WARNING`, `INFO`, `DEBUG`, `FINE`, `FINER`, `FINEST`, `ALL`. The default is `OFF`.

To change the level of the logger:

```javascript
logger.setLevel(logging.Level.INFO)
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
WARNING: this is a warning
```

Python logs actionable content at logger level — `WARNING` Details about deprecations are logged at this level.

Example:

```text
WARNING  selenium:test_logging.py:23 this is a warning
```

.NET logs actionable content at logger level `Warn`.

Example:

```text
11:04:40.986 WARN LoggingTest: this is a warning
```

Ruby logs actionable content at logger level — `:warn`. Details about deprecations are logged at this level.

For example:

```text
2023-05-08 20:53:13 WARN Selenium [:example_id] this is a warning 
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
INFO: this is useful information
```

Python logs useful information at logger level — `INFO`

Example:

```text
INFO     selenium:test_logging.py:22 this is useful information
```

.NET logs useful information at logger level `Info`.

Example:

```text
11:04:40.986 INFO LoggingTest: this is useful information
```

Ruby logs useful information at logger level — `:info`.

Example:

```text
2023-05-08 20:53:13 INFO Selenium [:example_id] this is useful information 
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
FINE: this is detailed debug information
```

Python logs debugging details at logger level — `DEBUG`

Example:

```text
DEBUG    selenium:test_logging.py:24 this is detailed debug information
```

.NET logs most debug content at logger level `Debug`.

Example:

```text
11:04:40.986 DEBUG LoggingTest: this is detailed debug information
```

Ruby only provides one level for debugging, so all details are at logger level — `:debug`.

Example:

```text
2023-05-08 20:53:13 DEBUG Selenium [:example_id] this is detailed debug information 
```

```java

      Path output = artifactsDir().resolve("selenium.xml");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L37-L38)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

By default all logs are sent to `sys.stderr`. To direct output somewhere else, you need to add a handler with either a `StreamHandler` or a `FileHandler`:

```py
    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L9-L10)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

By default all logs are sent to `System.Console.Error` output. To direct output somewhere else, you need to add a handler with a `FileLogHandler`:

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L20)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

By default, logs are sent to the console in `stdout`.\
To store the logs in a file:

```rb
    logger.output = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L15)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

JavaScript does not currently support sending output to a file.

To send logs to console output:

```javascript
logging.installConsoleHandler()
```

```java
        logger.addHandler(handler);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L40-L41)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Because logging is managed by module, instead of working with just "selenium", you can specify different levels for different modules:

```py
    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L12-L13)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

.NET logging is managed on a per class level, set the level you want to use on a per-class basis:

```cs

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

Ruby’s logger allows you to opt in (“allow”) or opt out (“ignore”) of log messages based on their IDs. Everything that Selenium logs includes an ID. You can also turn on or off all deprecation notices by using `:deprecations`.

These methods accept one or more symbols or an array of symbols:

```rb
    logger.ignore(:jwp_caps, :logger_info)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L17)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

or

```rb
    logger.allow(%i[selenium_manager example_id])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L18)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

# 3 - Como atualizar para Selenium 4

```java
DesiredCapabilities caps = DesiredCapabilities.firefox();
caps.setCapability("platform", "Windows 10");
caps.setCapability("version", "92");
caps.setCapability("build", myTestBuild);
caps.setCapability("name", myTestName);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), caps);
```

```javascript
caps = {};
caps['browserName'] = 'Firefox';
caps['platform'] = 'Windows 10';
caps['version'] = '92';
caps['build'] = myTestBuild;
caps['name'] = myTestName;
```

```csharp
DesiredCapabilities caps = new DesiredCapabilities();
caps.SetCapability("browserName", "firefox");
caps.SetCapability("platform", "Windows 10");
caps.SetCapability("version", "92");
caps.SetCapability("build", myTestBuild);
caps.SetCapability("name", myTestName);
var driver = new RemoteWebDriver(new Uri(CloudURL), caps);
```

```rb
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L123-L130)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```python
caps = {}
caps['browserName'] = 'firefox'
caps['platform'] = 'Windows 10'
caps['version'] = '92'
caps['build'] = my_test_build
caps['name'] = my_test_name
driver = webdriver.Remote(cloud_url, desired_capabilities=caps)
```

```java
FirefoxOptions browserOptions = new FirefoxOptions();
browserOptions.setPlatformName("Windows 10");
browserOptions.setBrowserVersion("92");
Map<String, Object> cloudOptions = new HashMap<>();
cloudOptions.put("build", myTestBuild);
cloudOptions.put("name", myTestName);
browserOptions.setCapability("cloud:options", cloudOptions);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), browserOptions);
```

```javascript
capabilities = {
  browserName: 'firefox',
  browserVersion: '92',
  platformName: 'Windows 10',
  'cloud:options': {
     build: myTestBuild,
     name: myTestName,
  }
}
```

```csharp
var browserOptions = new FirefoxOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "92";
var cloudOptions = new Dictionary<string, object>();
cloudOptions.Add("build", myTestBuild);
cloudOptions.Add("name", myTestName);
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);
var driver = new RemoteWebDriver(new Uri(CloudURL), browserOptions);
```

```rb
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L38-L47)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```python
from selenium.webdriver.firefox.options import Options as FirefoxOptions
options = FirefoxOptions()
options.browser_version = '92'
options.platform_name = 'Windows 10'
cloud_options = {}
cloud_options['build'] = my_test_build
cloud_options['name'] = my_test_name
options.set_capability('cloud:options', cloud_options)
driver = webdriver.Remote(cloud_url, options=options)
```

### Utilitário para encontrar elemento (s) no Java

O utilitário para localizar elementos no Java (interfaces `FindsBy`) foram removidos visto que se destinavam apenas a uso interno. Os exemplos de código a seguir explicam isso melhor.

Encontrando um único elemento com `findElement*`

Antes

```java

driver.findElementByClassName("className");
driver.findElementByCssSelector(".className");
driver.findElementById("elementId");
driver.findElementByLinkText("linkText");
driver.findElementByName("elementName");
driver.findElementByPartialLinkText("partialText");
driver.findElementByTagName("elementTagName");
driver.findElementByXPath("xPath");
```

Depois

```java

driver.findElement(By.className("className"));
driver.findElement(By.cssSelector(".className"));
driver.findElement(By.id("elementId"));
driver.findElement(By.linkText("linkText"));
driver.findElement(By.name("elementName"));
driver.findElement(By.partialLinkText("partialText"));
driver.findElement(By.tagName("elementTagName"));
driver.findElement(By.xpath("xPath"));
```

Encontrando multiplos elementos com `findElements*`

Antes

```java

driver.findElementsByClassName("className");
driver.findElementsByCssSelector(".className");
driver.findElementsById("elementId");
driver.findElementsByLinkText("linkText");
driver.findElementsByName("elementName");
driver.findElementsByPartialLinkText("partialText");
driver.findElementsByTagName("elementTagName");
driver.findElementsByXPath("xPath");
```

Depois

```java

driver.findElements(By.className("className"));
driver.findElements(By.cssSelector(".className"));
driver.findElements(By.id("elementId"));
driver.findElements(By.linkText("linkText"));
driver.findElements(By.name("elementName"));
driver.findElements(By.partialLinkText("partialText"));
driver.findElements(By.tagName("elementTagName"));
driver.findElements(By.xpath("xPath"));
```

## Atualizando as dependências

Verifique as subseções abaixo para isntalar o Selenium 4 e atualizar as dependências do seu projeto

### Java

O processo de atualização do Selenium depende de qual ferramenta de compilação está sendo usada. Vamos mostrar as mais comuns para Java, como [Maven](https://maven.apache.org/) e [Gradle](https://gradle.org/). A versão minínma do Java ainda é 8.

#### Maven

Antes

```xml

<dependencies>
  <!-- more dependencies ... -->
  <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.141.59</version>
  </dependency>
  <!-- more dependencies ... -->
</dependencies>
```

Depois

```xml

<dependencies>
    <!-- more dependencies ... -->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.4.0</version>
    </dependency>
    <!-- more dependencies ... -->
</dependencies>
```

Após realizar a mudança, você pode executar `mvn clean compile` no mesmo diretório, onde o arquivo `pom.xml` está.

#### Gradle

Antes

```jsonpath

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.141.59'
}
test {
    useJUnitPlatform()
}
```

Depois

```jsonpath

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '4.4.0'
}
test {
    useJUnitPlatform()
}
```

Após realizar a mudança, você pode executar `./gradlew clean build` no mesmo diretório onde o arquivo `build.gradle`está.

Para verifica todas as versões do Java, você pode ir até [MVNRepository](https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java).

### C\#

O local para obter atualizações para Selenium 4 em C# é [NuGet](https://www.nuget.org/) Dentro do pacaote [`Selenium.WebDriver`](https://www.nuget.org/packages/Selenium.WebDriver/4.4.0) você pode seguir as instruções para atualizar para ultima versão. Dentro do Visual Studio, através do NuGet Package Manager você pode executar:

```shell
PM> Install-Package Selenium.WebDriver -Version 4.4.0
```

### Python

A mudança mais importante para usar o Python é a versão minima requerida. Para Selenium 4 a versão miníma requerida será Python3.7 ou superior. Mais detalhes podem ser encontrados aqui:[Python Package Index](https://pypi.org/project/selenium/4.4.3/). Para atualizar através da linha de comando, você pode executar:

```shell
pip install selenium==4.4.3
```

### Ruby

Detalhes para atualizar para o Selenium 4 podem ser vistos aqui: [selenium-webdriver](https://rubygems.org/gems/selenium-webdriver/versions/4.4.0) gem in RubyGems Para instalar a ultima versão, você pode executar:

```shell
gem install selenium-webdriver
```

Para adicioná-lo ao seu Gemfile:

```shell
gem 'selenium-webdriver', '~> 4.4.0'
```

### JavaScript

O pacote selenium-webdriver pode ser encontrado pelo Node package manager, [npmjs](https://www.npmjs.com). Selenium 4 pode ser encontrado [aqui](https://www.npmjs.com/package/selenium-webdriver/v/4.4.0). Para instalar, você pode executar:

```shell
npm install selenium-webdriver
```

Ou, atualize o seu package.json e execute `npm install`:

```json
{
  "name": "selenium-tests",
  "version": "1.0.0",
  "dependencies": {
    "selenium-webdriver": "^4.4.0"
  }
}
```

## Possíveis erros e mensagens de descontinuação

Aqui temos um conjunto de exemplos de código que o ajudarão a superar as mensagens de descontinuação, que você pode encontrar após atualizar para o Selenium 4.

### Java

#### Waits e Timeout

Os parametros que eram esperados de ser recebidos em um Timeout trocaram de `(long time, TimeUnit unit)` para o `(Duration duration)`.

Antes

```java

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(2, TimeUnit.MINUTES);
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
```

Depois

```java

driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().timeouts().scriptTimeout(Duration.ofMinutes(2));
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
```

As esperas(waits) também esperam parâmetros diferentes agora. O `WebDriverWait` agora espera uma `Duration` em vez de um tempo limite `long` em segundos e milissegundos. Os métodos utilitários `withTimeout` e `pollingEvery` do `FluentWait` passaram do `(long time, TimeUnit unit)` para o `(Duration duration)`.

Antes

```java

new WebDriverWait(driver, 3)
.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(30, TimeUnit.SECONDS)
  .pollingEvery(5, TimeUnit.SECONDS)
  .ignoring(NoSuchElementException.class);
```

Depois

```java

new WebDriverWait(driver, Duration.ofSeconds(3))
  .until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

  Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(Duration.ofSeconds(30))
  .pollingEvery(Duration.ofSeconds(5))
  .ignoring(NoSuchElementException.class);
```

#### A fusão de recursos não estã mais alterando o objeto de invocação

Antes era possível fundir um conjunto diferente de recursos em outro counjunto, e isso alterava o objeto de chamada. Agora, o resultado da operação de fusão precisa ser atribuído.

Antes

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options.merge(capabilities);

//Como resultado, o objeto `options` estava sendo modificado.
```

Depois

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options = options.merge(capabilities);

// O resultado da chamada `merge`  precisa ser atribuído a um objeto.
```

#### Firefox Legacy

Antes do GeckoDriver existir, o projeto Selenium tinha uma implementação de driver para automatizar o Firefox(versão<48). Entretanto, esta implementação não é mais necessária, pois não funciona nas versões mais recentes do Firefox. Para evitar graves problemas ao atualizar para o Selenium 4, a opção `setLegacy` será mostrada como obsoleta. A recomendação é parar de utilizar a implementação antiga e depender apenas do GeckoDriver. O código a seguir mostrará a linha `setLegacy` obsoleta após atualizar.

```java
FirefoxOptions options = new FirefoxOptions();
options.setLegacy(true);
```

#### `BrowserType`

A interface `BrowserType` existe há um bom tempo, más ela está ficando obsoleta a favor da nova interface `Browser`.

Antes

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", BrowserType.FIREFOX);
```

Depois

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", Browser.FIREFOX);
```

### C\#

#### `AddAdditionalCapability` está descontinuada

Em vez dela, `AddAdditionalOption` é recomendada. Aqui está um exemplo mostrando isso:

Antes

```cs

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalCapability("cloud:options", cloudOptions, true);
```

Depois

```cs

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);
```

### Python

#### `executable_path foi descontinuada, por favor, passe um Service object`

No Selenium 4, você precisara definir o `executable_path` a partir de um objeto Service para evitar avisos de depreciação. (Ou não defina o caminho e, em vez disso, certifique-se de que o driver que você precisa esteja no System PATH.)

Antes

```python

from selenium import webdriver
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(
    executable_path=CHROMEDRIVER_PATH, 
    options=options
)
```

Depois

```python

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
options = webdriver.ChromeOptions()
service = ChromeService(executable_path=CHROMEDRIVER_PATH)
driver = webdriver.Chrome(service=service, options=options)
```

## Resumo

Passamos pelas principais mudanças a serem levadas em consideração ao atualizar para o Selenium 4. Cobrimos os diferentes aspectos a serem cobertos quando o código de teste é preparado para a atualização, incluindo sugestões sobre como evitar possíveis problemas que podem aparecer ao usar a nova versão do Selenium. Para finalizar, também abordamos um conjunto de possíveis problemas com os quais você pode se deparar depois da atualização e compartilhamos possíveis correções para esses problemas.

*Este tópico foi originalmente postado no site <https://saucelabs.com/resources/articles/how-to-upgrade-to-selenium-4>*

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/bidi/w3c/script/
----

# Script

```java
        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));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L52-L75)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L32-L53)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L201-L210)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L202-L204)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L219-L229)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L222-L227)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L239-L242)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L237-L239)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L280-L283)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L279-L283)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L293-L299)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L292-L299)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            script.disownBrowsingContextScript(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L322-L322)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    await manager.disownBrowsingContextScript(id, boxId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L330-L330)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            script.disownRealmScript(realmId, List.of(boxId));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L375-L375)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    await manager.disownRealmScript(realmId, boxId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L372-L372)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L391-L392)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L383-L385)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L401-402)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L393-L395)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L411-412)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L403-L405)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L422-423)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L416-L416)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L463-463)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L424-L426)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
                script.removePreloadScript(id);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L486-486)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    await manager.removePreloadScript(scriptId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L471-L471)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L37-L51)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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,
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L26-L43)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L58-L68)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L52-L65)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L75-L85)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.19](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.19.0)

```js
    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()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L73-L86)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

[Add Example](/documentation/about/contributing/#creating-examples)

----
url: https://www.selenium.dev/documentation/legacy/selenium_2/upgrading/
----

# Migrating from RC to WebDriver

```java
Selenium selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.yoursite.com");
selenium.start();
```

This should be replaced like so:

```java
WebDriver driver = new FirefoxDriver();
Selenium selenium = new WebDriverBackedSelenium(driver, "http://www.yoursite.com");
```

## Next Steps

Once your tests execute without errors, the next stage is to migrate the actual test code to use the WebDriver APIs. Depending on how well abstracted your code is, this might be a short process or a long one. In either case, the approach is the same and can be summed up simply: modify code to use the new API when you come to edit it.

If you need to extract the underlying WebDriver implementation from the Selenium instance, you can simply cast it to WrapsDriver:

```java
WebDriver driver = ((WrapsDriver) selenium).getWrappedDriver();
```

This allows you to continue passing the Selenium instance around as normal, but to unwrap the WebDriver instance as required.

At some point, you’re codebase will mostly be using the newer APIs. At this point, you can flip the relationship, using WebDriver throughout and instantiating a Selenium instance on demand:

```java
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);
```

## Common Problems

Fortunately, you’re not the first person to go through this migration, so here are some common problems that others have seen, and how to solve them.

### Clicking and Typing is More Complete

A common pattern in a Selenium RC test is to see something like:

```java
selenium.type("name", "exciting tex");
selenium.keyDown("name", "t");
selenium.keyPress("name", "t");
selenium.keyUp("name", "t");
```

```java
Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(30));
WebElement element= wait.until(visibilityOfElementLocated(By.id("some_id")));
```

Where “visibilityOfElementLocated” is implemented as:

```java
public ExpectedCondition<WebElement> visibilityOfElementLocated(final By locator) {
  return new ExpectedCondition<WebElement>() {
    public WebElement apply(WebDriver driver) {
      WebElement toReturn = driver.findElement(locator);
      if (toReturn.isDisplayed()) {
        return toReturn;
      }
      return null;
    }
  };
}
```

This may look complex, but it’s almost all boiler-plate code. The only interesting bit is that the “ExpectedCondition” will be evaluated repeatedly until the “apply” method returns something that is neither “null” nor Boolean.FALSE.

Of course, adding all these “wait” calls may clutter up your code. If that’s the case, and your needs are simple, consider using the implicit waits:

```java
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
```

```java
String name = selenium.getEval(
    "selenium.browserbot.findElement('id=foo', browserbot.getCurrentWindow()).tagName");
```

becomes:

```java
WebElement element = driver.findElement(By.id("foo"));
String name = (String) ((JavascriptExecutor) driver).executeScript(
    "return arguments[0].tagName", element);
```

Notice how the passed in “element” variable appears as the first item in the JS standard “arguments” array.

### Executing Javascript Doesn’t Return Anything

WebDriver’s JavascriptExecutor will wrap all JS and evaluate it as an anonymous expression. This means that you need to use the “return” keyword:

```java
String title = selenium.getEval("browserbot.getCurrentWindow().document.title");
```

becomes:

```java
((JavascriptExecutor) driver).executeScript("return document.title;");
```

----
url: https://www.selenium.dev/pt-br/documentation/about/copyright/
----

# Direitos autorais e atribuições

| Software                            | Versão   | Licença                                                     |
| ----------------------------------- | -------- | ----------------------------------------------------------- |
| [Hugo](/pt-br/)                     | v0.110.0 | [Apache 2.0](//gohugo.io/about/license/)                    |
| [Docsy](//github.com/google/docsy/) | —        | [Apache 2.0](//github.com/google/docsy/blob/master/LICENSE) |

## Licença

Todo o código e documentação proveniente do projeto Selenium está licenciado sob a licença Apache 2.0, com a [Software Freedom Conservancy](/pt-br/) como detentor dos direitos autorais.

A licença está incluída aqui por conveniência, mas você também pode encontrá-la no [Site da Apache Foundation](//apache.org/licenses/LICENSE-2.0.html):

```markdown
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
```

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/encouraged/locators/
----

# 使用定位器的提示

最后修改 February 10, 2022: [#891 Update locators (#947) \[deploy site\] (f39d357da08)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/f39d357da08a64c9dc00e3be29c6c369729482bb)

----
url: https://www.selenium.dev/ja/documentation/grid/advanced_features/observability/
----

# 可観測性

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar standalone --log-level FINE
```

2. Jaeger UI - OpenTelemetry は、コード内のトレースを計測するための API と SDK を提供します。一方、Jaeger はトレースのバックエンドで、トレースのテレメトリデータを収集し、データのクエリ、フィルタリング、ビジュアライズの機能を提供します。

Jaeger UI を用いたトレースの可視化の詳細な手順を確認するには、次のコマンドを実行してください:

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar info tracing
```

[非常に参考になる例と、Jaeger にトレースを送信するスクリプトです](https://github.com/manoj9788/tracing-selenium-grid)

## イベントログの活用

トレースを可視化しない場合でも、イベントロギングではトレースを有効にする必要があります。 **デフォルトでは、トレースは有効です。コンソールでログを見るために、追加のパラメータを渡す必要はありません。** スパン内のすべてのイベントは FINE レベルでログに記録されます。エラーイベントは、WARN レベルでログに記録されます。

全てのイベントは次のフィールドを持ちます:

| フィールド   | フィールド名          | 概要                                                                                                |
| ------- | --------------- | ------------------------------------------------------------------------------------------------- |
| イベント時刻  | eventId         | イベントのタイムスタンプ(エポックナノ秒)。                                                                            |
| トレース ID | tracedId        | 各トレースはトレース ID で一意に識別されます。                                                                         |
| スパン ID  | spanId          | トレース内の各スパンは、スパン ID により一意に識別されます。                                                                  |
| スパン種別   | spanKind        | スパン種別は、スパンの種類を示すスパンのプロパティです。スパンの処理の性質を識別するのに役立ちます。                                                |
| イベント名   | eventName       | ログメッセージにマッピングされます。                                                                                |
| イベント属性  | eventAttributes | イベントログの核となるもので、実行された操作に基づいて JSON フォーマットのキーと値のペアが用意されています。また、ロガークラスを表示するために、ハンドラークラスアトリビュートも含まれます。 |

サンプルログ

```
FINE [LoggingOptions$1.lambda$export$1] - {
  "traceId": "fc8aef1d44b3cc8bc09eb8e581c4a8eb",
  "spanId": "b7d3b9865d3ddd45",
  "spanKind": "INTERNAL",
  "eventTime": 1597819675128886121,
  "eventName": "Session request execution complete",
  "attributes": {
    "http.status_code": 200,
    "http.handler_class": "org.openqa.selenium.grid.router.HandleSession",
    "http.url": "\u002fsession\u002fdd35257f104bb43fdfb06242953f4c85",
    "http.method": "DELETE",
    "session.id": "dd35257f104bb43fdfb06242953f4c85"
  }
}
```

上記のフィールドに加えて、[OpenTelemetry の仕様](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/exceptions.md)に基づきエラーログは以下のフィールドで構成されます:

| フィールド    | フィールド名               | 概要                                           |
| -------- | -------------------- | -------------------------------------------- |
| 例外タイプ    | exception.type       | 例外クラス名。                                      |
| 例外メッセージ  | exception.message    | 例外の原因。                                       |
| スタックトレース | exception.stacktrace | 例外が発生した時点のコールスタックを表示します。 例外の発生源を把握するのに役立ちます。 |

サンプルエラーログ

```
WARN [LoggingOptions$1.lambda$export$1] - {
  "traceId": "7efa5ea57e02f89cdf8de586fe09f564",
  "spanId": "914df6bc9a1f6e2b",
  "spanKind": "INTERNAL",
  "eventTime": 1597820253450580272,
  "eventName": "exception",
  "attributes": {
    "exception.type": "org.openqa.selenium.ScriptTimeoutException",
    "exception.message": "Unable to execute request: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist ..." (full message will be printed),
    "exception.stacktrace": "org.openqa.selenium.ScriptTimeoutException: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist\nBuild info: version: '4.0.0-alpha-7', revision: 'Unknown'\nSystem info: host: 'XYZ-MacBook-Pro.local', ip: 'fe80:0:0:0:10d5:b63a:bdc6:1aff%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.7'\nDriver info: driver.version: unknown ...." (full stack will be printed),
    "http.handler_class": "org.openqa.selenium.grid.distributor.remote.RemoteDistributor",
    "http.url": "\u002fsession",
    "http.method": "POST"
  }
}
```

注: ログは読みやすさのためプリティプリントされています。Selenimu サーバーではぷるティプリントはオフになっています。

以上がトレースとログをセットアップするための手順です。

## 参考

1. [Understanding Tracing](https://lightstep.com/blog/opentelemetry-101-what-is-tracing/)
2. [OpenTelemetry Tracing API Specification](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/api.md#status)
3. [Selenium Wiki](https://github.com/SeleniumHQ/selenium/wiki)
4. [Structured logs vs events](https://www.honeycomb.io/blog/how-are-structured-logs-different-from-events/)
5. [Jaeger framework](https://github.com/jaegertracing/jaeger)

----
url: https://www.selenium.dev/ja/documentation/webdriver/browsers/firefox/
----

# Firefox特有の機能

```java
    driver = new FirefoxDriver(options);
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L36-L37)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L10-L11)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
        public void BasicOptions()
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L34-L35)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/openFirefoxTest.spec.js#L10-L13)

##### /examples/javascript/test/getting\_started/openFirefoxTest.spec.js

```js
const {Browser, Builder} = require('selenium-webdriver');
const firefox = require('selenium-webdriver/firefox');


describe('Open Firefox', function () {
  let driver;

  before(async function () {
    let options = new firefox.Options();
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options)
      .build();
  });

  after(async () => await driver.quit());

  it('Basic Firefox test', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options.add_argument("-headless")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L19)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            var options = new FirefoxOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L43)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options.args << '-headless'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L17)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
      .setFirefoxOptions(options.addArguments('--headless'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L12)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L54)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options.binary_location = firefox_bin
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L28)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            var options = new FirefoxOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L53)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options.binary = firefox_location
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L25)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
    driver = new FirefoxDriver(options);
  }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L211-L216)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L160-L168)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```csharp
var options = new FirefoxOptions();
var profile = new FirefoxProfile();
options.Profile = profile;
var driver = new RemoteWebDriver(options);
  
```

```rb
      profile = Selenium::WebDriver::Firefox::Profile.new
        profile['browser.download.dir'] = '/tmp/webdriver-downloads'
        options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L139-L141)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true
  
  require 'spec_helper'
  
  RSpec.describe 'Firefox' do
    describe 'Options' do
      let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }
  
      it 'basic options' do
        options = Selenium::WebDriver::Options.firefox
        @driver = Selenium::WebDriver.for :firefox, options: options
      end
  
      it 'add arguments' do
        options = Selenium::WebDriver::Options.firefox
  
        options.args << '-headless'
  
        @driver = Selenium::WebDriver.for :firefox, options: options
      end
  
      it 'sets location of binary' do
        options = Selenium::WebDriver::Options.firefox
  
        options.binary = firefox_location
  
        @driver = Selenium::WebDriver.for :firefox, options: options
      end
    end
  
    describe 'Service' do
      let(:file_name) { Tempfile.new('geckodriver').path }
      let(:root_directory) { Dir.mktmpdir }
  
      after do
        FileUtils.rm_f(file_name)
        FileUtils.rm_rf(root_directory)
      end
  
      it 'logs to file' do
        service = Selenium::WebDriver::Service.firefox
  
        service.log = file_name
  
        @driver = Selenium::WebDriver.for :firefox, service: service
        expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
      end
  
      it 'logs to console' do
        service = Selenium::WebDriver::Service.firefox
  
        service.log = $stdout
  
        expect {
          @driver = Selenium::WebDriver.for :firefox, service: service
        }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
      end
  
      it 'sets log level' do
        service = Selenium::WebDriver::Service.firefox
        service.log = file_name
  
        service.args += %w[--log debug]
  
        @driver = Selenium::WebDriver.for :firefox, service: service
        expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
      end
  
      it 'stops truncating log lines' do
        service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])
  
        service.args << '--log-no-truncate'
  
        @driver = Selenium::WebDriver.for :firefox, service: service
        expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
      end
  
      it 'sets default profile location' do
        service = Selenium::WebDriver::Service.firefox
  
        service.args += ['--profile-root', root_directory]
  
        @driver = Selenium::WebDriver.for :firefox, service: service
        profile_location = Dir.new(@driver.capabilities['moz:profile'])
        expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
      end
    end
  
    describe 'Features' do
      let(:driver) { start_firefox }
  
      it 'installs addon' do
        extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
  
        driver.install_addon(extension_file_path)
  
        driver.get 'https://www.selenium.dev/selenium/web/blank.html'
        injected = driver.find_element(id: 'webextensions-selenium-example')
        expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
      end
  
      it 'uninstalls addon' do
        extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
        extension_id = driver.install_addon(extension_file_path)
  
        driver.uninstall_addon(extension_id)
  
        driver.get 'https://www.selenium.dev/selenium/web/blank.html'
        expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
      end
  
      it 'installs unsigned addon' do
        extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)
  
        driver.install_addon(extension_dir_path, true)
  
        driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
        injected = driver.find_element(id: 'webextensions-selenium-example')
        expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
      end
  
      it 'takes full page screenshot' do
        driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
        Dir.mktmpdir('screenshot_test') do |dir|
          screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))
  
          expect(screenshot).to be_a File
        end
      end
  
      it 'sets the context' do
        driver.context = 'content'
        expect(driver.context).to eq 'content'
      end
    end
  
    describe 'Profile' do
      it 'creates a new profile' do
        profile = Selenium::WebDriver::Firefox::Profile.new
        profile['browser.download.dir'] = '/tmp/webdriver-downloads'
        options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
        expect(options.profile).to eq(profile)
      end
    end
  
    def driver_finder
      options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
      service = Selenium::WebDriver::Service.firefox
      finder = Selenium::WebDriver::DriverFinder.new(options, service)
      ENV['GECKODRIVER_BIN'] = finder.driver_path
      ENV['FIREFOX_BIN'] = finder.browser_path
    end
  end
  
```

```javascript
const { Builder } = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');

const options = new firefox.Options();
let profile = '/path to custom profile';
options.setProfile(profile);
const driver = new Builder()
    .forBrowser('firefox')
    .setFirefoxOptions(options)
    .build();
  
```

```kotlin
val options = FirefoxOptions()
options.profile = FirefoxProfile()
driver = RemoteWebDriver(options)
  
```

```java
        new GeckoDriverService.Builder().withLogFile(logLocation).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L62-L63)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**注**: Java では、システムプロパティによってファイル出力を設定することもできます。\
プロパティキー:`GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY`\
プロパティ値: ログファイルへのパスを表す文字列

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L36)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L43)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withLogOutput(System.out).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L76-L77)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**注意**: Javaは、システムプロパティを使用してコンソール出力を設定することもできます;\
プロパティキー: `GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY`\
プロパティ値: `DriverService.LOG_STDOUT` または `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L48)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L52)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L90-L91)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**注意**: Javaは、システムプロパティによってログレベルの設定も可能です:\
プロパティキー: `GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY`\
プロパティ値:`FirefoxDriverLogLevel`列挙型の文字列表現

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L59)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args += %w[--log debug]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L63)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L106-L107)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**注意**: Javaでは、システムプロパティによってログレベルを設定することもできます。\
プロパティキー: `GeckoDriverService.GECKO_DRIVER_LOG_NO_TRUNCATE`\
プロパティ値: `"true"` または `"false"`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L70)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '--log-no-truncate'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L72)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L118-L119)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**注意**: Javaでは、システムプロパティを使用してログレベルを設定することもできます：\
プロパティキー: `GeckoDriverService.GECKO_DRIVER_PROFILE_ROOT`\
プロパティ値: プロファイルルートディレクトリへのパスを表す文字列

```py
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L81)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args += ['--profile-root', root_directory]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L81)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L133)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.install_addon(addon_path_xpi)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L94)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L137)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      driver.install_addon(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L95)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    let id = await driver.installAddon(xpiPath);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L25)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L148)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.uninstall_addon(id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L106)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```cs
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L152)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      driver.uninstall_addon(extension_id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L106)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    await driver.uninstallAddon(id);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L26)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L160)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.install_addon(addon_path_dir, temporary=True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L115)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```cs
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L165)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```rb
      driver.install_addon(extension_dir_path, true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L115)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    let id = await driver.installAddon(xpiPath, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L41)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L181)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.save_full_page_screenshot("full_page_screenshot.png")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L139)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L125)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
    // Verify the context is back to "content"
    Assertions.assertEquals(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L197-L198)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L151-L152)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      driver.context = 'content'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L132)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

**Note**: As of Firefox 138, geckodriver needs to be started with the argument `--allow-system-access` to switch the context to `CHROME`.

----
url: https://www.selenium.dev/ja/_print/documentation/webdriver/actions_api/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/webdriver/actions_api/).

# アクション API

仮想化されたデバイス入力アクションを Web ブラウザーに提供するための低レベルのインターフェイス。

* 1: [Keyboard actions](#pg-0a4ec92d386265c0bdf699e27c72f32e)
* 2: [Mouse actions](#pg-f66156e1f0bb539477626a1460b180c4)
* 3: [Pen actions](#pg-927165f37a6ca69af5c5f010b30761d7)
* 4: [Scroll wheel actions](#pg-2855d2d5622f17836c50921d04925c37)

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/ActionsTest.java#L21-L28)

##### /examples/java/src/test/java/dev/selenium/actions\_api/ActionsTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;

public class ActionsTest extends BaseChromeTest {
    @Test
    public void pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        long start = System.currentTimeMillis();

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();

        long duration = System.currentTimeMillis() - start;
        Assertions.assertTrue(duration > 2000);
        Assertions.assertTrue(duration < 3000);
    }

    @Test
    public void releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        Actions actions = new Actions(driver);
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        ((RemoteWebDriver) driver).resetInputState();

        actions.sendKeys("a").perform();
        Assertions.assertEquals("A", String.valueOf(clickable.getAttribute("value").charAt(0)));
        Assertions.assertEquals("a", String.valueOf(clickable.getAttribute("value").charAt(1)));
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_actions.py#L13-L20)

##### /examples/python/tests/actions\_api/test\_actions.py

```py
from time import time

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.by import By


def test_pauses(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    start = time()

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()

    duration = time() - start
    assert duration > 2
    assert duration < 3


def test_releases_all(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .click_and_hold(clickable)\
        .key_down(Keys.SHIFT)\
        .key_down("a")\
        .perform()

    ActionBuilder(driver).clear_actions()

    ActionChains(driver).key_down('a').perform()

    assert clickable.get_attribute('value')[0] == "A"
    assert clickable.get_attribute('value')[1] == "a"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs#L18-L25)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class ActionsTest : BaseChromeTest
    {
        [TestMethod]
        public void Pause()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            DateTime start = DateTime.Now;

            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();

            TimeSpan duration = DateTime.Now - start;
            Assert.IsTrue(duration > TimeSpan.FromSeconds(2));
            Assert.IsTrue(duration < TimeSpan.FromSeconds(3));
        }

        [TestMethod]
        public void ReleaseAll()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            var actions = new Actions(driver);
            actions.ClickAndHold(clickable)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            ((WebDriver)driver).ResetInputState();

            actions.SendKeys("a").Perform();
            var value = clickable.GetAttribute("value");
            Assert.AreEqual("A", value[..1]);
            Assert.AreEqual("a", value.Substring(1, 1));
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/actions_spec.rb#L12-L19)

##### /examples/ruby/spec/actions\_api/actions\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Actions' do
  let(:driver) { start_session }

  it 'pauses' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
    start = Time.now

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform

    duration = Time.now - start
    expect(duration).to be > 2
    expect(duration).to be < 3
  end

  it 'releases all' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    action = driver.action
                   .click_and_hold(clickable)
                   .key_down(:shift)
                   .key_down('a')
    action.perform

    driver.action.release_actions

    action.key_down('a').perform
    expect(clickable.attribute('value')[0]).to eq 'A'
    expect(clickable.attribute('value')[-1]).to eq 'a'
  end
end
```

```js
    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/actionsTest.spec.js#L18-L25)

##### /examples/javascript/test/actionsApi/actionsTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Pause and Release All Actions', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('Pause', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const start = Date.now()

    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()

    const end = Date.now() - start
    assert.ok(end > 2000)
    assert.ok(end < 4000)
  })

  it('Clear', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const clickable = driver.findElement(By.id('clickable'))
    await driver.actions()
      .click(clickable)
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    await driver.actions().clear()
    await driver.actions().sendKeys('a').perform()

    const value = await clickable.getAttribute('value')
    assert.deepStrictEqual('A', value.substring(0, 1))
    assert.deepStrictEqual('a', value.substring(1, 2))
  })
})
```

```kt
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/ActionsTest.kt#L22-L29)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/ActionsTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration

class ActionsTest : BaseTest() {

    @Test
    fun pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val start = System.currentTimeMillis()

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 

        val duration = System.currentTimeMillis() - start
        Assertions.assertTrue(duration > 2000)
        Assertions.assertTrue(duration < 4000)
    }

    @Test
    fun releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        val actions = Actions(driver)
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        (driver as RemoteWebDriver).resetInputState()

        actions.sendKeys("a").perform()
        Assertions.assertEquals("A", clickable.getAttribute("value")!!.get(0).toString())
        Assertions.assertEquals("a", clickable.getAttribute("value")!!.get(1).toString())
    }
}
```

```java
        ((RemoteWebDriver) driver).resetInputState();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/ActionsTest.java#L46)

##### /examples/java/src/test/java/dev/selenium/actions\_api/ActionsTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;

public class ActionsTest extends BaseChromeTest {
    @Test
    public void pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        long start = System.currentTimeMillis();

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();

        long duration = System.currentTimeMillis() - start;
        Assertions.assertTrue(duration > 2000);
        Assertions.assertTrue(duration < 3000);
    }

    @Test
    public void releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        Actions actions = new Actions(driver);
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        ((RemoteWebDriver) driver).resetInputState();

        actions.sendKeys("a").perform();
        Assertions.assertEquals("A", String.valueOf(clickable.getAttribute("value").charAt(0)));
        Assertions.assertEquals("a", String.valueOf(clickable.getAttribute("value").charAt(1)));
    }
}
```

```py
    ActionBuilder(driver).clear_actions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_actions.py#L37)

##### /examples/python/tests/actions\_api/test\_actions.py

```py
from time import time

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.by import By


def test_pauses(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    start = time()

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()

    duration = time() - start
    assert duration > 2
    assert duration < 3


def test_releases_all(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .click_and_hold(clickable)\
        .key_down(Keys.SHIFT)\
        .key_down("a")\
        .perform()

    ActionBuilder(driver).clear_actions()

    ActionChains(driver).key_down('a').perform()

    assert clickable.get_attribute('value')[0] == "A"
    assert clickable.get_attribute('value')[1] == "a"
```

```cs
            ((WebDriver)driver).ResetInputState();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs#L44)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class ActionsTest : BaseChromeTest
    {
        [TestMethod]
        public void Pause()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            DateTime start = DateTime.Now;

            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();

            TimeSpan duration = DateTime.Now - start;
            Assert.IsTrue(duration > TimeSpan.FromSeconds(2));
            Assert.IsTrue(duration < TimeSpan.FromSeconds(3));
        }

        [TestMethod]
        public void ReleaseAll()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            var actions = new Actions(driver);
            actions.ClickAndHold(clickable)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            ((WebDriver)driver).ResetInputState();

            actions.SendKeys("a").Perform();
            var value = clickable.GetAttribute("value");
            Assert.AreEqual("A", value[..1]);
            Assert.AreEqual("a", value.Substring(1, 1));
        }
    }
}
```

```rb
    driver.action.release_actions
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/actions_spec.rb#L36)

##### /examples/ruby/spec/actions\_api/actions\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Actions' do
  let(:driver) { start_session }

  it 'pauses' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
    start = Time.now

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform

    duration = Time.now - start
    expect(duration).to be > 2
    expect(duration).to be < 3
  end

  it 'releases all' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    action = driver.action
                   .click_and_hold(clickable)
                   .key_down(:shift)
                   .key_down('a')
    action.perform

    driver.action.release_actions

    action.key_down('a').perform
    expect(clickable.attribute('value')[0]).to eq 'A'
    expect(clickable.attribute('value')[-1]).to eq 'a'
  end
end
```

```js
    await driver.actions().clear()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/actionsTest.spec.js#L42)

##### /examples/javascript/test/actionsApi/actionsTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Pause and Release All Actions', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('Pause', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const start = Date.now()

    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()

    const end = Date.now() - start
    assert.ok(end > 2000)
    assert.ok(end < 4000)
  })

  it('Clear', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const clickable = driver.findElement(By.id('clickable'))
    await driver.actions()
      .click(clickable)
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    await driver.actions().clear()
    await driver.actions().sendKeys('a').perform()

    const value = await clickable.getAttribute('value')
    assert.deepStrictEqual('A', value.substring(0, 1))
    assert.deepStrictEqual('a', value.substring(1, 2))
  })
})
```

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/ActionsTest.kt#L47)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/ActionsTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration

class ActionsTest : BaseTest() {

    @Test
    fun pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val start = System.currentTimeMillis()

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 

        val duration = System.currentTimeMillis() - start
        Assertions.assertTrue(duration > 2000)
        Assertions.assertTrue(duration < 4000)
    }

    @Test
    fun releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        val actions = Actions(driver)
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        (driver as RemoteWebDriver).resetInputState()

        actions.sendKeys("a").perform()
        Assertions.assertEquals("A", clickable.getAttribute("value")!!.get(0).toString())
        Assertions.assertEquals("a", clickable.getAttribute("value")!!.get(1).toString())
    }
}
```

# 1 - Keyboard actions

```java
        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L17-L20)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L10-L13)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L13-L16)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L17-L20)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L19-L22)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L30-L35)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L21-L26)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L30-L35)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L25-L30)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L32-L37)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L32-L37)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .sendKeys("abc")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L45-L47)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L34-L36)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs

            new Actions(driver)
                .SendKeys("abc")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L45-L47)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .send_keys('abc')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L39-L41)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .sendKeys('abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L48-L50)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .sendKeys("abc")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L47-L49)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L59-L62)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L45-L48)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L58-L61)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L51-L54)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L59-L63)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L60-L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L70-L84)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L56-L67)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L72-L82)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L64-L74)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L73-L85)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L74-L86)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L22-L25)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L14-L17)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L11-L14)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    let clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.move({origin: clickable}).press().perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/clickAndHold.spec.js#L14-L16)

##### /examples/javascript/test/actionsApi/mouse/clickAndHold.spec.js

```js
const {By, Builder} = require('selenium-webdriver');

describe('Click and hold', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and mouseDown on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    let clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.move({origin: clickable}).press().perform();
  });
});
```

```kt
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L23-L26)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L34-L37)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L26-L29)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L30-L33)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L22-L25)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    let click = driver.findElement(By.id("click"));
    const actions = driver.actions({async: true});
    await actions.move({origin: click}).click().perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/clickAndRelease.spec.js#L14-L16)

##### /examples/javascript/test/actionsApi/mouse/clickAndRelease.spec.js

```js
const {By,Builder} = require('selenium-webdriver');

describe('Click and release', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    let click = driver.findElement(By.id("click"));
    const actions = driver.actions({async: true});
    await actions.move({origin: click}).click().perform();
  });
});
```

```kt
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L35-L38)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L46-L49)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L37-L40)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L43-L46)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L34-L37)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.contextClick(clickable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/rightClick.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/rightClick.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Right click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and right click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.contextClick(clickable).perform();

    await driver.sleep(500);
    const clicked = await driver.findElement(By.id('click-status')).getText();
    assert.deepStrictEqual(clicked, `context-clicked`)
  });
});
```

```kt
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L47-L50)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L60-L66)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L51-L54)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L59-L63)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L47-L50)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js#L19-L20)

##### /examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js

```js
const {By, Button, Browser, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Should be able to perform BACK click and FORWARD click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Back click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)

    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)
  });

  it('Forward click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();
    await driver.navigate().back();

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)

    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L61-L67)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L78-L84)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L65-L68)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L77-L81)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L61-L64)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js#L32-L33)

##### /examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js

```js
const {By, Button, Browser, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Should be able to perform BACK click and FORWARD click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Back click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)

    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)
  });

  it('Forward click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();
    await driver.navigate().back();

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)

    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L79-L85)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L93-L96)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L76-L79)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L91-L94)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L73-L76)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.doubleClick(clickable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/doubleClick.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/doubleClick.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Double click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Double-click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.doubleClick(clickable).perform();

    await driver.sleep(500);
    const status = await driver.findElement(By.id('click-status')).getText();
    assert.deepStrictEqual(status, `double-clicked`)
  });
});
```

```kt
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L94-L97)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L105-L108)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L87-L90)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L104-L107)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L84-L87)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const hoverable = driver.findElement(By.id("hover"));
    const actions = driver.actions({async: true});
    await actions.move({origin: hoverable}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveToElement.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/moveToElement.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Move to element', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move into an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const hoverable = driver.findElement(By.id("hover"));
    const actions = driver.actions({async: true});
    await actions.move({origin: hoverable}).perform();

    const status = await driver.findElement(By.id('move-status')).getText();
    assert.deepStrictEqual(status, `hovered`)
  });
});
```

```kt
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L106-L109)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L118-L121)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L98-L101)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L132-L135)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L97-L100)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L119-L122)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L131-L136)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L110-L112)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L146-L150)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      driver.action
            .move_to_location(8, 12)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L114-L116)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L27-L28)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L132-L137)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L153-L155)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L126-L128)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L167-L169)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      driver.action
            .move_by(13, 15)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L128-L130)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L40)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L154-L156)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L166-L170)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L139-L143)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L181-L185)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L141-L145)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js#L27-L30)

##### /examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Drag and Drop', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('By Offset', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });

  it('Onto Element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });
});
```

```kt
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L167-L171)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L179-L184)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L151-L156)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L195-L200)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L153-L158)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js#L15-L19)

##### /examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Drag and Drop', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('By Offset', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });

  it('Onto Element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });
});
```

```kt
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L180-L185)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/PenTest.java#L26-L33)

##### /examples/java/src/test/java/dev/selenium/actions\_api/PenTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PenTest extends BaseChromeTest {
    @Test
    public void usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();

        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    @Test
    public void setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();
        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("-72", moveBy.get("tiltX"));
        Assertions.assertEquals("9", moveBy.get("tiltY"));
        Assertions.assertEquals("86", moveBy.get("twist"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    private Map<String, String> getPropertyInfo(WebElement element) {
        String text = element.getText();
        text = text.substring(text.indexOf(' ') + 1);

        return Arrays.stream(text.split(", "))
                .map(s -> s.split(": "))
                .collect(Collectors.toMap(
                        a -> a[0],
                        a -> a[1]
                ));
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_pen.py#L12-L20)

##### /examples/python/tests/actions\_api/test\_pen.py

```py
import math

from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.interaction import POINTER_PEN
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.by import By


def test_use_pen(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def test_set_pointer_event_properties(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert move_by["tiltX"] == "-72"
    assert move_by["tiltY"] == "9"
    assert move_by["twist"] == "86"
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def properties(element):
    kv = element.text.split(' ', 1)[1].split(', ')
    return {x[0]:x[1] for x in list(map(lambda item: item.split(': '), kv))}
```

```cs
            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs#L19-L28)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class PenTest : BaseChromeTest
    {
        [TestMethod]
        public void UsePen()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        [TestMethod]
        public void SetPointerEventProperties()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual((-72).ToString(), moveBy["tiltX"]);
            Assert.AreEqual((9).ToString(), moveBy["tiltY"]);
            Assert.AreEqual((86).ToString(), moveBy["twist"]);
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        private Dictionary<string, string> getProperties(IWebElement element)
        {
            var str = element.Text;
            str = str[(str.Split()[0].Length + 1)..];
            IEnumerable<string[]> keyValue = str.Split(", ").Select(part => part.Split(":"));
            return keyValue.ToDictionary(split => split[0].Trim(), split => split[1].Trim());
        }

        private bool VerifyEquivalent(decimal expected, string actual)
        {
            var absolute = Math.Abs(expected - decimal.Parse(actual));
            if (absolute <= 1)
            {
                return true;
            }

            throw new Exception("Expected: " + expected + "; but received: " + actual);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/pen_spec.rb#L11-L17)

##### /examples/ruby/spec/actions\_api/pen\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Pen' do
  let(:driver) { start_session }

  it 'uses a pen' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  it 'sets pointer event attributes' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s,
                               'tiltX' => -72.to_s,
                               'tiltY' => 9.to_s,
                               'twist' => 86.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  def properties(element)
    element.text.sub(/.*?\s/, '').split(',').to_h { |item| item.lstrip.split(/\s*:\s*/) }
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/PenTest.kt#L23-L30)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/PenTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import kotlin.collections.Map
import java.time.Duration

class PenTest : BaseTest() {
  
    @Test
    fun usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
    }

    @Test
    fun setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY")) 
	    
        Assertions.assertEquals("-72", moveBy.get("tiltX"))
        Assertions.assertEquals("9", moveBy.get("tiltY"))
        Assertions.assertEquals("86", moveBy.get("twist"))
    }
    
    fun getPropertyInfo(element: WebElement): Map<String, String> {
        var text = element.getText()  
        text = text.substring(text.indexOf(" ")+1)
        return text.split(", ")
        .map { it.split(": ") }
        .map { it.first() to it.last() }
        .toMap() 
    }
}
```

```java
        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/PenTest.java#L67-L81)

##### /examples/java/src/test/java/dev/selenium/actions\_api/PenTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PenTest extends BaseChromeTest {
    @Test
    public void usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();

        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    @Test
    public void setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();
        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("-72", moveBy.get("tiltX"));
        Assertions.assertEquals("9", moveBy.get("tiltY"));
        Assertions.assertEquals("86", moveBy.get("twist"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    private Map<String, String> getPropertyInfo(WebElement element) {
        String text = element.getText();
        text = text.substring(text.indexOf(' ') + 1);

        return Arrays.stream(text.split(", "))
                .map(s -> s.split(": "))
                .collect(Collectors.toMap(
                        a -> a[0],
                        a -> a[1]
                ));
    }
}
```

```py
    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_pen.py#L53-L61)

##### /examples/python/tests/actions\_api/test\_pen.py

```py
import math

from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.interaction import POINTER_PEN
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.by import By


def test_use_pen(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def test_set_pointer_event_properties(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert move_by["tiltX"] == "-72"
    assert move_by["tiltY"] == "9"
    assert move_by["twist"] == "86"
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def properties(element):
    kv = element.text.split(' ', 1)[1].split(', ')
    return {x[0]:x[1] for x in list(map(lambda item: item.split(': '), kv))}
```

```cs
            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs#L64-L77)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class PenTest : BaseChromeTest
    {
        [TestMethod]
        public void UsePen()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        [TestMethod]
        public void SetPointerEventProperties()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual((-72).ToString(), moveBy["tiltX"]);
            Assert.AreEqual((9).ToString(), moveBy["tiltY"]);
            Assert.AreEqual((86).ToString(), moveBy["twist"]);
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        private Dictionary<string, string> getProperties(IWebElement element)
        {
            var str = element.Text;
            str = str[(str.Split()[0].Length + 1)..];
            IEnumerable<string[]> keyValue = str.Split(", ").Select(part => part.Split(":"));
            return keyValue.ToDictionary(split => split[0].Trim(), split => split[1].Trim());
        }

        private bool VerifyEquivalent(decimal expected, string actual)
        {
            var absolute = Math.Abs(expected - decimal.Parse(actual));
            if (absolute <= 1)
            {
                return true;
            }

            throw new Exception("Expected: " + expected + "; but received: " + actual);
        }
    }
}
```

```rb
    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/pen_spec.rb#L50-L56)

##### /examples/ruby/spec/actions\_api/pen\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Pen' do
  let(:driver) { start_session }

  it 'uses a pen' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  it 'sets pointer event attributes' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s,
                               'tiltX' => -72.to_s,
                               'tiltY' => 9.to_s,
                               'twist' => 86.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  def properties(element)
    element.text.sub(/.*?\s/, '').split(',').to_h { |item| item.lstrip.split(/\s*:\s*/) }
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/PenTest.kt#L64-L78)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/PenTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import kotlin.collections.Map
import java.time.Duration

class PenTest : BaseTest() {
  
    @Test
    fun usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
    }

    @Test
    fun setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY")) 
	    
        Assertions.assertEquals("-72", moveBy.get("tiltX"))
        Assertions.assertEquals("9", moveBy.get("tiltY"))
        Assertions.assertEquals("86", moveBy.get("twist"))
    }
    
    fun getPropertyInfo(element: WebElement): Map<String, String> {
        var text = element.getText()  
        text = text.substring(text.indexOf(" ")+1)
        return text.split(", ")
        .map { it.split(": ") }
        .map { it.first() to it.last() }
        .toMap() 
    }
}
```

```java
        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L17-L20)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L11-L14)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L11-L14)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L16-L19)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L18-L21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L29-L33)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L22-L26)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L31-L35)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L22-L26)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L26-L31)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L30-L34)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L42-L46)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L35-L39)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L46-L53)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L34-L38)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L40-L44)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L43-L47)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L57-L61)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L50-L54)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L66-L75)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L48-L52)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L57-L61)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L59-L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L73-L76)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L66-L70)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L89-L97)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L63-L66)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L75-L77)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L75-L78)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

----
url: https://www.selenium.dev/documentation/webdriver/bidi/script/
----

# WebDriver BiDi Script Features

These features are related to scripts, and are made available via a “script” namespace.

The implementation of these features is being tracked here: [#13992](https://github.com/SeleniumHQ/selenium/issues/13992)

Remember that to use WebDriver BiDi, you must enable it in Options. For more details, see [Enabling BiDi](https://www.selenium.dev/documentation/webdriver/bidi/)

## Script Pinning

## Execute Script

## DOM Mutation Handlers

----
url: https://www.selenium.dev/documentation/webdriver/getting_started/using_selenium/
----

# Organizing and Executing Selenium Code

```java
		String title = driver.getTitle();
		assertEquals("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L30-L31)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java
package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

```py
    title = driver.title
    assert title == "Web form"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L8-L9)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

```cs
            var title = driver.Title;
            Assert.AreEqual("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs#L19-L20)

##### /examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted
{
    [TestClass]
    public class UsingSeleniumTest
    {

        [TestMethod]
        public void EightComponents()
        {
            IWebDriver driver = new ChromeDriver();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

            var title = driver.Title;
            Assert.AreEqual("Web form", title);

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            var textBox = driver.FindElement(By.Name("my-text"));
            var submitButton = driver.FindElement(By.TagName("button"));
            
            textBox.SendKeys("Selenium");
            submitButton.Click();
            
            var message = driver.FindElement(By.Id("message"));
            var value = message.Text;
            Assert.AreEqual("Received!", value);
            
            driver.Quit();
        }
    }
}
```

```rb
    title = @driver.title
    expect(title).to eq('Web form')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb#L14-L15)

##### /examples/ruby/spec/getting\_started/using\_selenium\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

```js
    let title = await driver.getTitle();
    assert.equal("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L14-L15)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

```java
	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L19-L22)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java
package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

### Tear Down

```java
	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L45-L48)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java
package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

### Set Up

```py
def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L25-L28)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

### Tear Down

```py
def teardown(driver):
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L30-31)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

### Set Up

```rb
  before do
    @driver = Selenium::WebDriver.for :chrome
  end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb#L7-L9)

##### /examples/ruby/spec/getting\_started/using\_selenium\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

### Tear Down

```rb
  config.after { @driver&.quit }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/spec_helper.rb#L30)

##### /examples/ruby/spec/spec\_helper.rb

```rb
# frozen_string_literal: true

require 'selenium-webdriver'
require 'selenium/webdriver/support/guards'

RSpec.configure do |config|
  # Enable flags like --only-failures and --next-failure
  config.example_status_persistence_file_path = '.rspec_status'

  # Disable RSpec exposing methods globally on `Module` and `main`
  config.disable_monkey_patching!
  Dir.mktmpdir('tmp')
  config.example_status_persistence_file_path = 'tmp/examples.txt'

  config.expect_with :rspec do |c|
    c.syntax = :expect
  end

  config.before do |example|
    bug_tracker = 'https://github.com/SeleniumHQ/seleniumhq.github.io/issues'
    guards = Selenium::WebDriver::Support::Guards.new(example,
                                                      bug_tracker: bug_tracker)
    guards.add_condition(:platform, Selenium::WebDriver::Platform.os)
    guards.add_condition(:ci, Selenium::WebDriver::Platform.ci)

    results = guards.disposition
    send(*results) if results
  end

  config.after { @driver&.quit }

  def start_session
    options = Selenium::WebDriver::Chrome::Options.new
    options.add_argument('disable-search-engine-choice-screen')
    options.add_argument('--no-sandbox')
    @driver = Selenium::WebDriver.for(:chrome, options: options)
  end

  def start_bidi_session
    options = Selenium::WebDriver::Chrome::Options.new(web_socket_url: true)
    @driver = Selenium::WebDriver.for :chrome, options: options
  end

  def start_firefox
    options = Selenium::WebDriver::Options.firefox(timeouts: {implicit: 1500})
    @driver = Selenium::WebDriver.for :firefox, options: options
  end
end
```

\### Set Up

```js
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L7-L9)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

\### Tear Down

```js
  after(async () => await driver.quit());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L30)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

```shell
mvn clean test
```

### Gradle

```shell
gradle clean test
```

````md
```
````

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/README.md#L35)

##### /examples/python/README.md

````md
# Running tests from Selenium Python examples

#### 1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

#### 2. Navigate to `python` directory

```
cd seleniumhq.github.io/examples/python
```

#### 3. Create a virtual environment

- On Windows:

```
py -m venv venv
venv\Scripts\activate
```

- On Linux/Mac:

```
python3 -m venv venv
source venv/bin/activate
```

#### 4. Install dependencies:

```
pip install -r requirements.txt
```

> for help, see: https://packaging.python.org/en/latest/tutorials/installing-packages

#### 5. Run tests

- Run all tests with the default Python interpreter:

```
pytest
```

- Run all tests with every installed/supported Python interpreter:

```
tox
```

> Please have some patience - If you are doing it for the first time, it will take a little while to download the browser drivers

- Run a specific example:

```
pytest path/to/test_script.py
```

> Make sure to replace `path/to/test_script.py` with the path and name of the example you want to run
````

```md
dotnet test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/README.md#L44)

##### /examples/dotnet/README.md

````md

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

## Navigate to the .NET directory
### Change into the .NET examples directory:

```bash
cd seleniumhq.github.io/examples/dotnet/SeleniumDocs
```

## Running the Tests
### Restore dependencies
Install necessary dependencies using the .NET CLI:

```bash
dotnet restore
```

### Run all tests
To run all available tests:

```bash
dotnet test
```

### Run a Specific Test Method
To run a specific test method using its fully qualified name:

```bash
dotnet test --filter "FullyQualifiedName=Namespace.ClassName.MethodName"
```
For example:
```bash
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

You can also filter by test name only (if it's unique):
```bash
dotnet test --filter "Name=EightComponents"
```
````

```md
bundle exec rspec
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/README.md#L26)

##### /examples/ruby/README.md

````md
# Running all tests from Selenium ruby example

Follow these steps to run all test example from selenium ruby

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `ruby` directory

```
cd seleniumhq.github.io/examples/ruby
```

3. Install dependencies using bundler

```
bundler install
```

4. Run all tests

```
bundle exec rspec
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a ruby script

Use this command to run a ruby script and follow the first script example

```
ruby example_script.rb
```
````

### Mocha

```shell
mocha runningTests.spec.js
```

### npx

```shell
npx mocha runningTests.spec.js
```

[Add Example](/documentation/about/contributing/#creating-examples)

### Examples

In [First script](https://www.selenium.dev/documentation/webdriver/getting_started/first_script/), we saw each of the components of a Selenium script. Here’s an example of that code using a test runner:

*
*
*
*
*
*

```java

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java)

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py)

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted
{
    [TestClass]
    public class UsingSeleniumTest
    {

        [TestMethod]
        public void EightComponents()
        {
            IWebDriver driver = new ChromeDriver();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

            var title = driver.Title;
            Assert.AreEqual("Web form", title);

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            var textBox = driver.FindElement(By.Name("my-text"));
            var submitButton = driver.FindElement(By.TagName("button"));
            
            textBox.SendKeys("Selenium");
            submitButton.Click();
            
            var message = driver.FindElement(By.Id("message"));
            var value = message.Text;
            Assert.AreEqual("Received!", value);
            
            driver.Quit();
        }
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs)

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb)

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js)

[Add Example](/documentation/about/contributing/#creating-examples)

## Next Steps

Take what you’ve learned and build out your Selenium code!

As you find more functionality that you need, read up on the rest of our [WebDriver documentation](https://www.selenium.dev/documentation/webdriver/).

Last modified February 25, 2026: [Update "Using Selenium" documentation with C# example from .NET README (#2584) (e1d46ea60e4)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e1d46ea60e47ff168113cd1e609b27a142527573)

## Development Partners

[](https://www.browserstack.com/automate?utm_campaign=open-source-sponsor\&utm_campaigncode=701OW000009sQwVYAU\&utm_medium=partnered\&utm_source=seleniumorg)

[](https://saucelabs.com/resources/topic-hub/selenium?utm_source=selenium\&utm_medium=website\&utm_campaign=selenium-sponsorship-fy25)

[](https://www.testmuai.com)

## Selenium Level Sponsors

[](https://brightdata.com/?utm_source=brand\&utm_campaign=brnd-mkt_partners_selenium)

[](https://applitools.com/)

[](https://www.thordata.com/?ls=waOicIkB\&lk=selenium)

## Support the Selenium Project

Learn more or view the full list of sponsors.

[Learn more**](/sponsors)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/support_features/listeners/
----

# 命令监听器

----
url: https://www.selenium.dev/ja/documentation/test_practices/encouraged/page_object_models/
----

# ページオブジェクトモデル

```java
/***
 * Tests login feature
 */
public class Login {

  public void testLogin() {
    // fill login data on sign-in page
    driver.findElement(By.name("user_name")).sendKeys("userName");
    driver.findElement(By.name("password")).sendKeys("my supersecret password");
    driver.findElement(By.name("sign-in")).click();

    // verify h1 tag is "Hello userName" after login
    driver.findElement(By.tagName("h1")).isDisplayed();
    assertThat(driver.findElement(By.tagName("h1")).getText(), is("Hello userName"));
  }
}
```

There are two problems with this approach.

* There is no separation between the test method and the AUT’s locators (IDs in this example); both are intertwined in a single method. If the AUT’s UI changes its identifiers, layout, or how a login is input and processed, the test itself must change.
* The ID-locators would be spread in multiple tests, in all tests that had to use this login page.

Applying the page object model, this example could be rewritten like this in the following example of a page object for a Sign-in page.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Sign-in page.
 */
public class SignInPage {
  protected WebDriver driver;

  // <input name="user_name" type="text" value="">
  private By usernameBy = By.name("user_name");
  // <input name="password" type="password" value="">
  private By passwordBy = By.name("password");
  // <input name="sign_in" type="submit" value="SignIn">
  private By signinBy = By.name("sign_in");

  public SignInPage(WebDriver driver){
    this.driver = driver;
     if (!driver.getTitle().equals("Sign In Page")) {
      throw new IllegalStateException("This is not Sign In Page," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Login as valid user
    *
    * @param userName
    * @param password
    * @return HomePage object
    */
  public HomePage loginValidUser(String userName, String password) {
    driver.findElement(usernameBy).sendKeys(userName);
    driver.findElement(passwordBy).sendKeys(password);
    driver.findElement(signinBy).click();
    return new HomePage(driver);
  }
}
```

and page object for a Home page could look like this.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Home Page
 */
public class HomePage {
  protected WebDriver driver;

  // <h1>Hello userName</h1>
  private By messageBy = By.tagName("h1");

  public HomePage(WebDriver driver){
    this.driver = driver;
    if (!driver.getTitle().equals("Home Page of logged in user")) {
      throw new IllegalStateException("This is not Home Page of logged in user," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Get message (h1 tag)
    *
    * @return String message text
    */
  public String getMessageText() {
    return driver.findElement(messageBy).getText();
  }

  public HomePage manageProfile() {
    // Page encapsulation to manage profile functionality
    return new HomePage(driver);
  }
  /* More methods offering the services represented by Home Page
  of Logged User. These methods in turn might return more Page Objects
  for example click on Compose mail button could return ComposeMail class object */
}
```

So now, the login test would use these two page objects as follows.

```java
/***
 * Tests login feature
 */
public class TestLogin {

  @Test
  public void testLogin() {
    SignInPage signInPage = new SignInPage(driver);
    HomePage homePage = signInPage.loginValidUser("userName", "password");
    assertThat(homePage.getMessageText(), is("Hello userName"));
  }

}
```

```html
<!-- Products Page -->
<div class="header_container">
    <span class="title">Products</span>
</div>

<div class="inventory_list">
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
</div>
```

Each product is a component of the Products page.

```html
<!-- Inventory Item -->
<div class="inventory_item">
    <div class="inventory_item_name">Backpack</div>
    <div class="pricebar">
        <div class="inventory_item_price">$29.99</div>
        <button id="add-to-cart-backpack">Add to cart</button>
    </div>
</div>
```

The Products page HAS-A list of products. This object relationship is called Composition. In simpler terms, something is *composed of* another thing.

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

// Page Object
public class ProductsPage extends BasePage {
    public ProductsPage(WebDriver driver) {
        super(driver);
        // No assertions, throws an exception if the element is not loaded
        new WebDriverWait(driver, Duration.ofSeconds(3))
            .until(d -> d.findElement(By.className​("header_container")));
    }

    // Returning a list of products is a service of the page
    public List<Product> getProducts() {
        return driver.findElements(By.className​("inventory_item"))
            .stream()
            .map(e -> new Product(e)) // Map WebElement to a product component
            .toList();
    }

    // Return a specific product using a boolean-valued function (predicate)
    // This is the behavioral Strategy Pattern from GoF
    public Product getProduct(Predicate<Product> condition) {
        return getProducts()
            .stream()
            .filter(condition) // Filter by product name or price
            .findFirst()
            .orElseThrow(() -> new RuntimeException("Product not found")); // Error thrown during actual test run
    }
}
```

The Product component object is used inside the Products page object.

```java
public abstract class BaseComponent {
    protected WebElement root;

    public BaseComponent(WebElement root) {
        this.root = root;
    }
}

// Page Component Object
public class Product extends BaseComponent {
    // The root element contains the entire component
    public Product(WebElement root) {
        super(root); // inventory_item
    }

    public String getName() {
        // Locating an element begins at the root of the component
        return root.findElement(By.className("inventory_item_name")).getText();
    }

    public BigDecimal getPrice() {
        return new BigDecimal(
                root.findElement(By.className("inventory_item_price"))
                    .getText()
                    .replace("$", "")
            ).setScale(2, RoundingMode.UNNECESSARY); // Sanitation and formatting
    }

    public void addToCart() {
        root.findElement(By.id("add-to-cart-backpack")).click();
    }
}
```

So now, the products test would use the page object and the page component object as follows.

```java
public class ProductsTest {
    @Test
    public void testProductInventory() {
        var productsPage = new ProductsPage(driver); // page object
        var products = productsPage.getProducts();
        assertEquals(6, products.size()); // expected, actual
    }
    
    @Test
    public void testProductPrices() {
        var productsPage = new ProductsPage(driver);

        // Pass a lambda expression (predicate) to filter the list of products
        // The predicate or "strategy" is the behavior passed as parameter
        var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); // page component object
        var bikeLight = productsPage.getProduct(p -> p.getName().equals("Bike Light"));

        assertEquals(new BigDecimal("29.99"), backpack.getPrice());
        assertEquals(new BigDecimal("9.99"), bikeLight.getPrice());
    }
}
```

```java
public class LoginPage {
    public HomePage loginAs(String username, String password) {
        // ... clever magic happens here
    }
    
    public LoginPage loginAsExpectingError(String username, String password) {
        //  ... failed login here, maybe because one or both of the username and password are wrong
    }
    
    public String getErrorMessage() {
        // So we can verify that the correct error is shown
    }
}
```

The code presented above shows an important point: the tests, not the Page Objects, should be responsible for making assertions about the state of a page. For example:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    inbox.assertMessageWithSubjectIsUnread("I like cheese");
    inbox.assertMessageWithSubjectIsNotUnread("I'm not fond of tofu");
}
```

could be re-written as:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    assertTrue(inbox.isMessageWithSubjectIsUnread("I like cheese"));
    assertFalse(inbox.isMessageWithSubjectIsUnread("I'm not fond of tofu"));
}
```

```java
public class LoginPage {
    private final WebDriver driver;

    public LoginPage(WebDriver driver) {
        this.driver = driver;

        // Check that we're on the right page.
        if (!"Login".equals(driver.getTitle())) {
            // Alternatively, we could navigate to the login page, perhaps logging out first
            throw new IllegalStateException("This is not the login page");
        }
    }

    // The login page contains several HTML elements that will be represented as WebElements.
    // The locators for these elements should only be defined once.
        By usernameLocator = By.id("username");
        By passwordLocator = By.id("passwd");
        By loginButtonLocator = By.id("login");

    // The login page allows the user to type their username into the username field
    public LoginPage typeUsername(String username) {
        // This is the only place that "knows" how to enter a username
        driver.findElement(usernameLocator).sendKeys(username);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to type their password into the password field
    public LoginPage typePassword(String password) {
        // This is the only place that "knows" how to enter a password
        driver.findElement(passwordLocator).sendKeys(password);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to submit the login form
    public HomePage submitLogin() {
        // This is the only place that submits the login form and expects the destination to be the home page.
        // A seperate method should be created for the instance of clicking login whilst expecting a login failure. 
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the login page ever
        // go somewhere else (for example, a legal disclaimer) then changing the method signature
        // for this method will mean that all tests that rely on this behaviour won't compile.
        return new HomePage(driver);	
    }

    // The login page allows the user to submit the login form knowing that an invalid username and / or password were entered
    public LoginPage submitLoginExpectingFailure() {
        // This is the only place that submits the login form and expects the destination to be the login page due to login failure.
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the user ever be navigated to the home page after submiting a login with credentials 
        // expected to fail login, the script will fail when it attempts to instantiate the LoginPage PageObject.
        return new LoginPage(driver);	
    }

    // Conceptually, the login page offers the user the service of being able to "log into"
    // the application using a user name and password. 
    public HomePage loginAs(String username, String password) {
        // The PageObject methods that enter username, password & submit login have already defined and should not be repeated here.
        typeUsername(username);
        typePassword(password);
        return submitLogin();
    }
}
```

最終更新 October 30, 2025: [docs: improve consistency and readability of the guide (#2168) (708f32f0c58)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/708f32f0c58c2386be472aec8b74801183f6743a)

----
url: https://www.selenium.dev/ja/_print/documentation/webdriver/bidi/w3c/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/webdriver/bidi/w3c/).

# BiDirectional API (W3C compliant)

* 1: [Browsing Context](#pg-71445a3bd85f6b2e34356b41ee60db3b)
* 2: [Browsing Context](#pg-ef9ce12ee5c5fe510651bedd57b53722)
* 3: [Network](#pg-721cf0509b15fcb32920495485b01973)
* 4: [Script](#pg-6afed3196b7c00fc93d474524705147d)
* 5: [BiDirectional API (W3C compliant)](#pg-a7b8e828be7ea2633cd38c7a4d91f093)

**Page being translated from English to Japanese. Do you speak Japanese? Help us to translate it by sending us pull requests!

The following list of APIs will be growing as the [WebDriver BiDirectional Protocol](https://w3c.github.io/webdriver-bidi/) 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](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=\&template=feature.md).

# 1 - Browsing Context

```java
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L44-L47)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L33-L35)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

    @Test
    void testNavigateToAUrl() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L58-L61)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L48-L50)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L37-L41)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L25-L28)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L50-L55)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L40-L43)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        Assertions.assertNotNull(browsingContext.getId());
        Assertions.assertNotNull(info.getNavigationId());
        Assertions.assertTrue(info.getUrl().contains("/bidi/logEntryAdded.html"));
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L64-L69)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L55-L58)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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"));
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L72-L80)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L67)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L83-L92)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L79-L82)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        Assertions.assertTrue(info.getChildren().get(0).getUrl().contains("formPage.html"));
    }

    @Test
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L95-L108)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    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()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L90-L96)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    }

    @Test
    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());
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L111-L123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L103-L109)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window2.close();

        Assertions.assertThrows(BiDiException.class, window2::getTree);
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L126-L133)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.20.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.20.0.0)

```js
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L426-L431)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext tab2 = new BrowsingContext(driver, WindowType.TAB);

        tab2.close();

        Assertions.assertThrows(BiDiException.class, tab2::getTree);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L136-L153)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L115-L118)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L157-L161)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L192-L194)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```js
    await window1.activate()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L204)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L169-L173)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.reload(undefined, 'complete')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L351)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    @Test
    void testDismissUserPromptWithText() {
        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";
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L220-L228)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.handleUserPrompt(true, userText)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L301)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        driver.get("https://www.selenium.dev/selenium/web/coordinates_tests/simple_page.html");

        WebElement element = driver.findElement(By.id("box"));
        Rectangle elementRectangle = element.getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L248-L252)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const response = await browsingContext.captureScreenshot()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L362)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    }

    @Test
    void textCaptureElementScreenshot() {
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L259-L268)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L165-L169)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L275-L280)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const response = await browsingContext.captureElementScreenshot(elementId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L184)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L304-L307)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.setViewport(250, 300)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L335)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L317-L322)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    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'],
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L145-L157)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        wait.until(visibilityOfElementLocated(By.id("imageButton"))).submit();
        wait.until(titleIs("We Arrive Here"));

        browsingContext.back();
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L330-L336)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.back()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L396)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L342-L352)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.forward()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L420)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L359-L365)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.traverseHistory(-1)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L378)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L34-L41)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L23-L28)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L54-L63)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L53-L62)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L81-88)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L70-L78)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L97-104)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L113-123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L86-L97)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L113-123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L150-163)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L170-L181)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0.0)

```js
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L105-L113)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

[Add Example](/documentation/about/contributing/#creating-examples)

# 2 - Browsing Context

```java
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ActionsTest.java#L41-L44)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ActionsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Input;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.interactions.Actions;

class ActionsTest extends BaseTest {
    private Input input;

    private String windowHandle;

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        windowHandle = driver.getWindowHandle();
        input = new Input(driver);
    }

    @Test
    void canPerformInputActions() {
        driver.get("https://www.selenium.dev/selenium/web/formSelectionPage.html");

        List<WebElement> options = driver.findElements(By.tagName("option"));

        Actions actions = new Actions(driver);
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());

        WebElement showButton = driver.findElement(By.name("showselected"));
        showButton.click();

        WebElement resultElement = driver.findElement(By.id("result"));
        Assertions.assertTrue(resultElement.getText().contains("roquefort parmigiano cheddar"));
        }

    @Test
    void canPerformReleaseAction() {
        driver.get("https://www.selenium.dev/selenium/web/bidi/release_action.html");

        WebElement inputTextBox = driver.findElement(By.id("keys"));

        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);

        List<Map<String, Object>> events =
                (List<Map<String, Object>>)
                        ((JavascriptExecutor) driver).executeScript("return allEvents.events");
        Assertions.assertEquals("KeyB", events.get(0).get("code"));
        Assertions.assertEquals("KeyA", events.get(1).get("code"));
        }
    }
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/input.spec.js#L27-L29)

##### /examples/javascript/test/bidirectional/input.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, Key, Builder} = require("selenium-webdriver")
const Input = require('selenium-webdriver/bidi/input')

describe('Input module', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can perform input action', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/formSelectionPage.html')

    let options = await driver.findElements(By.tagName('option'))

    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)

    let showButton = await driver.findElement(By.name('showselected'))
    showButton.click()

    let resultElement = await driver.findElement(By.id('result'))
    await resultElement.getText().then(function (text) {
      assert(text.includes('oquefort parmigiano cheddar'), `text is: ${text}`)
    })
  })

  it('can execute release in browsing context', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/bidi/release_action.html')

    let inputTextBox = await driver.findElement(By.id('keys'))

    await driver.executeScript('arguments[0].focus()', inputTextBox)

    const actions = driver.actions().keyDown('a').keyDown('b').getSequences()

    await input.perform(browsingContextId, actions)

    await driver.executeScript('resetEvents()')

    await input.release(browsingContextId)

    const events = await driver.executeScript('return allEvents.events')

    assert.strictEqual(events[0].code, 'KeyB')
    assert.strictEqual(events[1].code, 'KeyA')
  })
})
```

```java
        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ActionsTest.java#L59-L65)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ActionsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Input;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.interactions.Actions;

class ActionsTest extends BaseTest {
    private Input input;

    private String windowHandle;

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        windowHandle = driver.getWindowHandle();
        input = new Input(driver);
    }

    @Test
    void canPerformInputActions() {
        driver.get("https://www.selenium.dev/selenium/web/formSelectionPage.html");

        List<WebElement> options = driver.findElements(By.tagName("option"));

        Actions actions = new Actions(driver);
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());

        WebElement showButton = driver.findElement(By.name("showselected"));
        showButton.click();

        WebElement resultElement = driver.findElement(By.id("result"));
        Assertions.assertTrue(resultElement.getText().contains("roquefort parmigiano cheddar"));
        }

    @Test
    void canPerformReleaseAction() {
        driver.get("https://www.selenium.dev/selenium/web/bidi/release_action.html");

        WebElement inputTextBox = driver.findElement(By.id("keys"));

        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);

        List<Map<String, Object>> events =
                (List<Map<String, Object>>)
                        ((JavascriptExecutor) driver).executeScript("return allEvents.events");
        Assertions.assertEquals("KeyB", events.get(0).get("code"));
        Assertions.assertEquals("KeyA", events.get(1).get("code"));
        }
    }
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await input.release(browsingContextId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/input.spec.js#L55)

##### /examples/javascript/test/bidirectional/input.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, Key, Builder} = require("selenium-webdriver")
const Input = require('selenium-webdriver/bidi/input')

describe('Input module', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can perform input action', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/formSelectionPage.html')

    let options = await driver.findElements(By.tagName('option'))

    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)

    let showButton = await driver.findElement(By.name('showselected'))
    showButton.click()

    let resultElement = await driver.findElement(By.id('result'))
    await resultElement.getText().then(function (text) {
      assert(text.includes('oquefort parmigiano cheddar'), `text is: ${text}`)
    })
  })

  it('can execute release in browsing context', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/bidi/release_action.html')

    let inputTextBox = await driver.findElement(By.id('keys'))

    await driver.executeScript('arguments[0].focus()', inputTextBox)

    const actions = driver.actions().keyDown('a').keyDown('b').getSequences()

    await input.perform(browsingContextId, actions)

    await driver.executeScript('resetEvents()')

    await input.release(browsingContextId)

    const events = await driver.executeScript('return allEvents.events')

    assert.strictEqual(events[0].code, 'KeyB')
    assert.strictEqual(events[1].code, 'KeyA')
  })
})
```

[Add Example](/documentation/about/contributing/#creating-examples)

# 3 - Network

```java
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L36-L38)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    assert.notEqual(intercept, null)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L29)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L46-L50)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L34-L35)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                    responseDetails ->
                            network.continueWithAuth(
                                    responseDetails.getRequest().getRequestId(),
                                    new UsernameAndPassword("admin", "admin")));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L57-L64)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L42-L46)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                            // Does not handle the alert
                            network.continueWithAuthNoCredentials(responseDetails.getRequest().getRequestId()));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L74-L80)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L56-L60)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                            network.cancelAuth(responseDetails.getRequest().getRequestId()));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L90-L96)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L71-L75)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
            }
    }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L104-L108)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L30-L35)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L23-L29)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L45-L51)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L82-L88)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L62-L68)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L96-L102)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L101-L106)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

# 4 - Script

```java
        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));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L52-L75)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L32-L53)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L201-L210)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L202-L204)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L219-L229)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L222-L227)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L239-L242)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L237-L239)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L280-L283)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L279-L283)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L293-L299)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L292-L299)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            script.disownBrowsingContextScript(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L322-L322)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    await manager.disownBrowsingContextScript(id, boxId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L330-L330)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            script.disownRealmScript(realmId, List.of(boxId));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L375-L375)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    await manager.disownRealmScript(realmId, boxId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L372-L372)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L391-L392)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L383-L385)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L401-402)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L393-L395)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L411-412)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L403-L405)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L422-423)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L416-L416)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L463-463)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L424-L426)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
                script.removePreloadScript(id);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L486-486)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    await manager.removePreloadScript(scriptId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L471-L471)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L37-L51)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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,
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L26-L43)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L58-L68)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L52-L65)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L75-L85)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.19](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.19.0)

```js
    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()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L73-L86)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

[Add Example](/documentation/about/contributing/#creating-examples)

# 5 - BiDirectional API (W3C compliant)

```java
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L33-L39)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/logInspector.spec.js#L23-37)

##### /examples/javascript/test/bidirectional/logInspector.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const LogInspector = require('selenium-webdriver/bidi/logInspector');
const {Builder} = require("selenium-webdriver");


describe('Log Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test listen to console log', async function () {
    let logEntry = null
    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)

    await inspector.close()
  })

  it('test listen to javascript error log', async function () {
    let logEntry = null
    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')

    await inspector.close()
  })

  it('test retrieve stack trace for a log', async function () {
    let logEntry = null
    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()

    const stackTrace = logEntry.stackTrace
    assert.notEqual(stackTrace, null)
    assert.equal(stackTrace.callFrames.length, 3)

    await inspector.close()
  })

  it('test listen to logs with multiple consumers', async function () {
    let logEntry1 = null
    let logEntry2 = null
    const inspector = await LogInspector(driver)
    await inspector.onJavascriptException(function (log) {
      logEntry1 = log
    })
    await inspector.onJavascriptException(function (log) {
      logEntry2 = log
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    await driver.findElement({id: 'jsException'}).click()

    assert.equal(logEntry1.text, 'Error: Not working')
    assert.equal(logEntry1.type, 'javascript')
    assert.equal(logEntry1.level, 'error')

    assert.equal(logEntry2.text, 'Error: Not working')
    assert.equal(logEntry2.type, 'javascript')
    assert.equal(logEntry2.level, 'error')

    await inspector.close()
  })
})
```

```java
            logInspector.onJavaScriptException(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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L73-L78)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/logInspector.spec.js#L44-54)

##### /examples/javascript/test/bidirectional/logInspector.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const LogInspector = require('selenium-webdriver/bidi/logInspector');
const {Builder} = require("selenium-webdriver");


describe('Log Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test listen to console log', async function () {
    let logEntry = null
    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)

    await inspector.close()
  })

  it('test listen to javascript error log', async function () {
    let logEntry = null
    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')

    await inspector.close()
  })

  it('test retrieve stack trace for a log', async function () {
    let logEntry = null
    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()

    const stackTrace = logEntry.stackTrace
    assert.notEqual(stackTrace, null)
    assert.equal(stackTrace.callFrames.length, 3)

    await inspector.close()
  })

  it('test listen to logs with multiple consumers', async function () {
    let logEntry1 = null
    let logEntry2 = null
    const inspector = await LogInspector(driver)
    await inspector.onJavascriptException(function (log) {
      logEntry1 = log
    })
    await inspector.onJavascriptException(function (log) {
      logEntry2 = log
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    await driver.findElement({id: 'jsException'}).click()

    assert.equal(logEntry1.text, 'Error: Not working')
    assert.equal(logEntry1.type, 'javascript')
    assert.equal(logEntry1.level, 'error')

    assert.equal(logEntry2.text, 'Error: Not working')
    assert.equal(logEntry2.type, 'javascript')
    assert.equal(logEntry2.level, 'error')

    await inspector.close()
  })
})
```

```java
            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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L55-L60)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

----
url: https://www.selenium.dev/ja/documentation/overview/
----

# 概要

Seleniumはあなたに適していますか？さまざまなプロジェクトのコンポーネントの概要を参照してください。

***

##### [コンポーネントを理解する](/ja/documentation/overview/components/)

##### [Selenium 詳細](/ja/documentation/overview/details/)

Seleniumは、Web ブラウザーの自動化を可能にし、 サポートするさまざまなツールとライブラリーの包括的なプロジェクトです。

----
url: https://www.selenium.dev/pt-br/documentation/about/
----

# Sobre esta documentação

Essa documentação, como o próprio código, são mantidos 100% por voluntários dentro da comunidade Selenium. Muitos têm usado desde o seu início, mas muitos mais o usam há pouco tempo, e dedicaram seu tempo para ajudar a melhorar a experiência de integração para novos usuários.

Se houver algum problema com a documentação, queremos saber! A melhor maneira de comunicar um problema é visitar [https://github.com/seleniumhq/seleniumhq.github.io/issues](//github.com/seleniumhq/seleniumhq.github.io/issues) e pesquise se o problema já foi ou não arquivado. Se não, fique à vontade para abrir um!

Muitos membros da comunidade frequentam o canal Libera *#selenium* em [Libera.chat](https://libera.chat/). Sinta-se à vontade para entrar e fazer perguntas e se você receber ajuda que você acha que poderia ser útil nessa documentação, certifique-se de adicionar sua contribuição! Podemos atualizar essa documentação, mas é muito mais fácil para todos quando recebemos contribuições de fora dos committers normais.

***

##### [Direitos autorais e atribuições](/pt-br/documentation/about/copyright/)

Direitos autorais, contribuições e todas as atribuições para os diferentes projetos sob a iniciativa do Selenium.

##### [Contribuindo com o Site e Documentação do Selenium](/pt-br/documentation/about/contributing/)

Informações em como melhorar a documentação e exemplos de código para Selenium.

##### [Guia de estilo para a documentação do Selenium](/pt-br/documentation/about/style/)

Convenções para contribuições à documentação do Selenium e exemplos de código.

----
url: https://www.selenium.dev/ja/documentation/ie_driver_server/internals/
----

最終更新 January 10, 2022: [More wiki (#907) \[deploy site\] (adcf706a1ad)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/adcf706a1ad907d028dc57d10201a265972432af)

----
url: https://www.selenium.dev/ja/documentation/webdriver/bidi/cdp/logging/
----

```java
    ((HasLogEvents) driver).onLogEvent(consoleEvent(e -> messages.add(e.getMessages().get(0))));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/LoggingTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/LoggingTest.java

```java
package dev.selenium.bidi.cdp;

import static org.openqa.selenium.devtools.events.CdpEventTypes.consoleEvent;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.CopyOnWriteArrayList;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.HasLogEvents;
import org.openqa.selenium.support.ui.WebDriverWait;

public class LoggingTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void consoleLogs() {
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    CopyOnWriteArrayList<String> messages = new CopyOnWriteArrayList<>();

    ((HasLogEvents) driver).onLogEvent(consoleEvent(e -> messages.add(e.getMessages().get(0))));

    driver.findElement(By.id("consoleLog")).click();
    driver.findElement(By.id("consoleError")).click();

    wait.until(_d -> messages.size() > 1);
    Assertions.assertTrue(messages.contains("Hello, world!"));
    Assertions.assertTrue(messages.contains("I am console error"));
  }
}
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_logs.py#L11-12)

##### /examples/python/tests/bidi/cdp/test\_logs.py

```py
import pytest
from selenium.webdriver.common.bidi.console import Console
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log


@pytest.mark.trio
async def test_console_log(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
            driver.find_element(by=By.ID, value='consoleLog').click()

        assert messages["message"] == "Hello, world!"


@pytest.mark.trio
async def test_js_error(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
            driver.find_element(by=By.ID, value='jsException').click()

        assert "Error: Not working" in messages.exception_details.exception.description
```

```cs
            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs#L19-L25)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class LoggingTest : BaseChromeTest
    {
        [TestMethod]
        public async Task ConsoleLogs()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("consoleLog")).Click();
            driver.FindElement(By.Id("consoleError")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => messages.Count > 1);
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Hello, world!"));
            Assert.IsTrue(messages.Contains("I am console error"));
        }
        
        [TestMethod]
        public async Task JsErrors()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("jsException")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !messages.IsNullOrEmpty());
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Uncaught"));
        }
    }
}
```

```rb
    driver.on_log_event(:console) { |log| logs << log.args.first }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/logging_spec.rb#L12)

##### /examples/ruby/spec/bidi/cdp/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'listens for console logs' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    logs = []
    driver.on_log_event(:console) { |log| logs << log.args.first }

    driver.find_element(id: 'consoleLog').click
    driver.find_element(id: 'consoleError').click

    Selenium::WebDriver::Wait.new.until { logs.size > 1 }
    expect(logs).to include 'Hello, world!'
    expect(logs).to include 'I am console error'
  end

  it 'listens for js exception' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    exceptions = []
    driver.on_log_event(:exception) { |exception| exceptions << exception }

    driver.find_element(id: 'jsException').click

    Selenium::WebDriver::Wait.new.until { exceptions.any? }
    expect(exceptions.first&.description).to include 'Error: Not working'
  end
end
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_logs.py#L22-L23)

##### /examples/python/tests/bidi/cdp/test\_logs.py

```py
import pytest
from selenium.webdriver.common.bidi.console import Console
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log


@pytest.mark.trio
async def test_console_log(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
            driver.find_element(by=By.ID, value='consoleLog').click()

        assert messages["message"] == "Hello, world!"


@pytest.mark.trio
async def test_js_error(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
            driver.find_element(by=By.ID, value='jsException').click()

        assert "Error: Not working" in messages.exception_details.exception.description
```

```cs
            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs#L41-L47)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class LoggingTest : BaseChromeTest
    {
        [TestMethod]
        public async Task ConsoleLogs()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("consoleLog")).Click();
            driver.FindElement(By.Id("consoleError")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => messages.Count > 1);
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Hello, world!"));
            Assert.IsTrue(messages.Contains("I am console error"));
        }
        
        [TestMethod]
        public async Task JsErrors()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("jsException")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !messages.IsNullOrEmpty());
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Uncaught"));
        }
    }
}
```

```rb
    driver.on_log_event(:exception) { |exception| exceptions << exception }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/logging_spec.rb#L26)

##### /examples/ruby/spec/bidi/cdp/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'listens for console logs' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    logs = []
    driver.on_log_event(:console) { |log| logs << log.args.first }

    driver.find_element(id: 'consoleLog').click
    driver.find_element(id: 'consoleError').click

    Selenium::WebDriver::Wait.new.until { logs.size > 1 }
    expect(logs).to include 'Hello, world!'
    expect(logs).to include 'I am console error'
  end

  it 'listens for js exception' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    exceptions = []
    driver.on_log_event(:exception) { |exception| exceptions << exception }

    driver.find_element(id: 'jsException').click

    Selenium::WebDriver::Wait.new.until { exceptions.any? }
    expect(exceptions.first&.description).to include 'Error: Not working'
  end
end
```

----
url: https://www.selenium.dev/ja/documentation/legacy/selenium_3/grid_3/
----

# Grid 3

Selenium Grid 3 supported WebDriver without Selenium RC code. Grid 3 was completely rewritten for the new Grid 4.

[Grid 4](https://www.selenium.dev/ja/documentation/grid/)

*Selenium Grid* は、SeleniumテストがコマンドをリモートWebブラウザーインスタンスにルーティングできるようにする賢いプロキシサーバーです。 その目的は、複数のマシンで並行してテストを実行する簡単な方法を提供することです。

Selenium Gridでは、1つのサーバーが、JSON形式のテストコマンドを1つ以上の登録済みのグリッドノードにルーティングするハブとして機能します。 テストはハブに接続して、リモートブラウザーインスタンスへのアクセスを取得します。 ハブには、アクセスを提供する登録済みサーバーのリストがあり、これらのインスタンスを制御できます。

Selenium Gridを使用すると、複数のマシンで並行してテストを実行し、さまざまなブラウザーバージョンとブラウザー構成を（個々のテストではなく）一元的に管理できます。

Selenium Gridは特効薬ではありません。 一般的な委譲および配布の問題のサブセットを解決しますが、たとえばインフラストラクチャを管理せず、特定のニーズに適さない場合があります。

----
url: https://www.selenium.dev/ja/documentation/grid/advanced_features/external_datastore/
----

# External datastore

```sql
CREATE TABLE IF NOT EXISTS sessions_map(
    session_ids varchar(256),
    session_caps text,
    session_uri varchar(256),
    session_stereotype text,
    session_start varchar(256)
 );
```

* In the same directory as the `init.sql`, create a file named `docker-compose.yml` with its contents as below:

```yaml
version: '3.8'
services:
  db:
    image: postgres:9.6-bullseye
    restart: always
    environment:
      - POSTGRES_USER=seluser
      - POSTGRES_PASSWORD=seluser
      - POSTGRES_DB=selenium_sessions
    ports:
      - "5432:5432"
    volumes:
    - ./init.sql:/docker-entrypoint-initdb.d/init.sql
```

We can now start our database container by running:

```bash
docker-compose up -d
```

*Our database name is `selenium_sessions` with its username and password set to `seluser`*

If you are working with an already running PostGreSQL DB instance, then you just need to create a database named `selenium_sessions` and the table `sessions_map` using the above mentioned SQL statement.

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
implementation = "org.openqa.selenium.grid.sessionmap.jdbc.JdbcBackedSessionMap"
jdbc-url = "jdbc:postgresql://localhost:5432/selenium_sessions"
jdbc-user = "seluser"
jdbc-password = "seluser"
```

*Note:* If you plan to use an existing PostGreSQL DB instance, then replace `localhost:5432` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed Grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Sessions Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

```yaml
version: '3.8'
services:
  redis:
    image: redis:bullseye
    restart: always
    ports:
      - "6379:6379"
```

We can now start our Redis container by running:

```bash
docker-compose up -d
```

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
scheme = "redis"
implementation = "org.openqa.selenium.grid.sessionmap.redis.RedisBackedSessionMap"
hostname = "localhost"
port = 6379
```

*Note:* If you plan to use an existing Redis Cache instance, then replace `localhost` and `6379` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Session Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

* At this point the current directory should contain the following files:

  * `docker-compose.yml`
  * `sessions.toml`
  * `distributed.sh`

* You can now spawn the Grid by running `distributed.sh` shell script and quickly run a test. You will notice that the Grid now stores session information into the Redis instance. You can perhaps make use of a Redis GUI such as [TablePlus](https://tableplus.com/) to see them (Make sure that you have setup a debug point in your test, because the values will get deleted as soon as the test runs to completion).

In the line which spawns a `SessionMap` on a machine:

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

* The variable names from the above script have been replaced with their actual values for clarity.
* Remember to substitute `localhost` with the actual hostname of the machine where your `Event-Bus` is running.
* The arguments being passed to `coursier` are basically the GAV (Group Artifact Version) Maven co-ordinates of:
  * [selenium-session-map-redis](https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-session-map-redis) which is needed to help us store sessions information in Redis Cache.
* `sessions.toml` is the configuration file that we created earlier.

----
url: https://www.selenium.dev/documentation/webdriver/actions_api/pen/
----

```java
        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/PenTest.java#L26-L33)

##### /examples/java/src/test/java/dev/selenium/actions\_api/PenTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PenTest extends BaseChromeTest {
    @Test
    public void usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();

        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    @Test
    public void setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();
        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("-72", moveBy.get("tiltX"));
        Assertions.assertEquals("9", moveBy.get("tiltY"));
        Assertions.assertEquals("86", moveBy.get("twist"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    private Map<String, String> getPropertyInfo(WebElement element) {
        String text = element.getText();
        text = text.substring(text.indexOf(' ') + 1);

        return Arrays.stream(text.split(", "))
                .map(s -> s.split(": "))
                .collect(Collectors.toMap(
                        a -> a[0],
                        a -> a[1]
                ));
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_pen.py#L12-L20)

##### /examples/python/tests/actions\_api/test\_pen.py

```py
import math

from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.interaction import POINTER_PEN
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.by import By


def test_use_pen(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def test_set_pointer_event_properties(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert move_by["tiltX"] == "-72"
    assert move_by["tiltY"] == "9"
    assert move_by["twist"] == "86"
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def properties(element):
    kv = element.text.split(' ', 1)[1].split(', ')
    return {x[0]:x[1] for x in list(map(lambda item: item.split(': '), kv))}
```

```cs
            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs#L19-L28)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class PenTest : BaseChromeTest
    {
        [TestMethod]
        public void UsePen()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        [TestMethod]
        public void SetPointerEventProperties()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual((-72).ToString(), moveBy["tiltX"]);
            Assert.AreEqual((9).ToString(), moveBy["tiltY"]);
            Assert.AreEqual((86).ToString(), moveBy["twist"]);
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        private Dictionary<string, string> getProperties(IWebElement element)
        {
            var str = element.Text;
            str = str[(str.Split()[0].Length + 1)..];
            IEnumerable<string[]> keyValue = str.Split(", ").Select(part => part.Split(":"));
            return keyValue.ToDictionary(split => split[0].Trim(), split => split[1].Trim());
        }

        private bool VerifyEquivalent(decimal expected, string actual)
        {
            var absolute = Math.Abs(expected - decimal.Parse(actual));
            if (absolute <= 1)
            {
                return true;
            }

            throw new Exception("Expected: " + expected + "; but received: " + actual);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/pen_spec.rb#L11-L17)

##### /examples/ruby/spec/actions\_api/pen\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Pen' do
  let(:driver) { start_session }

  it 'uses a pen' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  it 'sets pointer event attributes' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s,
                               'tiltX' => -72.to_s,
                               'tiltY' => 9.to_s,
                               'twist' => 86.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  def properties(element)
    element.text.sub(/.*?\s/, '').split(',').to_h { |item| item.lstrip.split(/\s*:\s*/) }
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/PenTest.kt#L23-L30)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/PenTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import kotlin.collections.Map
import java.time.Duration

class PenTest : BaseTest() {
  
    @Test
    fun usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
    }

    @Test
    fun setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY")) 
	    
        Assertions.assertEquals("-72", moveBy.get("tiltX"))
        Assertions.assertEquals("9", moveBy.get("tiltY"))
        Assertions.assertEquals("86", moveBy.get("twist"))
    }
    
    fun getPropertyInfo(element: WebElement): Map<String, String> {
        var text = element.getText()  
        text = text.substring(text.indexOf(" ")+1)
        return text.split(", ")
        .map { it.split(": ") }
        .map { it.first() to it.last() }
        .toMap() 
    }
}
```

```java
        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/PenTest.java#L67-L81)

##### /examples/java/src/test/java/dev/selenium/actions\_api/PenTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PenTest extends BaseChromeTest {
    @Test
    public void usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();

        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    @Test
    public void setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();
        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("-72", moveBy.get("tiltX"));
        Assertions.assertEquals("9", moveBy.get("tiltY"));
        Assertions.assertEquals("86", moveBy.get("twist"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    private Map<String, String> getPropertyInfo(WebElement element) {
        String text = element.getText();
        text = text.substring(text.indexOf(' ') + 1);

        return Arrays.stream(text.split(", "))
                .map(s -> s.split(": "))
                .collect(Collectors.toMap(
                        a -> a[0],
                        a -> a[1]
                ));
    }
}
```

```py
    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_pen.py#L53-L61)

##### /examples/python/tests/actions\_api/test\_pen.py

```py
import math

from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.interaction import POINTER_PEN
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.by import By


def test_use_pen(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def test_set_pointer_event_properties(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert move_by["tiltX"] == "-72"
    assert move_by["tiltY"] == "9"
    assert move_by["twist"] == "86"
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def properties(element):
    kv = element.text.split(' ', 1)[1].split(', ')
    return {x[0]:x[1] for x in list(map(lambda item: item.split(': '), kv))}
```

```cs
            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs#L64-L77)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class PenTest : BaseChromeTest
    {
        [TestMethod]
        public void UsePen()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        [TestMethod]
        public void SetPointerEventProperties()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual((-72).ToString(), moveBy["tiltX"]);
            Assert.AreEqual((9).ToString(), moveBy["tiltY"]);
            Assert.AreEqual((86).ToString(), moveBy["twist"]);
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        private Dictionary<string, string> getProperties(IWebElement element)
        {
            var str = element.Text;
            str = str[(str.Split()[0].Length + 1)..];
            IEnumerable<string[]> keyValue = str.Split(", ").Select(part => part.Split(":"));
            return keyValue.ToDictionary(split => split[0].Trim(), split => split[1].Trim());
        }

        private bool VerifyEquivalent(decimal expected, string actual)
        {
            var absolute = Math.Abs(expected - decimal.Parse(actual));
            if (absolute <= 1)
            {
                return true;
            }

            throw new Exception("Expected: " + expected + "; but received: " + actual);
        }
    }
}
```

```rb
    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/pen_spec.rb#L50-L56)

##### /examples/ruby/spec/actions\_api/pen\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Pen' do
  let(:driver) { start_session }

  it 'uses a pen' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  it 'sets pointer event attributes' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s,
                               'tiltX' => -72.to_s,
                               'tiltY' => 9.to_s,
                               'twist' => 86.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  def properties(element)
    element.text.sub(/.*?\s/, '').split(',').to_h { |item| item.lstrip.split(/\s*:\s*/) }
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/PenTest.kt#L64-L78)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/PenTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import kotlin.collections.Map
import java.time.Duration

class PenTest : BaseTest() {
  
    @Test
    fun usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
    }

    @Test
    fun setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY")) 
	    
        Assertions.assertEquals("-72", moveBy.get("tiltX"))
        Assertions.assertEquals("9", moveBy.get("tiltY"))
        Assertions.assertEquals("86", moveBy.get("twist"))
    }
    
    fun getPropertyInfo(element: WebElement): Map<String, String> {
        var text = element.getText()  
        text = text.substring(text.indexOf(" ")+1)
        return text.split(", ")
        .map { it.split(": ") }
        .map { it.first() to it.last() }
        .toMap() 
    }
}
```

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/bidi/script/
----

# WebDriver BiDi Script Features

These features are related to scripts, and are made available via a “script” namespace.

The implementation of these features is being tracked here: [#13992](https://github.com/SeleniumHQ/selenium/issues/13992)

Remember that to use WebDriver BiDi, you must enable it in Options. For more details, see [Enabling BiDi](https://www.selenium.dev/zh-cn/documentation/webdriver/bidi/)

## Script Pinning

## Execute Script

## DOM Mutation Handlers

最后修改 October 18, 2024: [add missing pages for BiDi script (71f0aa453d2)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/71f0aa453d297d3ed90300d73ba2a800270d478a)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/bidi/cdp/logging/
----

# Chrome DevTools Logging Features

```java
    ((HasLogEvents) driver).onLogEvent(consoleEvent(e -> messages.add(e.getMessages().get(0))));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/LoggingTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/LoggingTest.java

```java
package dev.selenium.bidi.cdp;

import static org.openqa.selenium.devtools.events.CdpEventTypes.consoleEvent;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.CopyOnWriteArrayList;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.HasLogEvents;
import org.openqa.selenium.support.ui.WebDriverWait;

public class LoggingTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void consoleLogs() {
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    CopyOnWriteArrayList<String> messages = new CopyOnWriteArrayList<>();

    ((HasLogEvents) driver).onLogEvent(consoleEvent(e -> messages.add(e.getMessages().get(0))));

    driver.findElement(By.id("consoleLog")).click();
    driver.findElement(By.id("consoleError")).click();

    wait.until(_d -> messages.size() > 1);
    Assertions.assertTrue(messages.contains("Hello, world!"));
    Assertions.assertTrue(messages.contains("I am console error"));
  }
}
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_logs.py#L11-12)

##### /examples/python/tests/bidi/cdp/test\_logs.py

```py
import pytest
from selenium.webdriver.common.bidi.console import Console
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log


@pytest.mark.trio
async def test_console_log(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
            driver.find_element(by=By.ID, value='consoleLog').click()

        assert messages["message"] == "Hello, world!"


@pytest.mark.trio
async def test_js_error(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
            driver.find_element(by=By.ID, value='jsException').click()

        assert "Error: Not working" in messages.exception_details.exception.description
```

```cs
            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs#L19-L25)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class LoggingTest : BaseChromeTest
    {
        [TestMethod]
        public async Task ConsoleLogs()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("consoleLog")).Click();
            driver.FindElement(By.Id("consoleError")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => messages.Count > 1);
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Hello, world!"));
            Assert.IsTrue(messages.Contains("I am console error"));
        }
        
        [TestMethod]
        public async Task JsErrors()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("jsException")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !messages.IsNullOrEmpty());
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Uncaught"));
        }
    }
}
```

```rb
    driver.on_log_event(:console) { |log| logs << log.args.first }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/logging_spec.rb#L12)

##### /examples/ruby/spec/bidi/cdp/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'listens for console logs' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    logs = []
    driver.on_log_event(:console) { |log| logs << log.args.first }

    driver.find_element(id: 'consoleLog').click
    driver.find_element(id: 'consoleError').click

    Selenium::WebDriver::Wait.new.until { logs.size > 1 }
    expect(logs).to include 'Hello, world!'
    expect(logs).to include 'I am console error'
  end

  it 'listens for js exception' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    exceptions = []
    driver.on_log_event(:exception) { |exception| exceptions << exception }

    driver.find_element(id: 'jsException').click

    Selenium::WebDriver::Wait.new.until { exceptions.any? }
    expect(exceptions.first&.description).to include 'Error: Not working'
  end
end
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_logs.py#L22-L23)

##### /examples/python/tests/bidi/cdp/test\_logs.py

```py
import pytest
from selenium.webdriver.common.bidi.console import Console
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log


@pytest.mark.trio
async def test_console_log(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
            driver.find_element(by=By.ID, value='consoleLog').click()

        assert messages["message"] == "Hello, world!"


@pytest.mark.trio
async def test_js_error(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
            driver.find_element(by=By.ID, value='jsException').click()

        assert "Error: Not working" in messages.exception_details.exception.description
```

```cs
            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs#L41-L47)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class LoggingTest : BaseChromeTest
    {
        [TestMethod]
        public async Task ConsoleLogs()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("consoleLog")).Click();
            driver.FindElement(By.Id("consoleError")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => messages.Count > 1);
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Hello, world!"));
            Assert.IsTrue(messages.Contains("I am console error"));
        }
        
        [TestMethod]
        public async Task JsErrors()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("jsException")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !messages.IsNullOrEmpty());
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Uncaught"));
        }
    }
}
```

```rb
    driver.on_log_event(:exception) { |exception| exceptions << exception }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/logging_spec.rb#L26)

##### /examples/ruby/spec/bidi/cdp/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'listens for console logs' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    logs = []
    driver.on_log_event(:console) { |log| logs << log.args.first }

    driver.find_element(id: 'consoleLog').click
    driver.find_element(id: 'consoleError').click

    Selenium::WebDriver::Wait.new.until { logs.size > 1 }
    expect(logs).to include 'Hello, world!'
    expect(logs).to include 'I am console error'
  end

  it 'listens for js exception' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    exceptions = []
    driver.on_log_event(:exception) { |exception| exceptions << exception }

    driver.find_element(id: 'jsException').click

    Selenium::WebDriver::Wait.new.until { exceptions.any? }
    expect(exceptions.first&.description).to include 'Error: Not working'
  end
end
```

----
url: https://www.selenium.dev/ja/documentation/test_practices/encouraged/fresh_browser_per_test/
----

# テストごとに新しいブラウザを起動する

クリーンな既知の状態から各テストを開始します。 理想的には、テストごとに新しい仮想マシンを起動します。 新しい仮想マシンの起動が実用的でない場合は、少なくともテストごとに新しいWebDriverを起動してください。 Firefoxの場合、既知のプロファイルでWebDriverを起動します。 Most browser drivers like GeckoDriver and ChromeDriver will start with a clean known state with a new user profile, by default.

```java
WebDriver driver = new FirefoxDriver();
```

最終更新 July 28, 2022: [Fixes #927 (#1090) (e9323eb4d1e)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e9323eb4d1ea06146209479a8e1126da5487f651)

----
url: https://www.selenium.dev/documentation/webdriver/bidi/cdp/logging/
----

# Chrome DevTools Logging Features

```java
    ((HasLogEvents) driver).onLogEvent(consoleEvent(e -> messages.add(e.getMessages().get(0))));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/LoggingTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/LoggingTest.java

```java
package dev.selenium.bidi.cdp;

import static org.openqa.selenium.devtools.events.CdpEventTypes.consoleEvent;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.CopyOnWriteArrayList;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.HasLogEvents;
import org.openqa.selenium.support.ui.WebDriverWait;

public class LoggingTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void consoleLogs() {
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    CopyOnWriteArrayList<String> messages = new CopyOnWriteArrayList<>();

    ((HasLogEvents) driver).onLogEvent(consoleEvent(e -> messages.add(e.getMessages().get(0))));

    driver.findElement(By.id("consoleLog")).click();
    driver.findElement(By.id("consoleError")).click();

    wait.until(_d -> messages.size() > 1);
    Assertions.assertTrue(messages.contains("Hello, world!"));
    Assertions.assertTrue(messages.contains("I am console error"));
  }
}
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_logs.py#L11-12)

##### /examples/python/tests/bidi/cdp/test\_logs.py

```py
import pytest
from selenium.webdriver.common.bidi.console import Console
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log


@pytest.mark.trio
async def test_console_log(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
            driver.find_element(by=By.ID, value='consoleLog').click()

        assert messages["message"] == "Hello, world!"


@pytest.mark.trio
async def test_js_error(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
            driver.find_element(by=By.ID, value='jsException').click()

        assert "Error: Not working" in messages.exception_details.exception.description
```

```cs
            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs#L19-L25)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class LoggingTest : BaseChromeTest
    {
        [TestMethod]
        public async Task ConsoleLogs()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("consoleLog")).Click();
            driver.FindElement(By.Id("consoleError")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => messages.Count > 1);
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Hello, world!"));
            Assert.IsTrue(messages.Contains("I am console error"));
        }
        
        [TestMethod]
        public async Task JsErrors()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("jsException")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !messages.IsNullOrEmpty());
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Uncaught"));
        }
    }
}
```

```rb
    driver.on_log_event(:console) { |log| logs << log.args.first }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/logging_spec.rb#L12)

##### /examples/ruby/spec/bidi/cdp/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'listens for console logs' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    logs = []
    driver.on_log_event(:console) { |log| logs << log.args.first }

    driver.find_element(id: 'consoleLog').click
    driver.find_element(id: 'consoleError').click

    Selenium::WebDriver::Wait.new.until { logs.size > 1 }
    expect(logs).to include 'Hello, world!'
    expect(logs).to include 'I am console error'
  end

  it 'listens for js exception' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    exceptions = []
    driver.on_log_event(:exception) { |exception| exceptions << exception }

    driver.find_element(id: 'jsException').click

    Selenium::WebDriver::Wait.new.until { exceptions.any? }
    expect(exceptions.first&.description).to include 'Error: Not working'
  end
end
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_logs.py#L22-L23)

##### /examples/python/tests/bidi/cdp/test\_logs.py

```py
import pytest
from selenium.webdriver.common.bidi.console import Console
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log


@pytest.mark.trio
async def test_console_log(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
            driver.find_element(by=By.ID, value='consoleLog').click()

        assert messages["message"] == "Hello, world!"


@pytest.mark.trio
async def test_js_error(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
            driver.find_element(by=By.ID, value='jsException').click()

        assert "Error: Not working" in messages.exception_details.exception.description
```

```cs
            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs#L41-L47)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class LoggingTest : BaseChromeTest
    {
        [TestMethod]
        public async Task ConsoleLogs()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("consoleLog")).Click();
            driver.FindElement(By.Id("consoleError")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => messages.Count > 1);
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Hello, world!"));
            Assert.IsTrue(messages.Contains("I am console error"));
        }
        
        [TestMethod]
        public async Task JsErrors()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("jsException")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !messages.IsNullOrEmpty());
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Uncaught"));
        }
    }
}
```

```rb
    driver.on_log_event(:exception) { |exception| exceptions << exception }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/logging_spec.rb#L26)

##### /examples/ruby/spec/bidi/cdp/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'listens for console logs' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    logs = []
    driver.on_log_event(:console) { |log| logs << log.args.first }

    driver.find_element(id: 'consoleLog').click
    driver.find_element(id: 'consoleError').click

    Selenium::WebDriver::Wait.new.until { logs.size > 1 }
    expect(logs).to include 'Hello, world!'
    expect(logs).to include 'I am console error'
  end

  it 'listens for js exception' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    exceptions = []
    driver.on_log_event(:exception) { |exception| exceptions << exception }

    driver.find_element(id: 'jsException').click

    Selenium::WebDriver::Wait.new.until { exceptions.any? }
    expect(exceptions.first&.description).to include 'Error: Not working'
  end
end
```

----
url: https://www.selenium.dev/documentation/webdriver/bidi/w3c/browsing_context/
----

# Browsing Context

```java
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L44-L47)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L33-L35)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

    @Test
    void testNavigateToAUrl() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L58-L61)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L48-L50)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L37-L41)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L25-L28)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L50-L55)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L40-L43)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        Assertions.assertNotNull(browsingContext.getId());
        Assertions.assertNotNull(info.getNavigationId());
        Assertions.assertTrue(info.getUrl().contains("/bidi/logEntryAdded.html"));
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L64-L69)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L55-L58)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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"));
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L72-L80)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L67)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L83-L92)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L79-L82)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        Assertions.assertTrue(info.getChildren().get(0).getUrl().contains("formPage.html"));
    }

    @Test
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L95-L108)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    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()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L90-L96)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    }

    @Test
    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());
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L111-L123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L103-L109)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window2.close();

        Assertions.assertThrows(BiDiException.class, window2::getTree);
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L126-L133)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.20.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.20.0.0)

```js
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L426-L431)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext tab2 = new BrowsingContext(driver, WindowType.TAB);

        tab2.close();

        Assertions.assertThrows(BiDiException.class, tab2::getTree);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L136-L153)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L115-L118)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L157-L161)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L192-L194)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```js
    await window1.activate()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L204)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L169-L173)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.reload(undefined, 'complete')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L351)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    @Test
    void testDismissUserPromptWithText() {
        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";
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L220-L228)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.handleUserPrompt(true, userText)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L301)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        driver.get("https://www.selenium.dev/selenium/web/coordinates_tests/simple_page.html");

        WebElement element = driver.findElement(By.id("box"));
        Rectangle elementRectangle = element.getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L248-L252)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const response = await browsingContext.captureScreenshot()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L362)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    }

    @Test
    void textCaptureElementScreenshot() {
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L259-L268)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L165-L169)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L275-L280)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const response = await browsingContext.captureElementScreenshot(elementId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L184)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L304-L307)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.setViewport(250, 300)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L335)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L317-L322)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    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'],
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L145-L157)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        wait.until(visibilityOfElementLocated(By.id("imageButton"))).submit();
        wait.until(titleIs("We Arrive Here"));

        browsingContext.back();
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L330-L336)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.back()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L396)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L342-L352)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.forward()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L420)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L359-L365)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.traverseHistory(-1)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L378)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L34-L41)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L23-L28)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L54-L63)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L53-L62)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L81-88)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L70-L78)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L97-104)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L113-123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L86-L97)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L113-123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L150-163)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L170-L181)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0.0)

```js
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L105-L113)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

----
url: https://www.selenium.dev/documentation/test_practices/testing_types/
----

# Types of Testing

### Acceptance testing

This type of testing is done to determine if a feature or system meets the customer expectations and requirements. This type of testing generally involves the customer’s cooperation or feedback, being a validation activity that answers the question:

> Are we building the ***right*** product?

For web applications, the automation of this testing can be done directly with Selenium by simulating user expected behaviour. This simulation could be done by record/playback or through the different supported languages as explained in this documentation. Note: Acceptance testing is a subtype of ***functional testing***, which some people might also refer to.

### Functional testing

This type of testing is done to determine if a feature or system functions properly without issues. It checks the system at different levels to ensure that all scenarios are covered and that the system does *what* it’s supposed to do. It’s a verification activity that answers the question:

> Are we building the product ***right?***

This generally includes: the tests work without errors (404, exceptions…), in a usable way (correct redirections), in an accessible way and matching its specifications (see ***acceptance testing*** above).

For web applications, the automation of this testing can be done directly with Selenium by simulating expected returns. This simulation could be done by record/playback or through the different supported languages as explained in this documentation.

### Integration Tests

Integration tests verify the interactions between different components or modules of a system. Several modules are together tested. The purpose of Integration tests is to make sure that all modules integrate and work together as expected. Automated integration tests help ensure that these interactions work as expected and that integrated components function properly together.

> For example, ***Testing the flow of placing the order for an item in an ecommerce website along with payment.***

### System Tests

System Testing is a complete fully integrated product Testing. It is an end-to-end testing where in testing environment is similar to the production environment. Here, we navigate through all the features of the software and test if the end business / end feature works. We just test the end feature and don’t check for data flow or do functional testing and all.

> For example, ***Testing the end to end flow from login to placing an order and rechecking the order in My Orders page and logoff from an ecommerce website.***

### Performance testing

As its name indicates, performance tests are done to measure how well an application is performing.

There are two main sub-types for performance testing:

#### Load testing

Load testing is done to verify how well the application works under different defined loads (usually a particular number of users connected at once).

> For example, ***Testing that the site can handle numerous orders/users at once.***

#### Stress testing

Stress testing is done to verify how well the application works under stress (or above the maximum supported load).

> For example, ***Testing that your ecommerce site can handle Black Friday***

> For example, ***Testing that your new search bar doesn’t break the other buttons on the menu***

Last modified May 12, 2026: [Clarify BDD concepts and Selenium integration in testing types docs (#2566) (051b4c99811)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/051b4c998119db157295f8b35936cb84299e89c5)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/actions_api/keyboard/
----

# Ações de Teclado

```java
        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L17-L20)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L10-L13)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L13-L16)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L17-L20)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L19-L22)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L30-L35)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L21-L26)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L30-L35)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L25-L30)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L32-L37)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L32-L37)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .sendKeys("abc")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L45-L47)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L34-L36)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs

            new Actions(driver)
                .SendKeys("abc")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L45-L47)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .send_keys('abc')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L39-L41)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .sendKeys('abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L48-L50)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .sendKeys("abc")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L47-L49)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L59-L62)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L45-L48)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L58-L61)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L51-L54)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L59-L63)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L60-L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L70-L84)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L56-L67)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L72-L82)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L64-L74)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L73-L85)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L74-L86)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

----
url: https://www.selenium.dev/zh-cn/documentation/legacy/selenium_3/
----

# Selenium 3

Selenium 3是摒除了Selenium RC代码的WebDriver实现. 其已被实现了W3C WebDriver规范的Selenium 4所替代.

***

##### [服务网格 3](/zh-cn/documentation/legacy/selenium_3/grid_3/)

Selenium Grid 3 supported WebDriver without Selenium RC code. Grid 3 was completely rewritten for the new Grid 4.

##### [配置自己的服务网格](/zh-cn/documentation/legacy/selenium_3/grid_setup/)

Quick start guide for setting up Grid 3.

##### [服务网格的组件](/zh-cn/documentation/legacy/selenium_3/grid_components/)

Description of Hub and Nodes for Grid 3.

----
url: https://www.selenium.dev/pt-br/_print/documentation/webdriver/interactions/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/webdriver/interactions/).

# Browser interactions

* 1: [Browser navigation](#pg-8518d55e454f3b2bde11ba7045e18421)
* 2: [Alertas, prompts e confirmações JavaScript](#pg-9a4c7c70323fcb2800c1aa1cb53a26a6)
* 3: [Trabalhando com cookies](#pg-9b1bc8ac72585b018264a480c830e716)
* 4: [Working with IFrames and frames](#pg-4c2bcc66ae28060d39c5a58835230b80)
* 5: [Print Page](#pg-22ba314c22ae17172be65771ead8bd47)
* 6: [Working with windows and tabs](#pg-dcd02224fb2f013a77b712ca19e39a7c)
* 7: [Virtual Authenticator](#pg-d76dbaff8933667f4a8e7618d5a454a3)

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java#L15)

##### /examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class InteractionsTest extends BaseChromeTest {
    @Test
    public void getTitle() {
        driver.get("https://www.selenium.dev/");
        // get title
        String title = driver.getTitle();
        Assertions.assertEquals(title, "Selenium");
    }

    @Test
    public void getCurrentUrl() {
        driver.get("https://www.selenium.dev/");
        // get current url
        String url = driver.getCurrentUrl();
        Assertions.assertEquals(url, "https://www.selenium.dev/");
    }
}
```

```py
title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_interactions.py#L7)

##### /examples/python/tests/interactions/test\_interactions.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")

title = driver.title
assert title == "Selenium"

url = driver.current_url
assert url == "https://www.selenium.dev/"

driver.quit()
```

```cs
            String title = driver.Title;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs#L37)

##### /examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class InteractionsTest
    {
        [TestMethod]
        public void TestInteractions()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url="https://www.selenium.dev/";
            //GetTitle
            String title = driver.Title;
            Assert.AreEqual(title, "Selenium");

            //GetCurrentURL
            String url = driver.Url;
            Assert.AreEqual(url, "https://www.selenium.dev/");

            //quitting driver
            driver.Quit(); //close all windows
        }
    }
}
```

```rb
  it 'gets the current title' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/browser_spec.rb#L8)

##### /examples/ruby/spec/interactions/browser\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'gets the current title' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_title = driver.title
    expect(current_title).to eq 'Selenium'
  end

  it 'gets the current url' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_url = driver.current_url
    expect(current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    let title = await driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/interactionsIndex.spec.js#L20)

##### /examples/javascript/test/interactions/interactionsIndex.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Should be able to get title and current url', async function () {
    const url = 'https://www.selenium.dev/';
    await driver.get(url);

    //Get Current title
    let title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Get Current url
    let currentUrl = await driver.getCurrentUrl();
    assert.equal(currentUrl, url);
  });
});
```

```kotlin
driver.title
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java#L26)

##### /examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class InteractionsTest extends BaseChromeTest {
    @Test
    public void getTitle() {
        driver.get("https://www.selenium.dev/");
        // get title
        String title = driver.getTitle();
        Assertions.assertEquals(title, "Selenium");
    }

    @Test
    public void getCurrentUrl() {
        driver.get("https://www.selenium.dev/");
        // get current url
        String url = driver.getCurrentUrl();
        Assertions.assertEquals(url, "https://www.selenium.dev/");
    }
}
```

```py
url = driver.current_url
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_interactions.py#L10)

##### /examples/python/tests/interactions/test\_interactions.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")

title = driver.title
assert title == "Selenium"

url = driver.current_url
assert url == "https://www.selenium.dev/"

driver.quit()
```

```cs
            String url = driver.Url;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs#L41)

##### /examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class InteractionsTest
    {
        [TestMethod]
        public void TestInteractions()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url="https://www.selenium.dev/";
            //GetTitle
            String title = driver.Title;
            Assert.AreEqual(title, "Selenium");

            //GetCurrentURL
            String url = driver.Url;
            Assert.AreEqual(url, "https://www.selenium.dev/");

            //quitting driver
            driver.Quit(); //close all windows
        }
    }
}
```

```rb
  it 'gets the current url' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/browser_spec.rb#L14)

##### /examples/ruby/spec/interactions/browser\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'gets the current title' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_title = driver.title
    expect(current_title).to eq 'Selenium'
  end

  it 'gets the current url' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_url = driver.current_url
    expect(current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    let currentUrl = await driver.getCurrentUrl();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/interactionsIndex.spec.js#L24)

##### /examples/javascript/test/interactions/interactionsIndex.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Should be able to get title and current url', async function () {
    const url = 'https://www.selenium.dev/';
    await driver.get(url);

    //Get Current title
    let title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Get Current url
    let currentUrl = await driver.getCurrentUrl();
    assert.equal(currentUrl, url);
  });
});
```

```kotlin
driver.currentUrl
```

# 1 - Browser navigation

```java
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L14-L18)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.get("https://www.selenium.dev/selenium/web/index.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L6)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Convenient
            driver.Url = "https://selenium.dev";
            //Longer
            driver.Navigate().GoToUrl("https://selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class NavigationTest
    {
        [TestMethod]
        public void TestNavigationCommands()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            //Convenient
            driver.Url = "https://selenium.dev";
            //Longer
            driver.Navigate().GoToUrl("https://selenium.dev");
            var title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Back
            driver.Navigate().Back();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Forward
            driver.Navigate().Forward();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Refresh
            driver.Navigate().Refresh();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Quit the browser
            driver.Quit();
        }
    }
}
```

```rb

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L7-L9)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L16-L20)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
//Convenient
driver.get("https://selenium.dev")

//Longer way
driver.navigate().to("https://selenium.dev")
  
```

```java
        //Back
        driver.navigate().back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L22-L23)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.back()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L11)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Back
             driver.Navigate().Back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L24-L25)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
    driver.navigate.to 'https://www.selenium.dev/'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L15)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Back
    await driver.navigate().back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L24-L25)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().back() 
```

```java
        //Forward
        driver.navigate().forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L27-L28)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.forward()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L15)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Forward
             driver.Navigate().Forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L29-L30)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L23)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Forward
    await driver.navigate().forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L29-L30)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().forward()
```

```java
        //Refresh
        driver.navigate().refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L32-L33)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.refresh()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L19)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Refresh
             driver.Navigate().Refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L34-L35)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
  it 'refreshes the page' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L29)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Refresh
    await driver.navigate().refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L34-L35)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().refresh()
```

# 2 - Alertas, prompts e confirmações JavaScript

```java

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L36-L41)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L12-L18)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L15-L22)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L19-L21)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See an example alert")).click()

//Wait for the alert to be displayed and store it in a variable
val alert = wait.until(ExpectedConditions.alertIsPresent())

//Store the alert text in a variable
val text = alert.getText()

//Press the OK button
alert.accept()
  
```

```java
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L131-L138)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L26-L32)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See a sample confirm")).Click();

//Wait for the alert to be displayed
wait.Until(ExpectedConditions.AlertIsPresent());

//Store the alert in a variable
IAlert alert = driver.SwitchTo().Alert();

//Store the alert in a variable for reuse
string text = alert.Text;

//Press the Cancel button
alert.Dismiss();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L28-L35)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L30-L32)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See a sample confirm")).click()

//Wait for the alert to be displayed
wait.until(ExpectedConditions.alertIsPresent())

//Store the alert in a variable
val alert = driver.switchTo().alert()

//Store the alert in a variable for reuse
val text = alert.text

//Press the Cancel button
alert.dismiss()
  
```

```java
        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L79-L84)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L40-L47)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See a sample prompt")).Click();

//Wait for the alert to be displayed and store it in a variable
IAlert alert = wait.Until(ExpectedConditions.AlertIsPresent());

//Type your message
alert.SendKeys("Selenium");

//Press the OK button
alert.Accept();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L41-L48)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L42-L45)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See a sample prompt")).click()

//Wait for the alert to be displayed and store it in a variable
val alert = wait.until(ExpectedConditions.alertIsPresent())

//Type your message
alert.sendKeys("Selenium")

//Press the OK button
alert.accept()
  
```

# 3 - Trabalhando com cookies

```java

    WebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L30-L32)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L5-L9)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L32-L34)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L9-L11)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L18)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

  const {Browser, Builder} = require("selenium-webdriver");
  const assert = require('assert')
  
  
  describe('Cookies', function() {
    let driver;
  
    before(async function() {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('Create a cookie', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // set a cookie on the current domain
      await driver.manage().addCookie({ name: 'key', value: 'value' });
    });
  
    it('Create cookies with sameSite', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
      await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
      await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
    });
  
    it('Read cookie', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // set a cookie on the current domain
      await driver.manage().addCookie({ name: 'foo', value: 'bar' });
  
      // Get cookie details with named cookie 'foo'
      await driver.manage().getCookie('foo').then(function(cookie) {
        assert.equal(cookie.value, 'bar');
      });
    });
  
    it('Read all cookies', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // Add few cookies
      await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
      await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
  
      // Get all Available cookies
      await driver.manage().getCookies().then(function(cookies) {
        assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
      });
    });
  
    it('Delete a cookie', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // Add few cookies
      await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
      await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
  
      // Delete a cookie with name 'test1'
      await driver.manage().deleteCookie('test1');
  
      // Get all Available cookies
      await driver.manage().getCookies().then(function(cookies) {
        assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
      });
    });
  
    it('Delete all cookies', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // Add few cookies
      await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
      await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
  
      // Delete all cookies
      await driver.manage().deleteAllCookies();
    });
  });
  
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")

        // Adds the cookie into current browser context
        driver.manage().addCookie(Cookie("key", "value"))
    } finally {
        driver.quit()
    }
}
  
```

```java
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L38-L42)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L13-L20)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L40-L44)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L17-L21)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L35-L38)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("foo", "bar"))

        // Get cookie details with named cookie 'foo'
        val cookie = driver.manage().getCookieNamed("foo")
        println(cookie)
    } finally {
        driver.quit()
    }
}  
  
```

```java
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L52-L66)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L24-L32)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L51-L64)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L26-L31)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L49-L51)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        driver.manage().addCookie(Cookie("test2", "cookie2"))

        // Get All available cookies
        val cookies = driver.manage().cookies
        println(cookies)
    } finally {
        driver.quit()
    }
}  
  
```

```java
        }
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L74-L77)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L35-L43)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L70-L73)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L40-L43)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L61-L62)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        val cookie1 = Cookie("test2", "cookie2")
        driver.manage().addCookie(cookie1)

        // delete a cookie with name 'test1'
        driver.manage().deleteCookieNamed("test1")
        
        // delete cookie by passing cookie object of current browsing context.
        driver.manage().deleteCookie(cookie1)
    } finally {
        driver.quit()
    }
}  
  
```

```java
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L100-L105)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L47-L55)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L92-L97)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L49-L54)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L77-L78)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        driver.manage().addCookie(Cookie("test2", "cookie2"))

        // deletes all cookies
        driver.manage().deleteAllCookies()
    } finally {
        driver.quit()
    }
}  
  
```

```java

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L112-L121)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L59-L71)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SameSiteCookie {
  class SameSiteCookie {
    static void Main(string[] args) {
      IWebDriver driver = new ChromeDriver();
      try {
        driver.Navigate().GoToUrl("http://www.example.com");

        var cookie1Dictionary = new System.Collections.Generic.Dictionary<string, object>() {
          { "name", "test1" }, { "value", "cookie1" }, { "sameSite", "Strict" } };
        var cookie1 = Cookie.FromDictionary(cookie1Dictionary);

        var cookie2Dictionary = new System.Collections.Generic.Dictionary<string, object>() {
          { "name", "test2" }, { "value", "cookie2" }, { "sameSite", "Lax" } };
        var cookie2 = Cookie.FromDictionary(cookie2Dictionary);

        driver.Manage().Cookies.AddCookie(cookie1);
        driver.Manage().Cookies.AddCookie(cookie2);

        System.Console.WriteLine(cookie1.SameSite);
        System.Console.WriteLine(cookie2.SameSite);
      } finally {
        driver.Quit();
      }
    }
  }
}
  
```

```ruby
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://www.example.com'
  # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
  driver.manage.add_cookie(name: "foo", value: "bar", same_site: "Strict")
  driver.manage.add_cookie(name: "foo1", value: "bar", same_site: "Lax")
  puts driver.manage.cookie_named('foo')
  puts driver.manage.cookie_named('foo1')
ensure
  driver.quit
end
  
```

```js
  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L24-L26)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("http://www.example.com")
        val cookie = Cookie.Builder("key", "value").sameSite("Strict").build()
        val cookie1 = Cookie.Builder("key", "value").sameSite("Lax").build()
        driver.manage().addCookie(cookie)
        driver.manage().addCookie(cookie1)
        println(cookie.getSameSite())
        println(cookie1.getSameSite())
    } finally {
        driver.quit()
    }
}
  
```

# 4 - Working with IFrames and frames

Frames são um meio obsoleto de construir um layout de site a partir de vários documentos no mesmo domínio. É improvável que você trabalhe com eles a menos que você esteja trabalhando com um webapp pré-HTML5. Iframes permitem a inserção de um documento de um domínio totalmente diferente, e são ainda comumente usado.

Se você precisa trabalhar com frames ou iframes, o WebDriver permite que você trabalhe com eles da mesma maneira. Considere um botão dentro de um iframe. Se inspecionarmos o elemento usando as ferramentas de desenvolvimento do navegador, podemos ver o seguinte:

```html
<div id="modal">
  <iframe id="buttonframe" name="myframe"  src="https://seleniumhq.github.io">
   <button>Click here</button>
 </iframe>
</div>
```

```java
//This won't work
driver.findElement(By.tagName("button")).click();
  
```

```python
    # This Wont work
driver.find_element(By.TAG_NAME, 'button').click()
  
```

```csharp
//This won't work
driver.FindElement(By.TagName("button")).Click();
  
```

```ruby
    # This won't work
driver.find_element(:tag_name,'button').click
  
```

```javascript
// This won't work
await driver.findElement(By.css('button')).click();
  
```

```kotlin
//This won't work
driver.findElement(By.tagName("button")).click()
  
```

```java
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L38-L46)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L24-L32)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L38-L46)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L26-L33)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Store the web element
const iframe = driver.findElement(By.css('#modal > iframe'));

// Switch to the frame
await driver.switchTo().frame(iframe);

// Now we can click the button
await driver.findElement(By.css('button')).click();
  
```

```kotlin
//Store the web element
val iframe = driver.findElement(By.cssSelector("#modal>iframe"))

//Switch to the frame
driver.switchTo().frame(iframe)

//Now we can click the button
driver.findElement(By.tagName("button")).click()
  
```

```java
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L50-L58)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L34-L42)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L50-L58)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L36-L43)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Using the ID
await driver.switchTo().frame('buttonframe');

// Or using the name instead
await driver.switchTo().frame('myframe');

// Now we can click the button
await driver.findElement(By.css('button')).click();
  
```

```kotlin
//Using the ID
driver.switchTo().frame("buttonframe")

//Or using the name instead
driver.switchTo().frame("myframe")

//Now we can click the button
driver.findElement(By.tagName("button")).click()
  
```

```java
         //switch To IFrame using index
         driver.switchTo().frame(0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L62-L63)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L45-L46)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L62-L63)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L46-L47)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Switches to the second frame
await driver.switchTo().frame(1);
```

```kotlin
// Switches to the second frame
driver.switchTo().frame(1)
```

```java
         //leave frame
         driver.switchTo().defaultContent();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L66-L67)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L49-L50)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //leave frame
            driver.SwitchTo().DefaultContent();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L66-L67)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L49-L50)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Return to the top level
await driver.switchTo().defaultContent();
```

```kotlin
// Return to the top level
driver.switchTo().defaultContent()
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L14-L17)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L12-L19)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L12-L14)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L23-L26)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L22-L29)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L18-L26)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L32-L35)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L32-L38)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L24-L27)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#41-L48)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L51-L57)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L30-L35)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L53-L57)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L61-L68)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L42-L45)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L63-L66)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L41-L48)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L49-L51)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L72-L75)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L71-L78)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L55-L57)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java#L27-L31)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.Pdf;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.PrintsPage;
import dev.selenium.BaseTest;

public class PrintsPageTest extends BaseTest{

    @BeforeEach
    public void setup() {
        ChromeOptions options = getDefaultChromeOptions();
        options.setCapability("webSocketUrl", true);
        driver = new ChromeDriver(options);
    }

    @Test
    public void PrintWithPrintsPageTest() 
    {
        driver.get("https://www.selenium.dev/");
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }

    @Test
    public void PrintWithBrowsingContextTest() 
    {
        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);
        Assertions.assertTrue(printPage.length() > 0);
    }
}
```

**BrowsingContext()**

```java
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        PrintOptions printOptions = new PrintOptions();
        String printPage = browsingContext.print(printOptions);
        Assertions.assertTrue(printPage.length() > 0);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java#L37-L41)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.Pdf;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.PrintsPage;
import dev.selenium.BaseTest;

public class PrintsPageTest extends BaseTest{

    @BeforeEach
    public void setup() {
        ChromeOptions options = getDefaultChromeOptions();
        options.setCapability("webSocketUrl", true);
        driver = new ChromeDriver(options);
    }

    @Test
    public void PrintWithPrintsPageTest() 
    {
        driver.get("https://www.selenium.dev/");
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }

    @Test
    public void PrintWithBrowsingContextTest() 
    {
        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);
        Assertions.assertTrue(printPage.length() > 0);
    }
}
```

```cs
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L81-L88)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

**print\_page()**

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    pdf = driver.print_page(print_options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_prints_page.py#L12-L14)

##### /examples/python/tests/interactions/test\_prints\_page.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_prints_page(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    pdf = driver.print_page(print_options)
    assert len(pdf) > 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

# 6 - Working with windows and tabs

```java
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L16-L20)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L16-L18)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L17-L21)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
driver.window_handle
```

```javascript
await driver.getWindowHandle();
```

```kotlin
driver.windowHandle
```

```java
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L22-L29)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L22-L32)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L23-L30)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
    #Store the ID of the original window
original_window = driver.window_handle

    #Check we don't have other windows open already
assert(driver.window_handles.length == 1, 'Expected one window')

    #Click the link which opens in a new window
driver.find_element(link: 'new window').click

    #Wait for the new window or tab
wait.until { driver.window_handles.length == 2 }

    #Loop through until we find a new window handle
driver.window_handles.each do |handle|
    if handle != original_window
        driver.switch_to.window handle
        break
    end
end

    #Wait for the new tab to finish loading content
wait.until { driver.title == 'Selenium documentation'}
  
```

```javascript
//Store the ID of the original window
const originalWindow = await driver.getWindowHandle();

//Check we don't have other windows open already
assert((await driver.getAllWindowHandles()).length === 1);

//Click the link which opens in a new window
await driver.findElement(By.linkText('new window')).click();

//Wait for the new window or tab
await driver.wait(
    async () => (await driver.getAllWindowHandles()).length === 2,
    10000
  );

//Loop through until we find a new window handle
const windows = await driver.getAllWindowHandles();
windows.forEach(async handle => {
  if (handle !== originalWindow) {
    await driver.switchTo().window(handle);
  }
});

//Wait for the new tab to finish loading content
await driver.wait(until.titleIs('Selenium documentation'), 10000);
  
```

```kotlin
//Store the ID of the original window
val originalWindow = driver.getWindowHandle()

//Check we don't have other windows open already
assert(driver.getWindowHandles().size() === 1)

//Click the link which opens in a new window
driver.findElement(By.linkText("new window")).click()

//Wait for the new window or tab
wait.until(numberOfWindowsToBe(2))

//Loop through until we find a new window handle
for (windowHandle in driver.getWindowHandles()) {
    if (!originalWindow.contentEquals(windowHandle)) {
        driver.switchTo().window(windowHandle)
        break
    }
}

//Wait for the new tab to finish loading content
wait.until(titleIs("Selenium documentation"))

  
```

```java
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L31-L34)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L46-L46)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L32-L35)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
    #Close the tab or window
driver.close

    #Switch back to the old tab or window
driver.switch_to.window original_window
  
```

```javascript
//Close the tab or window
await driver.close();

//Switch back to the old tab or window
await driver.switchTo().window(originalWindow);
  
```

```kotlin
//Close the tab or window
driver.close()

//Switch back to the old tab or window
driver.switchTo().window(originalWindow)

  
```

```java
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L36-L42)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L53-L58)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L37-L43)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

Opens a new tab and switches to new tab

```rb
    driver.switch_to.new_window(:tab)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/windows_spec.rb#L9)

##### /examples/ruby/spec/interactions/windows\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Windows' do
  let(:driver) { start_session }

  it 'opens new tab' do
    driver.switch_to.new_window(:tab)

    expect(driver.window_handles.size).to eq 2
  end

  it 'opens new window' do
    driver.switch_to.new_window(:window)

    expect(driver.window_handles.size).to eq 2
  end
end
```

Opens a new window and switches to new window

```rb
    driver.switch_to.new_window(:window)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/windows_spec.rb#L15)

##### /examples/ruby/spec/interactions/windows\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Windows' do
  let(:driver) { start_session }

  it 'opens new tab' do
    driver.switch_to.new_window(:tab)

    expect(driver.window_handles.size).to eq 2
  end

  it 'opens new window' do
    driver.switch_to.new_window(:window)

    expect(driver.window_handles.size).to eq 2
  end
end
```

Opens a new tab and switches to new tab

```js
    await driver.switchTo().newWindow('tab');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L70)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

Opens a new window and switches to new window:

```js
    await driver.switchTo().newWindow('window');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L75)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Opens a new tab and switches to new tab
driver.switchTo().newWindow(WindowType.TAB)

// Opens a new window and switches to new window
driver.switchTo().newWindow(WindowType.WINDOW)
  
```

```java
        //quitting driver
        driver.quit(); //close all windows
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L44-L45)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L13-L13)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //quitting driver
              driver.Quit(); //close all windows
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L45-L46)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
driver.quit
```

```javascript
await driver.quit();
```

```kotlin
driver.quit()
```

```java
/**
 * Example using JUnit
 * https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
 */
@AfterAll
public static void tearDown() {
    driver.quit();
}
  
```

```python
    # unittest teardown
    # https://docs.python.org/3/library/unittest.html?highlight=teardown#unittest.TestCase.tearDown
def tearDown(self):
    self.driver.quit()
  
```

```csharp
/*
    Example using Visual Studio's UnitTesting
    https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.aspx
*/
[TestCleanup]
public void TearDown()
{
    driver.Quit();
}
  
```

```ruby
    # UnitTest Teardown
    # https://www.rubydoc.info/github/test-unit/test-unit/Test/Unit/TestCase
def teardown
    @driver.quit
end
  
```

```javascript
/**
 * Example using Mocha
 * https://mochajs.org/#hooks
 */
after('Tear down', async function () {
  await driver.quit();
});
  
```

```kotlin
/**
 * Example using JUnit
 * https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
 */
@AfterAll
fun tearDown() {
    driver.quit()
}
  
```

```java
try {
    //WebDriver code here...
} finally {
    driver.quit();
}
  
```

```python
try:
    #WebDriver code here...
finally:
    driver.quit()
  
```

```csharp
try {
    //WebDriver code here...
} finally {
    driver.Quit();
}
  
```

```ruby
begin
    #WebDriver code here...
ensure
    driver.quit
end
  
```

```javascript
try {
    //WebDriver code here...
} finally {
    await driver.quit();
}
  
```

```kotlin
try {
    //WebDriver code here...
} finally {
    driver.quit()
}
  
```

O WebDriver do Python agora suporta o gerenciador de contexto python, que ao usar a palavra-chave `with` pode encerrar automaticamente o driver no fim da execução.

```python
with webdriver.Firefox() as driver:
  # WebDriver code here...

# WebDriver will automatically quit after indentation
```

```java
//Access each dimension individually
int width = driver.manage().window().getSize().getWidth();
int height = driver.manage().window().getSize().getHeight();

//Or store the dimensions and query them later
Dimension size = driver.manage().window().getSize();
int width1 = size.getWidth();
int height1 = size.getHeight();
  
```

```python
    # Access each dimension individually
width = driver.get_window_size().get("width")
height = driver.get_window_size().get("height")

    # Or store the dimensions and query them later
size = driver.get_window_size()
width1 = size.get("width")
height1 = size.get("height")
  
```

```csharp
//Access each dimension individually
int width = driver.Manage().Window.Size.Width;
int height = driver.Manage().Window.Size.Height;

//Or store the dimensions and query them later
System.Drawing.Size size = driver.Manage().Window.Size;
int width1 = size.Width;
int height1 = size.Height;
  
```

```ruby
    # Access each dimension individually
width = driver.manage.window.size.width
height = driver.manage.window.size.height

    # Or store the dimensions and query them later
size = driver.manage.window.size
width1 = size.width
height1 = size.height
  
```

Access each dimension individually

```js
    const { width, height } = await driver.manage().window().getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L93)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

(or) store the dimensions and query them later

```js
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L96-L98)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
//Access each dimension individually
val width = driver.manage().window().size.width
val height = driver.manage().window().size.height

//Or store the dimensions and query them later
val size = driver.manage().window().size
val width1 = size.width
val height1 = size.height
  
```

```java
driver.manage().window().setSize(new Dimension(1024, 768));
```

```python
driver.set_window_size(1024, 768)
```

```csharp
driver.Manage().Window.Size = new Size(1024, 768);
```

```ruby
driver.manage.window.resize_to(1024,768)
```

```javascript
await driver.manage().window().setRect({ width: 1024, height: 768 });
```

```kotlin
driver.manage().window().size = Dimension(1024, 768)
```

```java
// Access each dimension individually
int x = driver.manage().window().getPosition().getX();
int y = driver.manage().window().getPosition().getY();

// Or store the dimensions and query them later
Point position = driver.manage().window().getPosition();
int x1 = position.getX();
int y1 = position.getY();
  
```

```python
    # Access each dimension individually
x = driver.get_window_position().get('x')
y = driver.get_window_position().get('y')

    # Or store the dimensions and query them later
position = driver.get_window_position()
x1 = position.get('x')
y1 = position.get('y')
  
```

```csharp
//Access each dimension individually
int x = driver.Manage().Window.Position.X;
int y = driver.Manage().Window.Position.Y;

//Or store the dimensions and query them later
Point position = driver.Manage().Window.Position;
int x1 = position.X;
int y1 = position.Y;
  
```

```ruby
    #Access each dimension individually
x = driver.manage.window.position.x
y = driver.manage.window.position.y

    # Or store the dimensions and query them later
rect  = driver.manage.window.rect
x1 = rect.x
y1 = rect.y
  
```

Access each dimension individually

```js
    const { x, y } = await driver.manage().window().getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L108)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

(or) store the dimensions and query them later

```js
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L111-L113)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Access each dimension individually
val x = driver.manage().window().position.x
val y = driver.manage().window().position.y

// Or store the dimensions and query them later
val position = driver.manage().window().position
val x1 = position.x
val y1 = position.y

  
```

```java
// Move the window to the top left of the primary monitor
driver.manage().window().setPosition(new Point(0, 0));
  
```

```python
    # Move the window to the top left of the primary monitor
driver.set_window_position(0, 0)
  
```

```csharp
// Move the window to the top left of the primary monitor
driver.Manage().Window.Position = new Point(0, 0);
  
```

```ruby
driver.manage.window.move_to(0,0)
  
```

```javascript
// Move the window to the top left of the primary monitor
await driver.manage().window().setRect({ x: 0, y: 0 });
  
```

```kotlin
// Move the window to the top left of the primary monitor
driver.manage().window().position = Point(0,0)
    
```

```java
driver.manage().window().maximize();
```

```python
driver.maximize_window()
```

```csharp
driver.Manage().Window.Maximize();
```

```ruby
driver.manage.window.maximize
```

```javascript
await driver.manage().window().maximize();
```

```kotlin
driver.manage().window().maximize()
```

```java
driver.manage().window().minimize();
```

```python
driver.minimize_window()
```

```csharp
driver.Manage().Window.Minimize();
```

```ruby
driver.manage.window.minimize
```

```javascript
await driver.manage().window().minimize();
```

```kotlin
driver.manage().window().minimize()
```

```java
driver.manage().window().fullscreen();
```

```python
driver.fullscreen_window()
```

```csharp
driver.Manage().Window.FullScreen();
```

```ruby
driver.manage.window.full_screen
```

```javascript
await driver.manage().window().fullscreen();
```

```kotlin
driver.manage().window().fullscreen()
```

```java
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.*;
import org.openqa.selenium.*;

public class SeleniumTakeScreenshot {
    public static void main(String args[]) throws IOException {
        WebDriver driver = new ChromeDriver();
        driver.get("http://www.example.com");
        File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(scrFile, new File("./image.png"));
        driver.quit();
    }
}
  
```

```python
from selenium import webdriver

driver = webdriver.Chrome()

    # Navigate to url
driver.get("http://www.example.com")

    # Returns and base64 encoded string into image
driver.save_screenshot('./image.png')

driver.quit()
```

```csharp
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using OpenQA.Selenium.Support.UI;

  var driver = new ChromeDriver();
  driver.Navigate().GoToUrl("http://www.example.com");
  Screenshot screenshot = (driver as ITakesScreenshot).GetScreenshot();
  screenshot.SaveAsFile("screenshot.png", ScreenshotImageFormat.Png); // Format values are Bmp, Gif, Jpeg, Png, Tiff
  
```

```ruby
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://example.com/'

      # Takes and Stores the screenshot in specified path
  driver.save_screenshot('./image.png')

end
  
```

```js
    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L56-L59)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
import com.oracle.tools.packager.IOUtils.copyFile
import org.openqa.selenium.*
import org.openqa.selenium.chrome.ChromeDriver
import java.io.File

fun main(){
    val driver =  ChromeDriver()
    driver.get("https://www.example.com")
    val scrFile = (driver as TakesScreenshot).getScreenshotAs<File>(OutputType.FILE)
    copyFile(scrFile, File("./image.png"))
    driver.quit()
}
   
```

```java
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.File;
import java.io.IOException;

public class SeleniumelementTakeScreenshot {
  public static void main(String args[]) throws IOException {
    WebDriver driver = new ChromeDriver();
    driver.get("https://www.example.com");
    WebElement element = driver.findElement(By.cssSelector("h1"));
    File scrFile = element.getScreenshotAs(OutputType.FILE);
    FileUtils.copyFile(scrFile, new File("./image.png"));
    driver.quit();
  }
}
  
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

    # Navigate to url
driver.get("http://www.example.com")

ele = driver.find_element(By.CSS_SELECTOR, 'h1')

    # Returns and base64 encoded string into image
ele.screenshot('./image.png')

driver.quit()
  
```

```csharp
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;
    using OpenQA.Selenium.Support.UI;

    // Webdriver
    var driver = new ChromeDriver();
    driver.Navigate().GoToUrl("http://www.example.com");

    // Fetch element using FindElement
    var webElement = driver.FindElement(By.CssSelector("h1"));

    // Screenshot for the element
    var elementScreenshot = (webElement as ITakesScreenshot).GetScreenshot();
    elementScreenshot.SaveAsFile("screenshot_of_element.png");
  
```

```ruby
    # Works with Selenium4-alpha7 Ruby bindings and above
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://example.com/'
  ele = driver.find_element(:css, 'h1')

      # Takes and Stores the element screenshot in specified path
  ele.save_screenshot('./image.jpg')
end
  
```

```js
    let header = await driver.findElement(By.css('h1'));
      // Captures the element screenshot
      let encodedString = await header.takeScreenshot(true);
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
  
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L44-L48)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
  const chrome = require('selenium-webdriver/chrome');
  const assert = require("node:assert");
  let opts = new chrome.Options();
  opts.addArguments('--headless');
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let imgMagicNumber = 'iVBOR'
  let base64Code
  
  describe('Interactions - Windows', function () {
    let driver;
    before(async function () {
      driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
    });
  
    after(async () => await driver.quit());
  
    it('Should be able to print page to pdf', async function () {
  
      await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
      let base64 = await driver.printPage({pageRanges: ["1-2"]});
      // page can be saved as a PDF as below
      // await fs.writeFileSync('./test.pdf', base64, 'base64');
  
      base64Code = base64.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, pdfMagicNumber)
    });
  
    it('Should be able to get text using executeScript', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
      // Stores the header element
      let header = await driver.findElement(By.css('h1'));
  
      // Executing JavaScript to capture innerText of header element
      let text = await driver.executeScript('return arguments[0].innerText', header);
      assert.strictEqual(text, `Type Stuff`)
    });
  
    it('Should be able to take Element Screenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      let header = await driver.findElement(By.css('h1'));
      // Captures the element screenshot
      let encodedString = await header.takeScreenshot(true);
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to takeScreenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      // Captures the screenshot
      let encodedString = await driver.takeScreenshot();
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to switch to newWindow and newTab and close', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
      const initialWindow = await driver.getAllWindowHandles();
      assert.strictEqual(initialWindow.length, 1)
  
      // Opens a new tab and switches to new tab
      await driver.switchTo().newWindow('tab');
      const browserTabs = await driver.getAllWindowHandles();
      assert.strictEqual(browserTabs.length, 2)
  
      // Opens a new window and switches to new window
      await driver.switchTo().newWindow('window');
      const windows = await driver.getAllWindowHandles();
      assert.strictEqual(windows.length, 3)
  
      //Close the tab or window
      await driver.close();
  
      //Switch back to the old tab or window
      await driver.switchTo().window(windows[1]);
  
      const windowsAfterClose = await driver.getAllWindowHandles();
      assert.strictEqual(windowsAfterClose.length, 2);
    });
  
    it('Should be able to getWindow Size', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { width, height } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const windowWidth = rect.width;
      const windowHeight = rect.height;
  
      assert.ok(windowWidth>0);
      assert.ok(windowHeight>0);
    });
  
    it('Should be able to getWindow position', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { x, y } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const x1 = rect.x;
      const y1 = rect.y;
  
      assert.ok(x1>=0);
      assert.ok(y1>=0);
    });
  });
```

```kotlin
import org.apache.commons.io.FileUtils
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.*
import java.io.File

fun main() {
    val driver = ChromeDriver()
    driver.get("https://www.example.com")
    val element = driver.findElement(By.cssSelector("h1"))
    val scrFile: File = element.getScreenshotAs(OutputType.FILE)
    FileUtils.copyFile(scrFile, File("./image.png"))
    driver.quit()
}
  
```

```java
    //Creating the JavascriptExecutor interface object by Type casting
      JavascriptExecutor js = (JavascriptExecutor)driver;
    //Button Element
      WebElement button =driver.findElement(By.name("btnLogin"));
    //Executing JavaScript to click on element
      js.executeScript("arguments[0].click();", button);
    //Get return value from script
      String text = (String) js.executeScript("return arguments[0].innerText", button);
    //Executing JavaScript directly
      js.executeScript("console.log('hello world')");
  
```

```python
    # Stores the header element
header = driver.find_element(By.CSS_SELECTOR, "h1")

    # Executing JavaScript to capture innerText of header element
driver.execute_script('return arguments[0].innerText', header)
  
```

```csharp
   //creating Chromedriver instance
	IWebDriver driver = new ChromeDriver();
	//Creating the JavascriptExecutor interface object by Type casting
	IJavaScriptExecutor js = (IJavaScriptExecutor) driver;
	//Button Element
	IWebElement button = driver.FindElement(By.Name("btnLogin"));
	//Executing JavaScript to click on element
	js.ExecuteScript("arguments[0].click();", button);
	//Get return value from script
	String text = (String)js.ExecuteScript("return arguments[0].innerText", button);
	//Executing JavaScript directly
	js.ExecuteScript("console.log('hello world')");
  
```

```ruby
    # Stores the header element
header = driver.find_element(css: 'h1')

    # Get return value from script
result = driver.execute_script("return arguments[0].innerText", header)

    # Executing JavaScript directly
driver.execute_script("alert('hello world')")
  
```

```js
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L33-L37)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Stores the header element
val header = driver.findElement(By.cssSelector("h1"))

// Get return value from script
val result = driver.executeScript("return arguments[0].innerText", header)

// Executing JavaScript directly
driver.executeScript("alert('hello world')")
  
```

```java
    import org.openqa.selenium.print.PrintOptions;

    driver.get("https://www.selenium.dev");
    printer = (PrintsPage) driver;

    PrintOptions printOptions = new PrintOptions();
    printOptions.setPageRanges("1-2");

    Pdf pdf = printer.print(printOptions);
    String content = pdf.getContent();
  
```

```python
    from selenium.webdriver.common.print_page_options import PrintOptions

    print_options = PrintOptions()
    print_options.page_ranges = ['1-2']

    driver.get("printPage.html")

    base64code = driver.print_page(print_options)
  
```

```csharp
    // code sample not available please raise a PR
  
```

```ruby
    driver.navigate_to 'https://www.selenium.dev'

    base64encodedContent = driver.print_page(orientation: 'landscape')
  
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
      let base64 = await driver.printPage({pageRanges: ["1-2"]});
      // page can be saved as a PDF as below
      // await fs.writeFileSync('./test.pdf', base64, 'base64');
  
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L22-L25)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
  const chrome = require('selenium-webdriver/chrome');
  const assert = require("node:assert");
  let opts = new chrome.Options();
  opts.addArguments('--headless');
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let imgMagicNumber = 'iVBOR'
  let base64Code
  
  describe('Interactions - Windows', function () {
    let driver;
    before(async function () {
      driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
    });
  
    after(async () => await driver.quit());
  
    it('Should be able to print page to pdf', async function () {
  
      await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
      let base64 = await driver.printPage({pageRanges: ["1-2"]});
      // page can be saved as a PDF as below
      // await fs.writeFileSync('./test.pdf', base64, 'base64');
  
      base64Code = base64.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, pdfMagicNumber)
    });
  
    it('Should be able to get text using executeScript', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
      // Stores the header element
      let header = await driver.findElement(By.css('h1'));
  
      // Executing JavaScript to capture innerText of header element
      let text = await driver.executeScript('return arguments[0].innerText', header);
      assert.strictEqual(text, `Type Stuff`)
    });
  
    it('Should be able to take Element Screenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      let header = await driver.findElement(By.css('h1'));
      // Captures the element screenshot
      let encodedString = await header.takeScreenshot(true);
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to takeScreenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      // Captures the screenshot
      let encodedString = await driver.takeScreenshot();
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to switch to newWindow and newTab and close', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
      const initialWindow = await driver.getAllWindowHandles();
      assert.strictEqual(initialWindow.length, 1)
  
      // Opens a new tab and switches to new tab
      await driver.switchTo().newWindow('tab');
      const browserTabs = await driver.getAllWindowHandles();
      assert.strictEqual(browserTabs.length, 2)
  
      // Opens a new window and switches to new window
      await driver.switchTo().newWindow('window');
      const windows = await driver.getAllWindowHandles();
      assert.strictEqual(windows.length, 3)
  
      //Close the tab or window
      await driver.close();
  
      //Switch back to the old tab or window
      await driver.switchTo().window(windows[1]);
  
      const windowsAfterClose = await driver.getAllWindowHandles();
      assert.strictEqual(windowsAfterClose.length, 2);
    });
  
    it('Should be able to getWindow Size', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { width, height } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const windowWidth = rect.width;
      const windowHeight = rect.height;
  
      assert.ok(windowWidth>0);
      assert.ok(windowHeight>0);
    });
  
    it('Should be able to getWindow position', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { x, y } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const x1 = rect.x;
      const y1 = rect.y;
  
      assert.ok(x1>=0);
      assert.ok(y1>=0);
    });
  });
```

```kotlin
    driver.get("https://www.selenium.dev")
    val printer = driver as PrintsPage

    val printOptions = PrintOptions()
    printOptions.setPageRanges("1-2")
    
    val pdf: Pdf = printer.print(printOptions)
    val content = pdf.content
  
```

# 7 - Virtual Authenticator

```java
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L55-L61)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L48-55)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L40-L46)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setHasUserVerification(true);
    options.setIsUserConsenting(true);
    options.setTransport(Transport['USB']);
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    assert(Object.keys(options).length === 6);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticatorOptions.spec.js#L11-L17)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticatorOptions.spec.js

```js
const {VirtualAuthenticatorOptions, Transport, Protocol} = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')


describe('Virtual authenticator options', function () {
  let options;

  it('Virtual options', async function () {
    options = new VirtualAuthenticatorOptions();
    options.setIsUserVerified(true);
    options.setHasUserVerification(true);
    options.setIsUserConsenting(true);
    options.setTransport(Transport['USB']);
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    assert(Object.keys(options).length === 6);
  });

  it('User verified', async function () {
    options.setIsUserVerified(true);

    assert(options.toDict()['isUserVerified']);
  });
});
```

```java
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L68-L73)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L63-71)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L53-L58)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L51-L55)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L86)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#80-86)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L68-L74)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L62-L63)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L100-L103)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#103-107)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L89-L97)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L80-L94)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L143-L145)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L145-148)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L140-L147)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L136-L140)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L137-L146)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L139-150)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.add_credential(credential)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L150)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L131-L142)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L157-L171)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L162-178)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    credential_list = driver.get_credentials()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L183)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L154-L170)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

## Remove Credential

Remove a credencial do autenticador baseado na id da credencial passado.

```cs
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L189-198)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

*
*
*
*
*
*

```java
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L181-L190)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.remove_credential(credential.id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L209)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```java
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L196-L205)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L207-216)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.remove_all_credentials()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L239)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L181-L190)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L211-L212)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L224-225)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L245-L247)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setIsUserVerified(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L197-L197)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

----
url: https://www.selenium.dev/documentation/grid/components/
----

# Selenium Grid Components

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/discouraged/http_response_codes/
----

# Códigos de respostas HTTP

Para algumas configurações de navegador no Selenium RC, Selenium atuou como um proxy entre o navegador e o site sendo automatizado. Isso significa que todo o tráfego do navegador que passou pelo Selenium poderia ser capturado ou manipulado. O método `captureNetworkTraffic()` pretendia capturar todo o tráfego de rede entre o navegador e o site sendo automatizado, incluindo códigos de resposta HTTP.

Selenium WebDriver é uma abordagem completamente diferente para a automação do navegador, preferindo agir mais como um usuário. Isso é representado na maneira como você escreve testes com o WebDriver. Em testes funcionais automatizados, verificar o código de status não é um detalhe particularmente importante da falha de um teste; as etapas que o precederam são mais importantes.

O navegador sempre representará o código de status HTTP, imagine, por exemplo, uma página de erro 404 ou 500. Uma maneira simples de “falhar rapidamente” quando você encontrar uma dessas páginas de erro é verificar o título da página ou o conteúdo de um ponto confiável (por exemplo, a tag `<h1>`) após cada carregamento de página. Se você estiver usando o modelo de objeto de página, você pode incluir esta verificação em seu construtor de classe ou ponto semelhante onde o carregamento da página é esperado. Ocasionalmente, o código HTTP pode até ser representado na página de erro do navegador e você pode usar o WebDriver para ler isso e melhorar sua saída de depuração.

Verificar se a própria página da web está alinhada com a prática ideal do WebDriver de representar a visão do usuário do site.

Se você insiste, uma solução avançada para capturar códigos de status HTTP é replicar o comportamento do Selenium RC usando um proxy. A API WebDriver fornece a capacidade de definir um proxy para o navegador, e há uma série de proxies que irão permitir que você manipule de forma programática o conteúdo das solicitações enviadas e recebidas do servidor da web. Usar um proxy permite que você decida como deseja responder para códigos de resposta de redirecionamento. Além disso, nem todo navegador torna os códigos de resposta disponíveis para WebDriver, então optar por usar um proxy permite que você tenha uma solução que funciona para todos os navegadores.

----
url: https://www.selenium.dev/documentation/webdriver/drivers/service/
----

# Driver Service Class

```java
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L15-L16)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

**Note**: Java Service classes only allow values to be set during construction with a Builder pattern.

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L5-L6)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

**Note**: Python Service classes only allow values to be set as arguments to the constructor.

```cs
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L14-L15)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

**Note**: .NET Service classes allow values to be set as properties.

```rb
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L14-L15)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

```java
    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L25-L26)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(executable_path=chromedriver_bin)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L15)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```cs
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L23)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
    service.executable_path = driver_path
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L26)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

```java
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L33)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(port=1234)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L23)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            service.Port = 1234;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L32)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
    service.port = 1234
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L33)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/troubleshooting/errors/driver_location/
----

# Unable to Locate Driver Error

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.bash_profile
source ~/.bash_profile
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Terminal and execute:

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.zshenv
source ~/.zshenv
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Command Prompt and execute:

```shell
echo %PATH%
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
setx PATH "%PATH%;C:\WebDriver\bin"
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver.exe --version
```

| Navegador         | OS Suportado                   | Mantido por      | Download                                                                     | Rastreador de Problemas                                             |
| ----------------- | ------------------------------ | ---------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| Chromium/Chrome   | Windows/macOS/Linux            | Google           | [Downloads](//chromedriver.chromium.org/downloads)                           | [Problemas](//bugs.chromium.org/p/chromedriver/issues/list)         |
| Firefox           | Windows/macOS/Linux            | Mozilla          | [Downloads](//github.com/mozilla/geckodriver/releases)                       | [Problemas](//github.com/mozilla/geckodriver/issues)                |
| Edge              | Windows/macOS/Linux            | Microsoft        | [Downloads](//developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/) | [Problemas](https://github.com/MicrosoftDocs/edge-developer/issues) |
| Internet Explorer | Windows                        | Projeto Selenium | [Downloads](/downloads)                                                      | [Problemas](//github.com/SeleniumHQ/selenium/labels/D-IE)           |
| Safari            | macOS High Sierra e superiores | Apple            | Integrado no Sistema                                                         | [Problemas](//bugreport.apple.com/logon)                            |

Nota: O Opera driver já não inclui as funcionalidades mais recentes do Selenium e oficialmente deixou de ser suportado.

----
url: https://www.selenium.dev/ja/documentation/webdriver/interactions/virtual_authenticator/
----

# Virtual Authenticator

```java
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L55-L61)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L48-55)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L40-L46)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setHasUserVerification(true);
    options.setIsUserConsenting(true);
    options.setTransport(Transport['USB']);
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    assert(Object.keys(options).length === 6);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticatorOptions.spec.js#L11-L17)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticatorOptions.spec.js

```js
const {VirtualAuthenticatorOptions, Transport, Protocol} = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')


describe('Virtual authenticator options', function () {
  let options;

  it('Virtual options', async function () {
    options = new VirtualAuthenticatorOptions();
    options.setIsUserVerified(true);
    options.setHasUserVerification(true);
    options.setIsUserConsenting(true);
    options.setTransport(Transport['USB']);
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    assert(Object.keys(options).length === 6);
  });

  it('User verified', async function () {
    options.setIsUserVerified(true);

    assert(options.toDict()['isUserVerified']);
  });
});
```

```java
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L68-L73)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L63-71)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L53-L58)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L51-L55)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L86)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#80-86)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L68-L74)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L62-L63)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L100-L103)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#103-107)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L89-L97)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L80-L94)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L143-L145)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L145-148)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L140-L147)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L136-L140)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L137-L146)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L139-150)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.add_credential(credential)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L150)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L131-L142)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L157-L171)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L162-178)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    credential_list = driver.get_credentials()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L183)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L154-L170)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

## Remove Credential

Removes a credential from the authenticator based on the passed credential id.

```cs
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L189-198)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

*
*
*
*
*
*

```java
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L181-L190)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.remove_credential(credential.id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L209)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```java
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L196-L205)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L207-216)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.remove_all_credentials()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L239)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L181-L190)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L211-L212)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L224-225)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L245-L247)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setIsUserVerified(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L197-L197)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

----
url: https://www.selenium.dev/_print/documentation/webdriver/bidi/w3c/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/webdriver/bidi/w3c/).

# BiDirectional API (W3C compliant)

Examples of working with Chrome DevTools Protocol in Selenium. CDP support is temporary until WebDriver BiDi has been implemented.

* 1: [Browsing Context](#pg-8924bec7dc6789b5c246bd77e6d006df)
* 2: [Input](#pg-bf9dadd6ca94db693da2b1ca388c61ce)
* 3: [Log](#pg-2f60b4365d2be630ef6f61c8d06c9d74)
* 4: [Network](#pg-cadb64accb52071728c1a560cf50c867)
* 5: [Script](#pg-a4331298926b3ed7226747c8cbe3c273)

The following list of APIs will be growing as the [WebDriver BiDirectional Protocol](https://w3c.github.io/webdriver-bidi/) 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](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=\&template=feature.md).

# 1 - Browsing Context

```java
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L44-L47)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L33-L35)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

    @Test
    void testNavigateToAUrl() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L58-L61)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L48-L50)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L37-L41)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L25-L28)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L50-L55)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L40-L43)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        Assertions.assertNotNull(browsingContext.getId());
        Assertions.assertNotNull(info.getNavigationId());
        Assertions.assertTrue(info.getUrl().contains("/bidi/logEntryAdded.html"));
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L64-L69)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L55-L58)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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"));
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L72-L80)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L67)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L83-L92)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L79-L82)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        Assertions.assertTrue(info.getChildren().get(0).getUrl().contains("formPage.html"));
    }

    @Test
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L95-L108)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    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()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L90-L96)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    }

    @Test
    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());
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L111-L123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L103-L109)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window2.close();

        Assertions.assertThrows(BiDiException.class, window2::getTree);
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L126-L133)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.20.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.20.0.0)

```js
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L426-L431)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext tab2 = new BrowsingContext(driver, WindowType.TAB);

        tab2.close();

        Assertions.assertThrows(BiDiException.class, tab2::getTree);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L136-L153)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L115-L118)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L157-L161)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L192-L194)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```js
    await window1.activate()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L204)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L169-L173)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.reload(undefined, 'complete')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L351)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    @Test
    void testDismissUserPromptWithText() {
        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";
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L220-L228)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.handleUserPrompt(true, userText)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L301)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        driver.get("https://www.selenium.dev/selenium/web/coordinates_tests/simple_page.html");

        WebElement element = driver.findElement(By.id("box"));
        Rectangle elementRectangle = element.getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L248-L252)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const response = await browsingContext.captureScreenshot()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L362)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    }

    @Test
    void textCaptureElementScreenshot() {
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L259-L268)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L165-L169)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L275-L280)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const response = await browsingContext.captureElementScreenshot(elementId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L184)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L304-L307)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.setViewport(250, 300)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L335)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L317-L322)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    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'],
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L145-L157)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        wait.until(visibilityOfElementLocated(By.id("imageButton"))).submit();
        wait.until(titleIs("We Arrive Here"));

        browsingContext.back();
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L330-L336)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.back()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L396)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L342-L352)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.forward()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L420)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L359-L365)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.traverseHistory(-1)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L378)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L34-L41)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L23-L28)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L54-L63)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L53-L62)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L81-88)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L70-L78)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L97-104)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L113-123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L86-L97)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L113-123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L150-163)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L170-L181)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0.0)

```js
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L105-L113)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

[Add Example](/documentation/about/contributing/#creating-examples)

# 2 - Input

```java
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ActionsTest.java#L41-L44)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ActionsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Input;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.interactions.Actions;

class ActionsTest extends BaseTest {
    private Input input;

    private String windowHandle;

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        windowHandle = driver.getWindowHandle();
        input = new Input(driver);
    }

    @Test
    void canPerformInputActions() {
        driver.get("https://www.selenium.dev/selenium/web/formSelectionPage.html");

        List<WebElement> options = driver.findElements(By.tagName("option"));

        Actions actions = new Actions(driver);
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());

        WebElement showButton = driver.findElement(By.name("showselected"));
        showButton.click();

        WebElement resultElement = driver.findElement(By.id("result"));
        Assertions.assertTrue(resultElement.getText().contains("roquefort parmigiano cheddar"));
        }

    @Test
    void canPerformReleaseAction() {
        driver.get("https://www.selenium.dev/selenium/web/bidi/release_action.html");

        WebElement inputTextBox = driver.findElement(By.id("keys"));

        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);

        List<Map<String, Object>> events =
                (List<Map<String, Object>>)
                        ((JavascriptExecutor) driver).executeScript("return allEvents.events");
        Assertions.assertEquals("KeyB", events.get(0).get("code"));
        Assertions.assertEquals("KeyA", events.get(1).get("code"));
        }
    }
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/input.spec.js#L27-L29)

##### /examples/javascript/test/bidirectional/input.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, Key, Builder} = require("selenium-webdriver")
const Input = require('selenium-webdriver/bidi/input')

describe('Input module', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can perform input action', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/formSelectionPage.html')

    let options = await driver.findElements(By.tagName('option'))

    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)

    let showButton = await driver.findElement(By.name('showselected'))
    showButton.click()

    let resultElement = await driver.findElement(By.id('result'))
    await resultElement.getText().then(function (text) {
      assert(text.includes('oquefort parmigiano cheddar'), `text is: ${text}`)
    })
  })

  it('can execute release in browsing context', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/bidi/release_action.html')

    let inputTextBox = await driver.findElement(By.id('keys'))

    await driver.executeScript('arguments[0].focus()', inputTextBox)

    const actions = driver.actions().keyDown('a').keyDown('b').getSequences()

    await input.perform(browsingContextId, actions)

    await driver.executeScript('resetEvents()')

    await input.release(browsingContextId)

    const events = await driver.executeScript('return allEvents.events')

    assert.strictEqual(events[0].code, 'KeyB')
    assert.strictEqual(events[1].code, 'KeyA')
  })
})
```

```java
        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ActionsTest.java#L59-L65)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ActionsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Input;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.interactions.Actions;

class ActionsTest extends BaseTest {
    private Input input;

    private String windowHandle;

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        windowHandle = driver.getWindowHandle();
        input = new Input(driver);
    }

    @Test
    void canPerformInputActions() {
        driver.get("https://www.selenium.dev/selenium/web/formSelectionPage.html");

        List<WebElement> options = driver.findElements(By.tagName("option"));

        Actions actions = new Actions(driver);
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());

        WebElement showButton = driver.findElement(By.name("showselected"));
        showButton.click();

        WebElement resultElement = driver.findElement(By.id("result"));
        Assertions.assertTrue(resultElement.getText().contains("roquefort parmigiano cheddar"));
        }

    @Test
    void canPerformReleaseAction() {
        driver.get("https://www.selenium.dev/selenium/web/bidi/release_action.html");

        WebElement inputTextBox = driver.findElement(By.id("keys"));

        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);

        List<Map<String, Object>> events =
                (List<Map<String, Object>>)
                        ((JavascriptExecutor) driver).executeScript("return allEvents.events");
        Assertions.assertEquals("KeyB", events.get(0).get("code"));
        Assertions.assertEquals("KeyA", events.get(1).get("code"));
        }
    }
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await input.release(browsingContextId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/input.spec.js#L55)

##### /examples/javascript/test/bidirectional/input.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, Key, Builder} = require("selenium-webdriver")
const Input = require('selenium-webdriver/bidi/input')

describe('Input module', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can perform input action', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/formSelectionPage.html')

    let options = await driver.findElements(By.tagName('option'))

    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)

    let showButton = await driver.findElement(By.name('showselected'))
    showButton.click()

    let resultElement = await driver.findElement(By.id('result'))
    await resultElement.getText().then(function (text) {
      assert(text.includes('oquefort parmigiano cheddar'), `text is: ${text}`)
    })
  })

  it('can execute release in browsing context', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/bidi/release_action.html')

    let inputTextBox = await driver.findElement(By.id('keys'))

    await driver.executeScript('arguments[0].focus()', inputTextBox)

    const actions = driver.actions().keyDown('a').keyDown('b').getSequences()

    await input.perform(browsingContextId, actions)

    await driver.executeScript('resetEvents()')

    await input.release(browsingContextId)

    const events = await driver.executeScript('return allEvents.events')

    assert.strictEqual(events[0].code, 'KeyB')
    assert.strictEqual(events[1].code, 'KeyA')
  })
})
```

[Add Example](/documentation/about/contributing/#creating-examples)

# 3 - Log

```java
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L33-L39)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/logInspector.spec.js#L23-37)

##### /examples/javascript/test/bidirectional/logInspector.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const LogInspector = require('selenium-webdriver/bidi/logInspector');
const {Builder} = require("selenium-webdriver");


describe('Log Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test listen to console log', async function () {
    let logEntry = null
    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)

    await inspector.close()
  })

  it('test listen to javascript error log', async function () {
    let logEntry = null
    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')

    await inspector.close()
  })

  it('test retrieve stack trace for a log', async function () {
    let logEntry = null
    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()

    const stackTrace = logEntry.stackTrace
    assert.notEqual(stackTrace, null)
    assert.equal(stackTrace.callFrames.length, 3)

    await inspector.close()
  })

  it('test listen to logs with multiple consumers', async function () {
    let logEntry1 = null
    let logEntry2 = null
    const inspector = await LogInspector(driver)
    await inspector.onJavascriptException(function (log) {
      logEntry1 = log
    })
    await inspector.onJavascriptException(function (log) {
      logEntry2 = log
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    await driver.findElement({id: 'jsException'}).click()

    assert.equal(logEntry1.text, 'Error: Not working')
    assert.equal(logEntry1.type, 'javascript')
    assert.equal(logEntry1.level, 'error')

    assert.equal(logEntry2.text, 'Error: Not working')
    assert.equal(logEntry2.type, 'javascript')
    assert.equal(logEntry2.level, 'error')

    await inspector.close()
  })
})
```

```java
            logInspector.onJavaScriptException(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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L73-L78)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/logInspector.spec.js#L44-54)

##### /examples/javascript/test/bidirectional/logInspector.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const LogInspector = require('selenium-webdriver/bidi/logInspector');
const {Builder} = require("selenium-webdriver");


describe('Log Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test listen to console log', async function () {
    let logEntry = null
    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)

    await inspector.close()
  })

  it('test listen to javascript error log', async function () {
    let logEntry = null
    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')

    await inspector.close()
  })

  it('test retrieve stack trace for a log', async function () {
    let logEntry = null
    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()

    const stackTrace = logEntry.stackTrace
    assert.notEqual(stackTrace, null)
    assert.equal(stackTrace.callFrames.length, 3)

    await inspector.close()
  })

  it('test listen to logs with multiple consumers', async function () {
    let logEntry1 = null
    let logEntry2 = null
    const inspector = await LogInspector(driver)
    await inspector.onJavascriptException(function (log) {
      logEntry1 = log
    })
    await inspector.onJavascriptException(function (log) {
      logEntry2 = log
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    await driver.findElement({id: 'jsException'}).click()

    assert.equal(logEntry1.text, 'Error: Not working')
    assert.equal(logEntry1.type, 'javascript')
    assert.equal(logEntry1.level, 'error')

    assert.equal(logEntry2.text, 'Error: Not working')
    assert.equal(logEntry2.type, 'javascript')
    assert.equal(logEntry2.level, 'error')

    await inspector.close()
  })
})
```

```java
            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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L55-L60)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

# 4 - Network

```java
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L36-L38)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    assert.notEqual(intercept, null)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L29)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L46-L50)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L34-L35)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                    responseDetails ->
                            network.continueWithAuth(
                                    responseDetails.getRequest().getRequestId(),
                                    new UsernameAndPassword("admin", "admin")));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L57-L64)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L42-L46)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                            // Does not handle the alert
                            network.continueWithAuthNoCredentials(responseDetails.getRequest().getRequestId()));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L74-L80)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L56-L60)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                            network.cancelAuth(responseDetails.getRequest().getRequestId()));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L90-L96)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L71-L75)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
            }
    }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L104-L108)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L30-L35)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L23-L29)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L45-L51)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L82-L88)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L62-L68)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L96-L102)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L101-L106)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

# 5 - Script

```java
        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));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L52-L75)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L32-L53)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L201-L210)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L202-L204)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L219-L229)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L222-L227)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L239-L242)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L237-L239)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L280-L283)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L279-L283)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L293-L299)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L292-L299)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            script.disownBrowsingContextScript(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L322-L322)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    await manager.disownBrowsingContextScript(id, boxId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L330-L330)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            script.disownRealmScript(realmId, List.of(boxId));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L375-L375)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    await manager.disownRealmScript(realmId, boxId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L372-L372)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L391-L392)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L383-L385)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L401-402)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L393-L395)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L411-412)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L403-L405)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L422-423)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L416-L416)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L463-463)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L424-L426)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
                script.removePreloadScript(id);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L486-486)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    await manager.removePreloadScript(scriptId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L471-L471)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L37-L51)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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,
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L26-L43)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L58-L68)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L52-L65)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L75-L85)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.19](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.19.0)

```js
    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()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L73-L86)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

----
url: https://www.selenium.dev/pt-br/documentation/legacy/selenium_2/upgrading/
----

# Migrando do RC para WebDriver

```java
Selenium selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.yoursite.com");
selenium.start();
```

Isso deve ser substituído assim:

```java
WebDriver driver = new FirefoxDriver();
Selenium selenium = new WebDriverBackedSelenium(driver, "http://www.yoursite.com");
```

## Próximos passos

Depois que seus testes forem executados sem erros, a próxima etapa é migrar o código de teste real para usar as APIs WebDriver. Dependendo de quão bem você abstrair o seu código, pode ser um processo curto ou longo. Em ambos os casos, a abordagem é a mesma e pode ser resumida simplesmente: modifique o código para usar a nova API quando for editá-lo.

Se você precisar extrair a implementação WebDriver subjacente da instância Selenium, você pode simplesmente fazer um cast para WrapsDriver:

```java
WebDriver driver = ((WrapsDriver) selenium).getWrappedDriver();
```

Isso permite que você continue passando a instância Selenium como normal, mas desembrulhar a instância do WebDriver conforme necessário.

Em algum ponto, sua base de código usará principalmente as APIs mais recentes. Neste ponto, você pode inverter o relacionamento, usando WebDriver em tudo e instanciar uma instância do Selenium sob demanda:

```java
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);
```

## Problemas comuns

Felizmente, você não é a primeira pessoa a passar por essa migração, então, aqui estão alguns problemas comuns que outras pessoas viram e como resolvê-los.

### Clicar e digitar são mais completos

Um padrão comum em um teste de Selenium RC é ver algo como:

```java
selenium.type("name", "exciting tex");
selenium.keyDown("name", "t");
selenium.keyPress("name", "t");
selenium.keyUp("name", "t");
```

```java
Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(30));
WebElement element= wait.until(visibilityOfElementLocated(By.id("some_id")));
```

Onde “visibilityOfElementLocated” é implementado como:

```java
public ExpectedCondition<WebElement> visibilityOfElementLocated(final By locator) {
  return new ExpectedCondition<WebElement>() {
    public WebElement apply(WebDriver driver) {
      WebElement toReturn = driver.findElement(locator);
      if (toReturn.isDisplayed()) {
        return toReturn;
      }
      return null;
    }
  };
}
```

Isso pode parecer complexo, mas é quase todo um código padrão. O único interessante é que a “condição esperada” será avaliada repetidamente até que o método “apply” retorne algo que não seja “null” nem Boolean.FALSE.

Claro, adicionar todas essas chamadas de “wait” pode confundir seu código. E se esse é o caso, e suas necessidades são simples, considere usar as esperas implícitas:

```java
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
```

```java
String name = selenium.getEval(
    "selenium.browserbot.findElement('id=foo', browserbot.getCurrentWindow()).tagName");
```

se torna:

```java
WebElement element = driver.findElement(By.id("foo"));
String name = (String) ((JavascriptExecutor) driver).executeScript(
    "return arguments[0].tagName", element);
```

Observe como a variável “element” passada aparece como o primeiro item na array de “arguments” padrão do JS.

### A execução de Javascript não retorna nada

O JavascriptExecutor do WebDriver envolverá todo o JS e o avaliará como uma expressão anônima. Isso significa que você precisa usar a palavra-chave “return”:

```java
String title = selenium.getEval("browserbot.getCurrentWindow().document.title");
```

se torna:

```java
((JavascriptExecutor) driver).executeScript("return document.title;");
```

----
url: https://www.selenium.dev/zh-cn/documentation/selenium_manager/
----

# Selenium Manager (测试版)

Selenium Manager 是一个用 Rust 语言实现的命令行工具, 为 Selenium 提供了自动化的驱动程序和浏览器管理功能. Selenium 默认绑定使用此工具, 因此您无需下载它, 也不需要在代码中添加任何内容或执行其他操作即可使用它.

## 动机

***简而言之:*** *Selenium Manager 是 Selenium 项目的官方驱动程序管理器, 并且在每次 Selenium 发布时都会随附提供.*

Selenium 利用每个浏览器实现的原生支持来执行自动化流程. 因此, Selenium 用户需要在使用 Selenium API 的脚本和浏览器之间放置一个名为 *驱动程序*(如 chromedriver、geckodriver、msedgedriver 等)的组件. 多年来, 管理这些驱动程序, 对Selenium 用户来说, 一直是个繁琐手动过程. 他们必须下载浏览器所需的驱动程序(如 Chrome 的 chromedriver、Firefox 的 geckodriver 等), 并将其放置在 `PATH` 中或以系统属性的形式导出驱动程序路径(如 Java、JavaScript 等). 但这种过程很麻烦, 导致了可维护性问题.

让我们来看一个例子. 假设您手动下载了用于通过 Selenium 驱动 Chrome 的所需 chromedriver. 在执行此操作时, Chrome 的稳定版本是 113, 所以您下载了 chromedriver 113 并将其放在您的 `PATH` 中. 此时, 您的 Selenium 脚本执行正确. 但 *问题* 在于 Chrome 是 *保持更新* 的. 这指的是 Chrome 能够在有新版本可用时自动且静默地升级到下一个稳定版本. 此功能对终端用户来说很棒, 但对浏览器自动化来说可能很危险. 让我们回到这个例子来明确这一点. 当您本地的 Chrome 最终更新到了 115 版本. 此时, 由于手动下载的驱动程序(113 版)与 Chrome 版本(115 版)不兼容, 您的 Selenium 脚本出错了. 因此, 您的 Selenium 脚本会因以下错误消息而失败: *“会话无法创建: 此版本的 ChromeDriver 仅支持 Chrome 版本 113”*.

这个问题是所谓的驱动管理器(例如 Java 的 [WebDriverManager](https://bonigarcia.dev/webdrivermanager/) 、 Python 的 [webdriver-manager](https://pypi.org/project/webdriver-manager/) 、 JavaScript 的 [webdriver-manager](https://www.npmjs.com/package/webdriver-manager) 、 C# 的 [WebDriverManager.Net](https://github.com/rosolko/WebDriverManager.Net) 以及 Ruby 的 [webdrivers](https://github.com/titusfortner/webdrivers) 存在的主要原因. 所有这些项目都是一种启示, 也清楚地表明社区需要将此功能内置到 Selenium 中. 因此, Selenium 项目创建了 *Selenium Manager*, 这是 Selenium 的官方驱动管理器, 从 4.6 版本开始, 它随每个 Selenium 发行版一起提供.

## 用法

***简而言之:*** *当驱动程序(如 ChromeDriver、GeckoDriver 等)不可用时, Selenium 绑定会使用 Selenium Manager.*

通过 Selenium Manager 进行驱动程序管理是 Selenium 绑定的 *可选功能* . 因此, 用户可以继续手动管理其驱动程序(将驱动程序放在 `PATH` 中或使用系统属性), 也可以依靠第三方 *驱动程序管理器* 自动完成. Selenium Manager 仅作为备用方案: 如果未提供驱动程序, Selenium Manager 将会介入.

Selenium Manager 是一个用 Rust 语言实现的命令行界面(CLI)工具, 可于 Windows、Linux 和 macOS 等多种操作系统上跨平台运行. Selenium Manager 的二进制文件随每个 Selenium 版本一起发布. 这样, 每个 Selenium 绑定语言都会调用 Selenium Manager 来执行以下各节中所述的自动化驱动程序和浏览器管理.

## Automated driver management 自动驱动管理

***简而言之:*** *当所需驱动程序不可用时, Selenium Manager 会自动寻找、下载并缓存 Selenium 所需的驱动程序.*

Selenium Manager 的主要特性被称为 *自动驱动管理* . 让我们通过一个例子来理解它. 假设我们想用 Selenium 驱动 Chrome(请参阅关于如何[使用Selenium启动会话](https://www.selenium.dev/documentation/webdriver/getting_started/first_script/#1-start-the-session)的文档). 在会话开始之前, 如果驱动程序不可用, Selenium Manager 会为我们管理 chromedriver. 我们用 *管理* 这个词来描述此功能(而不仅仅是 *下载* ), 因为这个过程更广泛, 包含不同的步骤:

1. 探索浏览器版本. Selenium Manager 会发现执行 Selenium 的机器上安装的浏览器版本(例如, Chrome、Firefox、Edge). 此步骤使用 shell 命令(例如, `google-chrome --version` ).
2. 寻找驱动程序版本. 通过探索过的浏览器版本, 确定合适的驱动程序版本. 在此步骤中, 使用由浏览器供应商维护的在线元数据/端点(例如, [chromedriver](https://chromedriver.chromium.org/downloads), [geckodriver](https://github.com/mozilla/geckodriver/releases), 或 [msedgedriver](https://developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/)).
3. 驱动下载. 通过解析出的驱动程序版本获取驱动程序的 URL；利用该 URL 下载驱动程序文件, 解压后将其存储在本地.
4. 驱动程序缓存. 未压缩的驱动程序二进制文件存储在本地缓存文件夹( `~/.cache/selenium` )中. 下次需要相同的驱动程序时, 如果该驱动程序已在缓存中, 则将从那里使用.

## 自动化浏览器管理

***简而言之:*** *当本地系统未安装 Selenium 驱动的浏览器(Chrome、Firefox 和 Edge)时, Selenium Manager 会自动发现、下载并缓存这些浏览器.*

从 Selenium 4.11.0 版本开始, Selenium Manager 还实现了 *自动浏览器管理*. 借助此功能, Selenium Manager 能够发现、下载并缓存不同浏览器的版本, 使其能够无缝地供 Selenium 使用. 在内部, Selenium Manager 使用了与前一节所述类似的管理流程, 但这次是针对浏览器版本的.

Selenium Manager 自动管理的浏览器有:

* Chrome浏览器, 基于 [Chrome for Testing (CfT)](https://googlechromelabs.github.io/chrome-for-testing/), 自 Selenium 4.11.0 版本起.
* 火狐浏览器. 基于[public Firefox releases](https://ftp.mozilla.org/pub/firefox/releases/), 自 Selenium 4.12.0 版本.
* Edge浏览器, 基于 [Edge downloads](https://www.microsoft.com/en-us/edge/download), 自 Selenium 4.14.0 版本.

让我们再次考虑用 Selenium 驱动 Chrome 的典型示例. 这一次, 假设在[启动新会话](https://www.selenium.dev/documentation/webdriver/getting_started/first_script/#1-start-the-session)时本地机器上未安装 Chrome. 在这种情况下, Selenium Manager会发现、下载并缓存当前的稳定版 Chrome 浏览器(在 `~/.cache/selenium/chrome` 中).

但不仅如此. 除了稳定的浏览器版本, Selenium Manager 还允许下载旧版浏览器(对于 Chrome for Testing 而言, 从 113 版本开始, 这是作为 Chrome for Testing 发布的第一个版本). 要使用 Selenium 设置浏览器版本, 我们使用一个名为 [browserVersion](https://www.selenium.dev/documentation/webdriver/drivers/options/#browserversion) 的浏览器选项.

让我们考虑另一个简单的例子. 假设我们使用 [Chrome options](https://www.selenium.dev/documentation/webdriver/browsers/chrome/) 将 `browserVersion` 设置为 `114` . 在这种情况下, Selenium Manager会检查是否已安装 Chrome 114 版本. 如果已安装, 就会使用它. 如果没有安装, Selenium Manager会进行管理(即发现、下载并缓存)Chrome 114 版本. 无论哪种情况, chromedriver 也会被管理. 最后, Selenium 会像往常一样启动 Chrome 以实现程序化驱动.

但还有更多. 除了固定的浏览器版本(例如, `113`, `114`, `115` 等), 我们还可以为 `browserVersion` 使用以下标签:

* `stable`: 当前 CfT 版本.
* `beta`: 下一个稳定版.
* `dev`: 当前正在开发的版本.
* `canary`: 面向开发者的夜间构建版本.
* `esr`: 扩展支持版本(仅适用于 Firefox 浏览器).

当指定了这些标签时, Selenium Manager首先会检查给定的浏览器是否已安装( `beta`, `dev` 等), 如果未检测到, 则会自动管理该浏览器.

### Windows中的Edge

在 Windows 系统中, Selenium Manager 对 Edge 的自动化边缘管理与其他浏览器有所不同. 对于 Chrome 和 Firefox(以及 macOS 和 Linux 系统中的 Edge), Selenium Manager 会自动将其下载到本地缓存( `~/.cache/selenium` ). 然而, 在 Windows 系统中, Edge 却无法实现同样的操作. 原因在于 Windows 版本的 Edge 安装程序是以微软安装程序(MSI)文件的形式分发的, 需要以管理员权限执行. 因此, 当在 Windows 系统中使用非管理员权限会话通过 Selenium Manager 安装 Edge 时, Selenium Manager 会显示如下警告信息:

```
edge can only be installed in Windows with administrator permissions
```

因此, 通过 Selenium Manager 在 Windows 系统中自动安装 Edge 浏览器需要管理员权限, 并且 Edge 最终会被安装在通常的程序文件夹中(例如 `C:\Program Files (x86)\Microsoft\Edge` ).

## 数据收集

Selenium Manager会向 [Plausible](https://plausible.io/manager.selenium.dev) 报送匿名使用[statistics](https://plausible.io/privacy-focused-web-analytics) 数据. 这能让 Selenium 团队更深入地了解 Selenium 的使用情况, 从而更好地集中我们的开发精力. 所收集的数据包括:

| Data                          | Purpose                                                    |
| ----------------------------- | ---------------------------------------------------------- |
| Selenium 版本                   | 这使得 Selenium 开发人员能够安全地弃用和移除功能, 并确定哪些新功能可能对您可用.             |
| 语言绑定                          | 用于执行 Selenium 脚本的编程语言(Java、JavaScript、Python、.Net、Ruby)    |
| Selenium Manager 正在运行的操作系统和架构 | Selenium 开发人员可以利用这些信息来帮助确定错误报告的优先级, 并识别是否存在系统性的与操作系统相关的故障. |
| 浏览器及浏览器版本                     | 协助确定错误报告的优先级                                               |
| 大致地理位置                        | 根据您连接的 IP 地址得出. 这有助于我们确定需要在哪些地区集中文档编写工作.                   |

Selenium Manager 每天会将这些数据发送给 Plausible 一次. 此周期基于 TTL 值(请参阅[configuration](https://www.selenium.dev/documentation/selenium_manager/#configuration)).

### 选择退出数据收集

**默认情况下会收集数据.** 若要禁用数据收集, 请将 `SE_AVOID_STATS` 环境变量设置 `true`. 您也可以在配置文件中(见下文)通过设置 `avoid-stats = true` 来禁用数据收集.

## 配置

***简而言之:*** *对于大多数用户而言, Selenium Manager 应该能静默且透明地运行. 不过, 在某些场景下(例如指定自定义缓存路径或全局设置代理), 可能需要自定义配置.*

Selenium Manager 是一个命令行界面(CLI)工具. 因此, 在底层, Selenium 绑定通过调用 shell 命令来调用 Selenium Manager. 和任何其他 CLI 工具一样, 可以使用参数来指定 Selenium Manager 中的特定功能. 要查看 Selenium Manager 支持的不同参数, 可以运行以下命令:

```
$ ./selenium-manager --help
```

除了命令行参数之外, Selenium Manager 还支持两种额外的配置机制:

* 配置文件. Selenium Manager使用位于 Selenium 缓存中的一个名为 `se-config.toml` 的文件(默认情况下位于 `~/.cache/selenium` )来存储自定义配置值. 此 TOML 文件包含用于自定义配置的键值集合.
* 环境变量. 每个配置键在环境变量中都有对应的等效项, 方法是将每个键名转换为大写, 将破折号(`-`)替换为下划线(`_`), 并在前面加上前缀`SE_`.

当存在配置文件且未指定相应的命令行参数时, Selenium Manager 会遵循该配置文件. 此外, 如果既未指定命令行参数也未提供配置文件, 则会使用环境变量. 换句话说, Selenium Manager 自定义配置的优先级顺序如下:

1. CLI参数.
2. 配置文件.
3. 环境变量.

请注意, Selenium 绑定使用命令行参数来指定配置值, 而这些配置值又在每个绑定中通过[browser options](https://www.selenium.dev/documentation/webdriver/drivers/options/)来定义.

下表总结了 Selenium Manager 支持的所有参数及其在配置文件和环境变量中的对应键.

| CLI argument                                | Configuration file                          | Env variable                               | Description                                                                                                                                                                                                                                                                             |
| ------------------------------------------- | ------------------------------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--browser BROWSER`                         | `browser = "BROWSER"`                       | `SE_BROWSER=BROWSER`                       | Browser name: `chrome`, `firefox`, `edge`, `iexplorer`, `safari`, `safaritp`, or `webview2`                                                                                                                                                                                             |
| `--driver <DRIVER>`                         | `driver = "DRIVER"`                         | `SE_DRIVER=DRIVER`                         | Driver name: `chromedriver`, `geckodriver`, `msedgedriver`, `IEDriverServer`, or `safaridriver`                                                                                                                                                                                         |
| `--browser-version <BROWSER_VERSION>`       | `browser-version = "BROWSER_VERSION"`       | `SE_BROWSER_VERSION=BROWSER_VERSION`       | Major browser version (e.g., `105`, `106`, etc. Also: `beta`, `dev`, `canary` -or `nightly`-, and `esr` -in Firefox- are accepted)                                                                                                                                                      |
| `--driver-version <DRIVER_VERSION>`         | `driver-version = "DRIVER_VERSION"`         | `SE_DRIVER_VERSION=DRIVER_VERSION`         | Driver version (e.g., `106.0.5249.61, 0.31.0`, etc.)                                                                                                                                                                                                                                    |
| `--browser-path <BROWSER_PATH>`             | `browser-path = "BROWSER_PATH"`             | `SE_BROWSER_PATH=BROWSER_PATH`             | Browser path (absolute) for browser version detection (e.g., `/usr/bin/google-chrome`, `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`, `C:\Program Files\Google\Chrome\Application\chrome.exe`)                                                                         |
| `--driver-mirror-url <DRIVER_MIRROR_URL>`   | `driver-mirror-url = "DRIVER_MIRROR_URL"`   | `SE_DRIVER_MIRROR_URL=DRIVER_MIRROR_URL`   | Mirror URL for driver repositories                                                                                                                                                                                                                                                      |
| `--browser-mirror-url <BROWSER_MIRROR_URL>` | `browser-mirror-url = "BROWSER_MIRROR_URL"` | `SE_BROWSER_MIRROR_URL=BROWSER_MIRROR_URL` | Mirror URL for browser repositories                                                                                                                                                                                                                                                     |
| `--output <OUTPUT>`                         | `output = "OUTPUT"`                         | `SE_OUTPUT=OUTPUT`                         | Output type: `LOGGER` (using `INFO`, `WARN`, etc.), `JSON` (custom JSON notation), `SHELL` (Unix-like), or `MIXED` (`INFO`, `WARN`, `DEBUG`, etc. to stderr and minimal `JSON` to stdout). Default: `LOGGER`                                                                            |
| `--os <OS>`                                 | `os = "OS"`                                 | `SE_OS=OS`                                 | Operating system for drivers and browsers (i.e., `windows`, `linux`, or `macos`)                                                                                                                                                                                                        |
| `--arch <ARCH>`                             | `arch = "ARCH"`                             | `SE_ARCH=ARCH`                             | System architecture for drivers and browsers (i.e., `x32`, `x64`, or `arm64`)                                                                                                                                                                                                           |
| `--proxy <PROXY>`                           | `proxy = "PROXY"`                           | `SE_PROXY=PROXY`                           | HTTP proxy for network connection (e.g., `myproxy:port`, `myuser:mypass@myproxy:port`)                                                                                                                                                                                                  |
| `--timeout <TIMEOUT>`                       | `timeout = TIMEOUT`                         | `SE_TIMEOUT=TIMEOUT`                       | Timeout for network requests (in seconds). Default: `300`                                                                                                                                                                                                                               |
| `--offline`                                 | `offline = true`                            | `SE_OFFLINE=true`                          | Offline mode (i.e., disabling network requests and downloads)                                                                                                                                                                                                                           |
| `--force-browser-download`                  | `force-browser-download = true`             | `SE_FORCE_BROWSER_DOWNLOAD=true`           | Force to download browser, e.g., when a browser is already installed in the system, but you want Selenium Manager to download and use it                                                                                                                                                |
| `--avoid-browser-download`                  | `avoid-browser-download = true`             | `SE_AVOID_BROWSER_DOWNLOAD=true`           | Avoid to download browser, e.g., when a browser is supposed to be downloaded by Selenium Manager, but you prefer to avoid it                                                                                                                                                            |
| `--skip-driver-in-path`                     | `skip-driver-in-path = true`                | `SE_SKIP_DRIVER_IN_PATH=true`              | Not using drivers found in the `PATH`                                                                                                                                                                                                                                                   |
| `--skip-browser-in-path`                    | `skip-browser-in-path = true`               | `SE_SKIP_BROWSER_IN_PATH=true`             | Not using browsers found in the `PATH`                                                                                                                                                                                                                                                  |
| `--debug`                                   | `debug = true`                              | `SE_DEBUG=true`                            | Display `DEBUG` messages                                                                                                                                                                                                                                                                |
| `--trace`                                   | `trace = true`                              | `SE_TRACE=true`                            | Display `TRACE` messages                                                                                                                                                                                                                                                                |
| `--cache-path <CACHE_PATH>`                 | `cache-path="CACHE_PATH"`                   | `SE_CACHE_PATH=CACHE_PATH`                 | Local folder used to store downloaded assets (drivers and browsers), local metadata, and configuration file. See next section for details. Default: `~/.cache/selenium`. For Windows paths in the TOML configuration file, double backslashes are required (e.g., `C:\\custom\\cache`). |
| `--ttl <TTL>`                               | `ttl = TTL`                                 | `SE_TTL=TTL`                               | Time-to-live in seconds. See next section for details. Default: `3600` (1 hour)                                                                                                                                                                                                         |
| `--language-binding <LANGUAGE>`             | `language-binding = "LANGUAGE"`             | `SE_LANGUAGE_BINDING=LANGUAGE`             | Language that invokes Selenium Manager (e.g., Java, JavaScript, Python, DotNet, Ruby)                                                                                                                                                                                                   |
| `--avoid-stats`                             | `avoid-stats = true`                        | `SE_AVOID_STATS=true`                      | Avoid sends usage statistics to plausible.io. Default: `false`                                                                                                                                                                                                                          |

除了前面表格中指定的配置键之外, 还有一些特殊情况, 即:

* 浏览器版本. 除了 `browser-version` 之外, 我们还可以使用特定的配置键为每个受支持的浏览器指定自定义版本. 这样, 键 `chrome-version`, `firefox-version`, `edge-version` 等就得到了支持. 环境变量(即 `SE_CHROME_VERSION`, `SE_FIREFOX_VERSION`, `SE_EDGE_VERSION` 等)也是如此.
* 驱动程序版本. 遵循相同的模式, 我们可以在配置文件中使用 `chromedriver-version`, `geckodriver-version`, `msedgedriver-version`等, 在环境变量中使用 `SE_CHROMEDRIVER_VERSION`, `SE_GECKODRIVER_VERSION`, `SE_MSEDGEDRIVER_VERSION` 等.
* 浏览器路径. 遵循相同的模式, 我们可以在配置文件中使用 `chrome-path`, `firefox-path`, `edge-path` 等, 在环境变量中使用 `SE_CHROME_PATH`, `SE_FIREFOX_PATH`, `SE_EDGE_PATH`等. Selenium 绑定还允许使用选项指定浏览器路径的自定义位置, 例如: Chrome、Edge 或 Firefox.
* 驱动镜像. 遵循同样的模式, 我们可以在配置文件中使用 `chromedriver-mirror-url`, `geckodriver-mirror-url`, `msedgedriver-mirror-url` 等, 在环境变量中使用 `SE_CHROMEDRIVER_MIRROR_URL`, `SE_GECKODRIVER_MIRROR_URL`, `SE_MSEDGEDRIVER_MIRROR_URL` 等.
* 浏览器镜像. 遵循同样的模式, 我们可以在配置文件中使用 `chrome-mirror-url`, `firefox-mirror-url`, `edge-mirror-url` 等, 在环境变量中使用 `SE_CHROME_MIRROR_URL`, `SE_FIREFOX_MIRROR_URL`, `SE_EDGE_MIRROR_URL` 等.

### se-config.toml 示例

*

```toml
browser = "chrome"                 # --browser BROWSER
driver = "chromedriver"             # --driver DRIVER
browser-version = "106"             # --browser-version BROWSER_VERSION
driver-version = "106.0.5249.61"    # --driver-version DRIVER_VERSION
browser-path = "/usr/bin/google-chrome"  # --browser-path BROWSER_PATH
driver-mirror-url = "https://custom-driver-mirror.com"  # --driver-mirror-url DRIVER_MIRROR_URL
browser-mirror-url = "https://custom-browser-mirror.com"  # --browser-mirror-url BROWSER_MIRROR_URL
output = "LOGGER"                   # --output OUTPUT
os = "linux"                        # --os OS
arch = "x64"                        # --arch ARCH
proxy = "myproxy:8080"              # --proxy PROXY
timeout = 300                       # --timeout TIMEOUT
offline = true                      # --offline
force-browser-download = true       # --force-browser-download
avoid-browser-download = false      # --avoid-browser-download
debug = true                        # --debug
trace = true                        # --trace
cache-path = "/custom/cache/path"    # --cache-path CACHE_PATH
ttl = 3600                          # --ttl TTL
language-binding = "Python"         # --language-binding LANGUAGE
avoid-stats = true                  # --avoid-stats
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/selenium_manager/example_se-config.toml#L1-L21)

##### /examples/python/tests/selenium\_manager/example\_se-config.toml

```toml
browser = "chrome"                 # --browser BROWSER
driver = "chromedriver"             # --driver DRIVER
browser-version = "106"             # --browser-version BROWSER_VERSION
driver-version = "106.0.5249.61"    # --driver-version DRIVER_VERSION
browser-path = "/usr/bin/google-chrome"  # --browser-path BROWSER_PATH
driver-mirror-url = "https://custom-driver-mirror.com"  # --driver-mirror-url DRIVER_MIRROR_URL
browser-mirror-url = "https://custom-browser-mirror.com"  # --browser-mirror-url BROWSER_MIRROR_URL
output = "LOGGER"                   # --output OUTPUT
os = "linux"                        # --os OS
arch = "x64"                        # --arch ARCH
proxy = "myproxy:8080"              # --proxy PROXY
timeout = 300                       # --timeout TIMEOUT
offline = true                      # --offline
force-browser-download = true       # --force-browser-download
avoid-browser-download = false      # --avoid-browser-download
debug = true                        # --debug
trace = true                        # --trace
cache-path = "/custom/cache/path"    # --cache-path CACHE_PATH
ttl = 3600                          # --ttl TTL
language-binding = "Python"         # --language-binding LANGUAGE
avoid-stats = true                  # --avoid-stats
```

## 缓存

***简而言之:*** *由 Selenium Manager 管理的驱动程序和浏览器会存储在本地文件夹(`~/.cache/selenium` )中.*

Selenium Manager中的缓存是一个本地文件夹(默认为 `~/.cache/selenium` ), 用于存储下载的资源(驱动程序和浏览器). 为了提高性能, 当驱动程序或浏览器已存在于缓存中(即存在 *缓存* 提示)时, Selenium Manager会从那里使用它们.

除了已下载的驱动程序和浏览器之外, 缓存根目录中还有两个额外的文件:

* 配置文件( `se-config.toml` ). 此文件是可选的, 正如前一节所述, 它允许为 Selenium Manager 存储自定义配置值. 此文件由最终用户维护, 并由 Selenium Manager 读取.
* 元数据文件( `se-metadata.json` ). 此文件包含由 Selenium Manager通过网络请求(例如, 使用 [CfT JSON endpoints](https://github.com/GoogleChromeLabs/chrome-for-testing#json-api-endpoints))发现的版本以及它们有效的生存时间(TTL). Selenium Manager会自动维护此文件.

Selenium Manager 中的生存时间(TTL)借鉴了 DNS 的 TTL 机制, 这是一种广为人知的机制, 指的是某些值在被自动刷新之前被缓存的时长. 对于 Selenium Manager 而言, 这些值是通过网络请求获取的驱动程序和浏览器版本发现的结果. 默认情况下, TTL 为 3600 秒(即 1 小时), 并且可以通过配置值进行调整, 或者将其设置为 0 来禁用此功能.

TTL 机制是一种提升 Selenium 总体性能的方法. 它基于这样一个事实: 在短期内, 发现的驱动程序和浏览器版本(例如, 适用于 Chrome 115 的正确 chromedriver 版本是 115.0.5790.170)很可能保持不变. 因此, 发现的版本会被写入元数据文件, 并从那里读取, 而不是连续进行相同的网络请求. 这样, 在驱动程序版本发现过程中(之前介绍的自动化驱动程序管理流程的第 2 步), Selenium Manager 首先读取元数据文件. 如果找到新的解决方案(即在 TTL 期间有效的驱动程序/浏览器版本), 则使用该版本(节省了进行新网络请求的时间). 如果未找到或 TTL 已过期, 则会进行网络请求, 并将结果存储在元数据文件中.

我们来看一个例子. 一个 Selenium 绑定请求 Selenium Manager解析 chromedriver. Selenium Manager检测到已安装 Chrome 115 版本, 于是向 CfT 端点发出网络请求以确定合适的 chromedriver 版本(当时为 115.0.5790.170). 此版本会被存储在元数据文件中, 并在接下来的一小时内(TTL)被视为有效. 如果在此期间(在执行测试套件时很可能发生)再次请求 Selenium Manager解析 chromedriver, 那么将通过读取元数据文件来获取 chromedriver 版本, 而无需向 CfT 端点发出新的请求. 一小时后, 缓存中存储的 chromedriver 版本将被视为过期, Selenium Manager会通过向相应端点发出新的网络请求来刷新它.

Selenium Manager includes two additional arguments two handle the cache, namely: Selenium Manager包含两个用于处理缓存的附加参数, 分别是:

* `--clear-cache`: 要删除缓存文件夹(相当于环境变量 `SE_CLEAR_CACHE=true` ).
* `--clear-metadata` : 删除元数据文件(相当于环境变量 `SE_CLEAR_METADATA=true` ).

## 版本控制

Selenium Manager 采用与 Selenium 相同的版本命名规则. 不过, 由于 Selenium Manager 仍处于测试阶段, 因此其主版本号为 0. 例如, 与 Selenium 4.12.0 一同发布的 Selenium Manager 二进制文件对应的是 0.4.12 版本.

## 获取 Selenium Manager

对于大多数用户而言, 由于 Selenium 绑定会在内部使用 Selenium Manager, 所以无需直接与之交互. 不过, 如果您想试用 Selenium Manager 或将其用于涉及驱动程序或浏览器管理的用例, 可以通过多种方式获取 Selenium Manager 的二进制文件

* Selenium Manager的源代码存储在 Selenium 主仓库的 [rust](https://github.com/SeleniumHQ/selenium/tree/trunk/rust) 文件夹中. 此外, 您可以在 [Selenium Manager Artifacts](https://github.com/SeleniumHQ/selenium_manager_artifacts) 仓库中找到适用于 Windows、Linux 和 macOS 的编译版本. 此文件中链接了稳定版的 Selenium Manager二进制[file](https://github.com/SeleniumHQ/selenium/blob/trunk/common/selenium_manager.bzl)(即在最新稳定版 Selenium 中分发的那些).
* 在构建工作流中, Selenium Manager 是通过 [GitHub Actions workflow](https://github.com/SeleniumHQ/selenium/actions/workflows/ci-rust.yml)进行编译的. 此工作流会为 Windows、Linux 和 macOS 创建二进制文件. 您可以从这些工作流执行中下载这些二进制文件.
* 在缓存中. 自 Selenium Java 绑定的 4.15.0 版本起, Selenium Manager 二进制文件会被提取并复制到缓存文件夹中. 例如, 与 Selenium 4.15.0 一同提供的 Selenium Manager 二进制文件会存储在文件夹 `~/.cache/selenium/manager/0.4.15` 中.

## 例子

让我们来看一个典型的例子: 我们想要自动管理 chromedriver. 为此, 我们像下面这样调用 Selenium Manager (请注意, 标志 `--debug` 是可选的, 但它有助于我们理解 Selenium Manager 正在做什么):

```
$ ./selenium-manager --browser chrome --debug
DEBUG chromedriver not found in PATH
DEBUG chrome detected at C:\Program Files\Google\Chrome\Application\chrome.exe
DEBUG Detected browser: chrome 139.0.7258.67
DEBUG Discovering versions from https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json
DEBUG Required driver: chromedriver 139.0.7258.68
DEBUG Acquiring lock: C:\Users\boni\.cache\selenium\chromedriver\win64\139.0.7258.68\sm.lock
DEBUG Downloading chromedriver 139.0.7258.68 from https://storage.googleapis.com/chrome-for-testing-public/139.0.7258.68/win64/chromedriver-win64.zip
INFO  Driver path: C:\Users\boni\.cache\selenium\chromedriver\win64\139.0.7258.68\chromedriver.exe
INFO  Browser path: C:\Program Files\Google\Chrome\Application\chrome.exe
```

在这种情况下, Selenium Manager会检测到本地的 Chrome(在 Windows 系统中). 然后, 根据其版本和 CfT 端点, 会将合适的 chromedriver 版本(在此示例中为 115 版)下载到本地缓存. 最后, Selenium Manager提供两个结果: i)驱动程序路径(已下载)和 ii)浏览器路径(本地).

让我们再来看一个例子. 现在我们想要使用 Chrome 测试版. 因此, 我们调用 Selenium Manager并指定该版本标签, 如下所示(请注意, CfT 测试版会被发现、下载并存储在本地缓存中):

```
$ ./selenium-manager --browser chrome --browser-version beta --debug
DEBUG chromedriver not found in PATH
DEBUG chrome not found in PATH
DEBUG chrome beta not found in the system
DEBUG Discovering versions from https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json
DEBUG Required browser: chrome 140.0.7339.16
DEBUG Acquiring lock: C:\Users\boni\.cache\selenium\chrome\win64\140.0.7339.16\sm.lock
DEBUG Downloading chrome 140.0.7339.16 from https://storage.googleapis.com/chrome-for-testing-public/140.0.7339.16/win64/chrome-win64.zip
DEBUG chrome 140.0.7339.16 is available at C:\Users\boni\.cache\selenium\chrome\win64\140.0.7339.16\chrome.exe
DEBUG Discovering versions from https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json
DEBUG Required driver: chromedriver 140.0.7339.16
DEBUG Acquiring lock: C:\Users\boni\.cache\selenium\chromedriver\win64\140.0.7339.16\sm.lock
DEBUG Downloading chromedriver 140.0.7339.16 from https://storage.googleapis.com/chrome-for-testing-public/140.0.7339.16/win64/chromedriver-win64.zip
INFO  Driver path: C:\Users\boni\.cache\selenium\chromedriver\win64\140.0.7339.16\chromedriver.exe
INFO  Browser path: C:\Users\boni\.cache\selenium\chrome\win64\140.0.7339.16\chrome.exe
```

```java
    public void testSetupWithoutManager() {
        System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/selenium_manager/SeleniumManagerUsageDemo.java#L12-L17)

##### /examples/java/src/test/java/dev/selenium/selenium\_manager/SeleniumManagerUsageDemo.java

```java
package dev.selenium.selenium_manager;

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class SeleniumManagerUsageDemo {

    @Test
    @Disabled("This test is just for demo purposes and should not be run in CI")
    public void testSetupWithoutManager() {
        System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }

    @Test
    public void testSetupWithManager() {
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }

}
```

**Selenium Manager**

```java
    public void testSetupWithManager() {
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/selenium_manager/SeleniumManagerUsageDemo.java#L20-L24)

##### /examples/java/src/test/java/dev/selenium/selenium\_manager/SeleniumManagerUsageDemo.java

```java
package dev.selenium.selenium_manager;

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class SeleniumManagerUsageDemo {

    @Test
    @Disabled("This test is just for demo purposes and should not be run in CI")
    public void testSetupWithoutManager() {
        System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }

    @Test
    public void testSetupWithManager() {
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }

}
```

**Previously**

```py
def setup_without_selenium_manager():
    chrome_service = Service(executable_path='path/to/chrome.exe')
    driver = webdriver.Chrome(chrome_service)
    return driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/selenium_manager/usage.py#L5-L8)

##### /examples/python/tests/selenium\_manager/usage.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

def setup_without_selenium_manager():
    chrome_service = Service(executable_path='path/to/chrome.exe')
    driver = webdriver.Chrome(chrome_service)
    return driver
    
def setup_with_selenium_manager():
    driver = webdriver.Chrome()
    return driver
```

**Selenium Manager**

```py
def setup_with_selenium_manager():
    driver = webdriver.Chrome()
    return driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/selenium_manager/usage.py#L10-L12)

##### /examples/python/tests/selenium\_manager/usage.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

def setup_without_selenium_manager():
    chrome_service = Service(executable_path='path/to/chrome.exe')
    driver = webdriver.Chrome(chrome_service)
    return driver
    
def setup_with_selenium_manager():
    driver = webdriver.Chrome()
    return driver
```

```cs
        public void TestWithSeleniumManager()
        {
            // Before
            // using var driver = new ChromeDriver("path/to/chromedriver");

            // Now
            using var driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/documentation/selenium_manager/");
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/SeleniumManager/UsageTest.cs#L10-L18)

##### /examples/dotnet/SeleniumDocs/SeleniumManager/UsageTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.SeleniumManagerTest
{
    [TestClass]
    public class UsageTest
    {
        [TestMethod]
        public void TestWithSeleniumManager()
        {
            // Before
            // using var driver = new ChromeDriver("path/to/chromedriver");

            // Now
            using var driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/documentation/selenium_manager/");
        }
    }
}
```

**Previously**

```rb
def setup_without_selenium_manager
  service = Selenium::WebDriver::Chrome::Service.new(path: '/path/to/chromedriver')
  driver = Selenium::WebDriver.for(:chrome, service: service)
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/selenium_manager/usage.rb#L5-L10)

##### /examples/ruby/spec/selenium\_manager/usage.rb

```rb
# frozen_string_literal: true

require 'selenium-webdriver'

def setup_without_selenium_manager
  service = Selenium::WebDriver::Chrome::Service.new(path: '/path/to/chromedriver')
  driver = Selenium::WebDriver.for(:chrome, service: service)
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end

def setup_with_selenium_manager
  driver = Selenium::WebDriver.for(:chrome) # Selenium Manager handles the driver automatically
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end
```

**Selenium Manager**

```rb
def setup_with_selenium_manager
  driver = Selenium::WebDriver.for(:chrome) # Selenium Manager handles the driver automatically
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/selenium_manager/usage.rb#L12-L16)

##### /examples/ruby/spec/selenium\_manager/usage.rb

```rb
# frozen_string_literal: true

require 'selenium-webdriver'

def setup_without_selenium_manager
  service = Selenium::WebDriver::Chrome::Service.new(path: '/path/to/chromedriver')
  driver = Selenium::WebDriver.for(:chrome, service: service)
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end

def setup_with_selenium_manager
  driver = Selenium::WebDriver.for(:chrome) # Selenium Manager handles the driver automatically
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end
```

**Previously**

```js
  // it('Creates driver with Selenium Manager', async function () {
  //   let driverPath = '/path/to/chromedriver';
  //   let browserPath = '/path/to/chrome';

  //   options.setChromeBinaryPath(browserPath)

  //   let service = new Chrome.ServiceBuilder().setPath(driverPath)

  //   let driver = new Builder()
  //       .forBrowser(Browser.CHROME)
  //       .setChromeService(service)
  //       .build();

  //   await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  //   await driver.quit();
  // });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/selenium_manager/usage.spec.js#L16-L31)

##### /examples/javascript/test/selenium\_manager/usage.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options();

describe('Usage Test', function () {
  it('Creates driver wit Selenium Manager', async function () {

    let driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  // it('Creates driver with Selenium Manager', async function () {
  //   let driverPath = '/path/to/chromedriver';
  //   let browserPath = '/path/to/chrome';

  //   options.setChromeBinaryPath(browserPath)

  //   let service = new Chrome.ServiceBuilder().setPath(driverPath)

  //   let driver = new Builder()
  //       .forBrowser(Browser.CHROME)
  //       .setChromeService(service)
  //       .build();

  //   await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  //   await driver.quit();
  // });
});
```

**Selenium Manager**

```js
  it('Creates driver wit Selenium Manager', async function () {

    let driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/selenium_manager/usage.spec.js#L6-L14)

##### /examples/javascript/test/selenium\_manager/usage.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options();

describe('Usage Test', function () {
  it('Creates driver wit Selenium Manager', async function () {

    let driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  // it('Creates driver with Selenium Manager', async function () {
  //   let driverPath = '/path/to/chromedriver';
  //   let browserPath = '/path/to/chrome';

  //   options.setChromeBinaryPath(browserPath)

  //   let service = new Chrome.ServiceBuilder().setPath(driverPath)

  //   let driver = new Builder()
  //       .forBrowser(Browser.CHROME)
  //       .setChromeService(service)
  //       .build();

  //   await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  //   await driver.quit();
  // });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

## Selenium Grid

Selenium Manager 可让您在设置 Selenium Grid 时自动配置驱动程序. 为此, 您需要在启动 Selenium Grid 的命令中包含 `--selenium-manager true` 参数. 更多详情, 请访问 [Selenium Grid starting page](https://www.selenium.dev/documentation/grid/getting_started/).

此外, Selenium Manager 还允许自动管理 Selenium Grid 的版本. 为此, 使用如下参数 `--grid` :

```
$ ./selenium-manager --grid
```

执行此命令后, Selenium Manager会发现 Selenium Grid 的最新版本, 并将 `selenium-server.jar` 存储在本地缓存中.

可选地, 参数 `--grid` 允许指定 Selenium Grid 版本( `--grid <GRID_VERSION>` ).

## 已知的限制

### 连接问题

Selenium Manager会请求远程端点(例如 Chrome 测试版(CfT)等) 从在线存储库中发现并下载驱动程序和浏览器. 当在具有代理或防火墙的企业环境中执行此操作时, 可能会导致以下连接问题:

```
error sending request for url (https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json)
```

```
error trying to connect: dns error: failed to lookup address information
```

```
error trying to connect: An existing connection was forcibly closed by the remote host. (os error 10054)
```

当这种情况发生时, 请考虑以下解决方案:

* 使用 Selenium 的代理功能(请参阅[documentation](https://www.selenium.dev/documentation/webdriver/drivers/options/#proxy)). 或者, 使用环境变量 `SE_PROXY` 来设置代理 URL, 或者使用配置文件(请参阅 [configuration](https://www.selenium.dev/documentation/selenium_manager/#configuration) ).
* 检查您的网络设置, 以启用 Selenium Manager所需的远程请求和下载.

### 自定义包管理器

如果您正在使用需要特定驱动程序的 Linux 软件包管理器(如 Anaconda、snap 等)来运行您的浏览器, 您可能需要指定[driver location](https://www.selenium.dev/documentation/webdriver/drivers/service/#driver-location)、[browser location](https://www.selenium.dev/documentation/webdriver/browsers/chrome/#start-browser-in-a-specified-location), 或者两者都需要, 具体取决于管理器的要求.

### 备选架构

Selenium 支持由谷歌 Chrome for Testing 管理的所有五种架构, 以及为微软 Edge 提供的所有六种驱动程序.

Selenium 绑定的每次发布都包含三个独立的 Selenium Manager 二进制文件, 分别适用于 Linux、Windows 和 Mac 系统.

* Mac 版本支持 x64 和 aarch64(英特尔和苹果)架构.
* Windows 版本应适用于 x86 和 x64(32 位和 64 位操作系统).
* Linux 版本仅经过验证可在 x64 系统上运行

不支持更多架构的原因:

1. 无论是 Chrome for Testing 还是 Microsoft Edge 都不支持其他架构, 因此 Selenium Manager 需要管理一些非官方的东西才能使其正常工作.
2. 我们目前从现有的 GitHub 操作运行器构建二进制文件, 这些运行器不支持这些架构.
3. 任何额外的架构都会随所有 Selenium 版本一起分发, 从而增加总的构建大小.

如果您在 arm64/aarch64、32 位架构或树莓派上运行 Linux, Selenium Manager 将无法为您服务.\
对于用户来说, 最大的问题在于他们过去常常获取自定义构建的驱动程序并将其放在 PATH 上, 然后就能正常工作.\
现在由于 Selenium Manager 负责在 PATH 上查找驱动程序, 这种方法不再奏效, 用户需要使用 `Service` 类并[直接设置位置](https://www.selenium.dev/documentation/webdriver/drivers/service/#driver-location) . 让 Selenium Manager 在 PATH 上查找驱动程序而不是在每个绑定中管理该逻辑, 有诸多优势, 所以目前这是我们愿意接受的权衡.

然而, 从 Selenium 4.13.0 版本开始, Selenium 绑定允许通过一个名为 `SE_MANAGER_PATH` 的环境变量来定位 Selenium Manager 二进制文件. 如果设置了此变量, 绑定将使用其值作为本地文件系统中的 Selenium Manager 路径. 此功能将允许用户提供自定义编译的 Selenium Manager, 例如, 如果默认的二进制文件(针对 Windows、Linux 和 macOS 编译)与给定系统(例如 Linux 中的 ARM64)不兼容.

### 浏览器依赖

在 Linux 系统中自动管理浏览器时, Selenium Manager 依赖于浏览器供应商(例如 Chrome、Firefox 和 Edge)发布的版本. 这些版本在大多数情况下都是可移植的. 然而, 在某些情况下可能需要现有的库. 在 Linux 中, 尝试运行 Firefox 时可能会遇到此问题, 例如:

```
libdbus-glib-1.so.2: cannot open shared object file: No such file or directory
Couldn't load XPCOM.
```

如果出现这种情况, 解决办法是安装相应的库, 例如, 可以按如下方式操作:

```
sudo apt-get install libdbus-glib-1-2
```

在 Linux 系统中尝试执行 Chrome for Testing 时可能会出现类似的问题:

```
error while loading shared libraries: libatk-1.0.so.0: cannot open shared object file: No such file or directory
```

在这种情况下, 要安装的库是以下这个:

```
sudo apt-get install libatk-bridge2.0-0
```

### 使用环境变量来指定驱动程序路径

可以使用环境变量来指定驱动程序路径, 而无需使用 Selenium Manager.\
支持以下环境变量:

* `SE_CHROMEDRIVER`
* `SE_EDGEDRIVER`
* `SE_GECKODRIVER`
* `SE_IEDRIVER`

例如, 要指定 chromedriver 的路径, 您可以将 `SE_CHROMEDRIVER` 环境变量设置为 chromedriver 可执行文件的路径. 以下绑定允许您使用环境变量指定驱动程序路径:

* Ruby
* Java
* Python

此功能从 Selenium Ruby 绑定的 4.25.0 版本以及 Python 绑定的 4.26.0 版本开始可用.

## 构建自定义 Selenium Manager

若要构建适用于我们当前不支持的架构的自定义 Selenium Manager, 您可以按照以下步骤操作:

2. 安装 Rust 开发环境
3. 将 Selenium 克隆到您的本地机器上 `git clone https://github.com/SeleniumHQ/selenium.git --depth 1`
4. 进入您的下载目录 `cd selenium/rust`
5. 构建 Selenium `cargo build --release`
6. 设置以下环境变量以指定驱动程序路径 `SE_MANAGER_PATH=~/selenium/rust/target/release/selenium-manager`
7. 将您想要的驱动程序放在系统路径中的某个位置.
8. Selenium 现在将使用内置的 Selenium Manager在 PATH 中定位手动下载的驱动程序.

## 路线图

您可以在 [Selenium Manager project dashboard](https://github.com/orgs/SeleniumHQ/projects/5) 中追踪正在进行的工作. 此外, 您还可以在每个 Selenium Manager 版本的[changelog file](https://github.com/SeleniumHQ/selenium/blob/trunk/rust/CHANGELOG.md) 中查看随版本发布的新增功能.

最后修改 August 15, 2025: [Update CLI output examples in Selenium Manager pages (310245c33be)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/310245c33be7fc8ba56139253f83d79d5e250db0)

----
url: https://www.selenium.dev/documentation/grid/applicability/
----

# When to Use Grid

```
   15      *       45s        /        1        =      11m 15s   // Without Grid
   15      *       45s        /        5        =      2m 15s    // Grid with 5 Nodes
   15      *       45s        /        15       =      45s       // Grid with 15 Nodes
  100      *       120s       /        15       =      13m 20s   // Would take over 3 hours without Grid
```

As the test suite is executing, the Grid allocates the tests to run against these browsers as configured in the tests.

A configuration such as this can greatly speed up the execution time of even the largest Selenium test suites.

Selenium Grid is a completely native part of the Selenium project, and is maintained in parallel by the same team of committers who work in the core Selenium development. Recognizing the importance of test execution speed, Grid has been a critical part of the Selenium project since the earliest days.

Last modified August 23, 2022: [Updating Applicability section of the grid docs (#1139) (d29144c94a7)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/d29144c94a76291198b551417616e01fbe4be8e1)

----
url: https://www.selenium.dev/documentation/legacy/selenium_2/
----

# Selenium 2

Selenium 2 was a rewrite of Selenium 1 that was implemented with WebDriver code.

***

##### [Migrating from RC to WebDriver](/documentation/legacy/selenium_2/upgrading/)

Information on Updating from Selenium 1 to Selenium 2.

##### [Backing Selenium with WebDriver](/documentation/legacy/selenium_2/emulation/)

The Java and .NET versions of Selenium 2 provided implementations of the original Selenium API

##### [Legacy Firefox Driver](/documentation/legacy/selenium_2/firefox_driver/)

The legacy Firefox Driver was developed as a browser extension by the Selenium Developers. Firefox updated their security model, so it no longer works. You now need to use geckodriver.

##### [Selenium grid 2](/documentation/legacy/selenium_2/grid_2/)

Selenium Grid 2 supported WebDriver and Selenium RC. It was replaced by Grid 3 which removed RC code. Grid 3 was completely rewritten for the new Grid 4.

##### [History of Grid Platforms](/documentation/legacy/selenium_2/grid_platforms/)

Information for working with platform names in Grid 2.

##### [Remote WebDriver standalone server](/documentation/legacy/selenium_2/remote_server/)

Working with the Standalone Server.

##### [Limitations of scaling up tests in Selenium 2](/documentation/legacy/selenium_2/parallel_execution/)

Summary of additional constraints that arise when running Selenium2 in parallel.

##### [Stealing focus from Firefox in Linux](/documentation/legacy/selenium_2/focus_stealing/)

How to work with Native Events in the Legacy Firefox extension.

##### [Untrusted SSL Certificates](/documentation/legacy/selenium_2/ssl_certs/)

Details on how Selenium 2 accepted untrusted SSL certificates

##### [WebDriver For Mobile Browsers](/documentation/legacy/selenium_2/mobile/)

Describes how Selenium 2 supported Android and iOS before Appium was created

##### [Frequently Asked Questions for Selenium 2](/documentation/legacy/selenium_2/faq/)

Items of interest for moving from Selenium 1 to Selenium 2

##### [Selenium 2.0 Team](/documentation/legacy/selenium_2/team/)

This is who you can blame for the Selenium 2 release.

----
url: https://www.selenium.dev/ja/documentation/legacy/selenium_3/grid_setup/
----

# 独自のグリッドを設定する

```shell
java -jar selenium-server-standalone.jar -role hub
```

ハブはデフォルトでポート4444をリッスンします。 ブラウザーウィンドウを開いて <http://localhost:4444/grid/console> に移動すると、ハブのステータスを表示できます。

デフォルトのポートを変更するには、コマンドを実行するときにリッスンするポートを表す整数を持つオプションの `-port` フラグを追加できます。 また、JSON構成ファイル（以下を参照）に表示される他のすべてのオプションは、可能なコマンドラインフラグです。

確かに上記の簡単なコマンドだけでうまくいくことができますが、より高度な構成が必要な場合は、JSON形式の構成ファイルを指定して、開始時にハブを構成することもできます。 JSON形式の構成ファイルを指定して開始時にハブを構成する方法は以下のとおりです。

```shell
java -jar selenium-server-standalone.jar -role hub -hubConfig hubConfig.json -debug
```

以下に、 `hubConfig.json` ファイルの例を示します。 ステップ2でノード構成ファイルを提供する方法について詳しく説明します。

```json
{
  "_comment" : "Configuration for Hub - hubConfig.json",
  "host": ip,
  "maxSession": 5,
  "port": 4444,
  "cleanupCycle": 5000,
  "timeout": 300000,
  "newSessionWaitTimeout": -1,
  "servlets": [],
  "prioritizer": null,
  "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
  "throwOnCapabilityNotPresent": true,
  "nodePolling": 180000,
  "platform": "WINDOWS"}
```

### ステップ2：ノードを起動する

新しいWebDriver機能を備えたグリッドを実行するか、Selenium 1 RC機能を備えたグリッドを実行するか、または両方を同時に実行するかに関係なく、同じ `selenium-server-standalone.jar` ファイルを使用してノードを起動します。

```shell
java -jar selenium-server-standalone.jar -role node -hub http://localhost:4444
```

```shell
java -Dwebdriver.chrome.driver=chromedriver.exe -jar selenium-server-standalone.jar -role node -nodeConfig node1Config.json
```

そして、これは `nodeConfig.json` ファイルの例です。

```json
{
  "capabilities": [
    {
      "browserName": "firefox",
      "acceptSslCerts": true,
      "javascriptEnabled": true,
      "takesScreenshot": false,
      "firefox_profile": "",
      "browser-version": "27",
      "platform": "WINDOWS",
      "maxInstances": 5,
      "firefox_binary": "",
      "cleanSession": true
    },
    {
      "browserName": "chrome",
      "maxInstances": 5,
      "platform": "WINDOWS",
      "webdriver.chrome.driver": "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"
    },
    {
      "browserName": "internet explorer",
      "maxInstances": 1,
      "platform": "WINDOWS",
      "webdriver.ie.driver": "C:/Program Files (x86)/Internet Explorer/iexplore.exe"
    }
  ],
  "configuration": {
    "_comment" : "Configuration for Node",
    "cleanUpCycle": 2000,
    "timeout": 30000,
    "proxy": "org.openqa.grid.selenium.proxy.WebDriverRemoteProxy",
    "port": 5555,
    "host": ip,
    "register": true,
    "hubPort": 4444,
    "maxSession": 5
  }
}
```

```shell
java -jar selenium-server-standalone.jar -role hub -log log.txt
```

お気に入りのテキストエディターを使用してログファイル（上記の例ではlog.txt）を開き、問題が発生した場合に"エラー"ログを見つけます。

### `-debug` 引数を使用する

-debug引数を使用して、デバッグログをコンソールに出力することもできます。 `-debug` 引数を使用してSeleniumグリッドハブまたはノードを起動します。 以下の例をご覧ください。

```shell
java -jar selenium-server-standalone.jar -role hub -debug
```

## 警告

Selenium Gridは、適切なファイアウォールアクセス許可を使用して外部アクセスから保護する必要があります。

グリッドを保護しないと、次の1つ以上が発生する可能性があります。

* グリッドインフラストラクチャへのオープンアクセスを提供します。
* サードパーティが内部Webアプリケーションおよびファイルにアクセスすることを許可します。
* サードパーティにカスタムバイナリの実行を許可します。

[Detectify](/ja/) に関するこのブログ投稿をご覧ください。 これは、公開されたグリッドが悪用される可能性のある概要を示しています。 [Don’t Leave your Grid Wide Open](//labs.detectify.com/2017/10/06/guest-blog-dont-leave-your-grid-wide-open/)

## Docker Selenium

[Docker](/ja/) は、コンテナと呼ばれる単位でSelenium Gridインフラストラクチャをプロビジョニングおよびスケーリングする便利な方法を提供します。 コンテナは、さまざまなマシンで信頼性と再現性のある方法で、すべての依存関係を含む目的のアプリケーションを実行するために必要なすべてを含むソフトウェアの標準化されたユニットです。

Seleniumプロジェクトは、ダウンロードして実行して作業用グリッドを迅速に起動および実行できる一連のDockerイメージを保持しています。 ノードはFirefoxとChromeの両方で使用できます。 グリッドのプロビジョニング方法の詳細は、 [Docker Selenium](//github.com/SeleniumHQ/docker-selenium) リポジトリ内にあります。

### 前提条件

グリッドを実行するための唯一の要件は、Dockerをインストールして動作させることです。 [Dockerのインストール](//www.docker.com/products/docker-desktop).

----
url: https://www.selenium.dev/ja/_print/documentation/webdriver/troubleshooting/errors/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/webdriver/troubleshooting/errors/).

# Understanding Common Errors

How to solve various problems in your Selenium code.

* 1: [Unable to Locate Driver Error](#pg-7dc6ce7850b813d8da2361fdcd2b0480)

* Make sure you are using a proper [Waiting Strategy](https://www.selenium.dev/ja/documentation/webdriver/waits/)

[Explicit Waits](https://www.selenium.dev/ja/documentation/webdriver/waits/) will likely be your best friend in these instances. A great way is to use `ExpectedCondition.ToBeClickable()` with `WebDriverWait` to wait until the right moment.

As of Selenium 4.6, Selenium downloads the correct driver for you. You shouldn’t need to do anything. If you are using the latest version of Selenium and you are getting an error, please [turn on logging](https://www.selenium.dev/ja/documentation/webdriver/troubleshooting/logging/) and [file a bug report](//github.com/seleniumhq/selenium/issues) with that information.

If you want to read more information about how Selenium manages driver downloads for you, you can read about the [Selenium Manager](https://www.selenium.dev/ja/documentation/selenium_manager/).

### Use the `PATH` environment variable

This option first requires manually [downloading the driver](/ja/documentation/webdriver/troubleshooting/errors/driver_location/#download-the-driver).

This is a flexible option to change location of drivers without having to update your code, and will work on multiple machines without requiring that each machine put the drivers in the same place.

You can either place the drivers in a directory that is already listed in `PATH`, or you can place them in a directory and add it to `PATH`.

*
*
*

To see what directories are already on `PATH`, open a Terminal and execute:

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.bash_profile
source ~/.bash_profile
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Terminal and execute:

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.zshenv
source ~/.zshenv
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Command Prompt and execute:

```shell
echo %PATH%
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
setx PATH "%PATH%;C:\WebDriver\bin"
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver.exe --version
```

| ブラウザー             | サポートするOS                    | 維持管理機関           | ダウンロード                                                                       | イシュートラッカー                                                        |
| ----------------- | --------------------------- | ---------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| Chromium/Chrome   | Windows/macOS/Linux         | Google           | [Downloads](//chromedriver.chromium.org/downloads)                           | [Issues](//bugs.chromium.org/p/chromedriver/issues/list)         |
| Firefox           | Windows/macOS/Linux         | Mozilla          | [Downloads](//github.com/mozilla/geckodriver/releases)                       | [Issues](//github.com/mozilla/geckodriver/issues)                |
| Edge              | Windows/macOS/Linux         | Microsoft        | [Downloads](//developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/) | [Issues](https://github.com/MicrosoftDocs/edge-developer/issues) |
| Internet Explorer | Windows                     | Selenium Project | [Downloads](/downloads)                                                      | [Issues](//github.com/SeleniumHQ/selenium/labels/D-IE)           |
| Safari            | macOS High Sierra and newer | Apple            | Built in                                                                     | [Issues](//bugreport.apple.com/logon)                            |

----
url: https://www.selenium.dev/documentation/legacy/selenium_2/parallel_execution/
----

# Limitations of scaling up tests in Selenium 2

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/elements/interactions/
----

# Web元素交互

```java
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L18-L22)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L12-L17)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L17-L21)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'color_input').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L11)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
    await submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L20)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
  const assert = require("assert");
  
  (async function firstTest() {
    let driver;
    
    try {
      driver = await new Builder().forBrowser(Browser.CHROME).build();
      await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
    
      let title = await driver.getTitle();
      assert.equal("Web form", title);
    
      await driver.manage().setTimeouts({implicit: 500});
    
      let textBox = await driver.findElement(By.name('my-text'));
      let submitButton = await driver.findElement(By.css('button'));
    
      await textBox.sendKeys('Selenium');
      await submitButton.click();
    
      let message = await driver.findElement(By.id('message'));
      let value = await message.getText();
      assert.equal("Received!", value);
    } catch (e) {
      console.log(e)
    } finally {
      await driver.quit();
    }
  }())
  
```

```kotlin
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    // Click the element
    driver.findElement(By.name("color_input")).click();
  
  
```

```java
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L27-L32)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L22-L27)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L27-L33)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L16)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
      let inputField = await driver.findElement(By.name('no_type'));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/interactions.spec.js#L21)

##### /examples/javascript/test/elements/interactions.spec.js

```js

  const {By, Browser, Builder} = require('selenium-webdriver');
  const assert = require("node:assert");
  
  
  describe('Element Interactions', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('should Clear input and send keys into input field', async function () {
  
      try {
        await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
        let inputField = await driver.findElement(By.name('no_type'));
        await inputField.clear();
        await inputField.sendKeys('Selenium');
        const text = await inputField.getAttribute('value');
        assert.strictEqual(text, "Selenium");
      } catch (e) {
        console.log(e)
      }
    });
  });
```

```kotlin
  
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

	//Clear field to empty it from any previous data
	driver.findElement(By.name("email_input")).clear()
	
    // Enter text 
    driver.findElement(By.name("email_input")).sendKeys("admin@localhost.dev")
  
  
```

```java
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L38-L40)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    email_input.clear()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L34)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L40-L43)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'email_input').clear
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L15)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
      await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/interactions.spec.js#L20)

##### /examples/javascript/test/elements/interactions.spec.js

```js

  const {By, Browser, Builder} = require('selenium-webdriver');
  const assert = require("node:assert");
  
  
  describe('Element Interactions', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('should Clear input and send keys into input field', async function () {
  
      try {
        await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
        let inputField = await driver.findElement(By.name('no_type'));
        await inputField.clear();
        await inputField.sendKeys('Selenium');
        const text = await inputField.getAttribute('value');
        assert.strictEqual(text, "Selenium");
      } catch (e) {
        console.log(e)
      }
    });
  });
```

```kotlin
  
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

	//Clear field to empty it from any previous data
	driver.findElement(By.name("email_input")).clear()
	
  
  
```

## 提交

在Selenium 4中, 不再通过单独的端点以及脚本执行的方法来实现. 因此, 建议不要使用此方法, 而是单击相应的表单提交按钮.

----
url: https://www.selenium.dev/ja/documentation/webdriver/support_features/colors/
----

# 色を扱う

```java
import org.openqa.selenium.support.Color;
  
```

```python
from selenium.webdriver.support.color import Color
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
include Selenium::WebDriver::Support
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
import org.openqa.selenium.support.Color
```

```java
private final Color HEX_COLOUR = Color.fromString("#2F7ED8");
private final Color RGB_COLOUR = Color.fromString("rgb(255, 255, 255)");
private final Color RGB_COLOUR = Color.fromString("rgb(40%, 20%, 40%)");
private final Color RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)");
private final Color RGBA_COLOUR = Color.fromString("rgba(40%, 20%, 40%, 0.5)");
private final Color HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)");
private final Color HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)");
  
```

```python
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
private val HEX_COLOUR = Color.fromString("#2F7ED8")
private val RGB_COLOUR = Color.fromString("rgb(255, 255, 255)")
private val RGB_COLOUR_PERCENT = Color.fromString("rgb(40%, 20%, 40%)")
private val RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)")
private val RGBA_COLOUR_PERCENT = Color.fromString("rgba(40%, 20%, 40%, 0.5)")
private val HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)")
private val HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)")
  
```

```java
private final Color BLACK = Color.fromString("black");
private final Color CHOCOLATE = Color.fromString("chocolate");
private final Color HOTPINK = Color.fromString("hotpink");
  
```

```python
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
private val BLACK = Color.fromString("black")
private val CHOCOLATE = Color.fromString("chocolate")
private val HOTPINK = Color.fromString("hotpink")
  
```

```java
private final Color TRANSPARENT = Color.fromString("transparent");
  
```

```python
TRANSPARENT = Color.from_string('transparent')
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
TRANSPARENT = Color.from_string('transparent')
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
private val TRANSPARENT = Color.fromString("transparent")
  
```

```java
Color loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"));

Color loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"));
  
```

```python
login_button_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('color'))

login_button_background_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('background-color'))
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
login_button_colour = Color.from_string(driver.find_element(id: 'login').css_value('color'))

login_button_background_colour = Color.from_string(driver.find_element(id: 'login').css_value('background-color'))
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
val loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"))

val loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"))
  
```

```java
assert loginButtonBackgroundColour.equals(HOTPINK);
  
```

```python
assert login_button_background_colour == HOTPINK
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
assert(login_button_background_colour == HOTPINK)
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
assert(loginButtonBackgroundColour.equals(HOTPINK))
  
```

```java
assert loginButtonBackgroundColour.asHex().equals("#ff69b4");
assert loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)");
assert loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)");
  
```

```python
assert login_button_background_colour.hex == '#ff69b4'
assert login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)'
assert login_button_background_colour.rgb == 'rgb(255, 105, 180)'
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
assert(login_button_background_colour.hex == '#ff69b4')
assert(login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)')
assert(login_button_background_colour.rgb == 'rgb(255, 105, 180)')
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
assert(loginButtonBackgroundColour.asHex().equals("#ff69b4"))
assert(loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)"))
assert(loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)"))
  
```

色はもはや問題ではありません。

最終更新 August 3, 2023: [update wait documentation (#1358)\[deploy site\] (d1af4fe2409)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/d1af4fe2409e2101eaabf23f4e5716428e0bdd56)

----
url: https://www.selenium.dev/documentation/webdriver/drivers/remote_webdriver/
----

# Remote WebDriver

```java
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L38-L39)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L13-L14)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L28-L29)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L20-L21)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L49-L52)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

Python adds a local file detector to remote webdriver instances by default, but you can also create your own class.

```py
    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L29-L32)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

.NET adds a local file detector to remote webdriver instances by default, but you can also create your own class.

```cs
            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L47-L50)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

Ruby adds a local file detector to remote webdriver instances by default, but you can also create your own lambda:

```rb
    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L33-L36)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## Downloads

Chrome, Edge and Firefox each allow you to set the location of the download directory. When you do this on a remote computer, though, the location is on the remote computer’s local file system. Selenium allows you to enable downloads to get these files onto the client computer.

### Enable Downloads in the Grid

Regardless of the client, when starting the grid in node or standalone mode, you must add the flag:

```
--enable-managed-downloads true
```

```java
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L60-L62)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L42-L44)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L59-L64)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L43-L44)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    List<String> files = ((HasDownloads) driver).getDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L73)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    files = driver.get_downloadable_files()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L52)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L72)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    files = driver.downloadable_files
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L52)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L83)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    driver.download_file(downloadable_file, target_directory)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L58)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L79)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    driver.download_file(downloadable_file, target_directory)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L57)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((HasDownloads) driver).deleteDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L88)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    driver.delete_downloadable_files()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L64)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ((RemoteWebDriver)driver).DeleteDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L84)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    driver.delete_downloadable_files
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L62)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    driver = new Augmenter().augment(driver);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L98)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

Of interest, using the `RemoteWebDriverBuilder` automatically augments the driver, so it is a great way to get all the functionality by default:

```java
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L106-L111)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

.NET uses a custom command executor for executing commands that are valid for the given browser in the remote driver.

```cs
            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L96-L100)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```xml
  <dependency>
      <groupId>io.opentelemetry</groupId>
      <artifactId>opentelemetry-exporter-jaeger</artifactId>
      <version>1.0.0</version>
    </dependency>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-netty</artifactId>
      <version>1.35.0</version>
    </dependency>
```

### Add/pass the required system properties while running the client

*

```java
System.setProperty("otel.traces.exporter", "jaeger");
System.setProperty("otel.exporter.jaeger.endpoint", "http://localhost:14250");
System.setProperty("otel.resource.attributes", "service.name=selenium-java-client");

ImmutableCapabilities capabilities = new ImmutableCapabilities("browserName", "chrome");

WebDriver driver = new RemoteWebDriver(new URL("http://www.example.com"), capabilities);

driver.get("http://www.google.com");

driver.quit();

  
```

Please refer to [Tracing Setup](https://github.com/SeleniumHQ/selenium/blob/selenium-4.0.0-beta-1/java/server/src/org/openqa/selenium/grid/commands/tracing.txt) for more information on external dependencies versions required for the desired Selenium version.

More information can be found at:

* OpenTelemetry: <https://opentelemetry.io>
* Configuring OpenTelemetry: <https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure>
* Jaeger: <https://www.jaegertracing.io>
* [Selenium Grid Observability](https://www.selenium.dev/documentation/grid/advanced_features/observability/)

----
url: https://www.selenium.dev/pt-br/documentation/grid/
----

# Grid

Pretende executar testes em paralelo em várias máquinas? Então a Grid é para si.

Selenium Grid permite a execucão de scripts WebDriver em máquinas remotas, passando os comandos recebidos pelo cliente para a instância remotas do navegador.

O objectivo da Grid é:

* Providenciar uma forma fácil de executar testes em paralelo em multiplas máquinas
* Permitir testes em versões diferentes de navegadores
* Permitir testes em várias plataformas

Está interessado? Enão siga lendo as próximas secções para entender como a Grid funciona e também como montar a sua.

***

##### [Configurando a sua](/pt-br/documentation/grid/getting_started/)

Instruções para criar uma Selenium Grid simples

##### [Quando usar a Grid](/pt-br/documentation/grid/applicability/)

Será a Grid a melhor escolha para você?

##### [Componentes](/pt-br/documentation/grid/components/)

Compreender como usar os componentes da Grid

##### [Configurando componentes](/pt-br/documentation/grid/configuration/)

Leia aqui como pode configurar cada um dos componentes Grid com base em valores comuns ou específicos para o componente.

##### [Arquitectura da Grid](/pt-br/documentation/grid/architecture/)

##### [Características avançadas](/pt-br/documentation/grid/advanced_features/)

Para obter todos os detalhes dos recursos avançados, entenda como funciona e como configurar crie o seu próprio, navegue pelas seções a seguir.

Última modificação February 6, 2024: [Grid as 4 in the index (f414b1ef8f2)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/f414b1ef8f2f4d0412a75fe8ca059786be95b0c0)

----
url: https://www.selenium.dev/ja/documentation/webdriver/interactions/frames/
----

# IFrame と Frame の操作

Frameは、同じドメイン上の複数のドキュメントからサイトレイアウトを構築する非推奨の手段となりました。 HTML5以前のWebアプリを使用している場合を除き、frameを使用することはほとんどありません。 iFrameは、まったく異なるドメインからのドキュメントの挿入を許可し、今でも一般的に使用されています。

FrameまたはiFrameを使用する必要がある場合、Webdriverを使用して同じ方法で作業できます。 iFrame内のボタンがある場合を考えてみましょう。ブラウザー開発ツールを使用して要素を検査すると、次のように表示される場合があります。

```html
<div id="modal">
  <iframe id="buttonframe" name="myframe"  src="https://seleniumhq.github.io">
   <button>Click here</button>
 </iframe>
</div>
```

```java
//This won't work
driver.findElement(By.tagName("button")).click();
  
```

```python
    # This Wont work
driver.find_element(By.TAG_NAME, 'button').click()
  
```

```csharp
//This won't work
driver.FindElement(By.TagName("button")).Click();
  
```

```ruby
    # This won't work
driver.find_element(:tag_name,'button').click
  
```

```javascript
// This won't work
await driver.findElement(By.css('button')).click();
  
```

```kotlin
//This won't work
driver.findElement(By.tagName("button")).click()
  
```

```java
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L38-L46)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L24-L32)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L38-L46)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L26-L36)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Store the web element
const iframe = driver.findElement(By.css('#modal > iframe'));

// Switch to the frame
await driver.switchTo().frame(iframe);

// Now we can click the button
await driver.findElement(By.css('button')).click();
  
```

```kotlin
//Store the web element
val iframe = driver.findElement(By.cssSelector("#modal>iframe"))

//Switch to the frame
driver.switchTo().frame(iframe)

//Now we can click the button
driver.findElement(By.tagName("button")).click()
  
```

```java
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L50-L58)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L34-L42)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L50-L58)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L36-L43)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Using the ID
await driver.switchTo().frame('buttonframe');

// Or using the name instead
await driver.switchTo().frame('myframe');

// Now we can click the button
await driver.findElement(By.css('button')).click();
  
```

```kotlin
//Using the ID
driver.switchTo().frame("buttonframe")

//Or using the name instead
driver.switchTo().frame("myframe")

//Now we can click the button
driver.findElement(By.tagName("button")).click()
  
```

```java
         //switch To IFrame using index
         driver.switchTo().frame(0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L62-L63)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L45-L46)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L62-L63)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L46-L47)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Switches to the second frame
await driver.switchTo().frame(1);
```

```kotlin
// Switches to the second frame
driver.switchTo().frame(1)
```

```java
         //leave frame
         driver.switchTo().defaultContent();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L66-L67)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```python
    # switch back to default content
driver.switch_to.default_content()
  
```

```cs
            //leave frame
            driver.SwitchTo().DefaultContent();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L66-L67)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L49-L50)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Return to the top level
await driver.switchTo().defaultContent();
  
```

```kotlin
// Return to the top level
driver.switchTo().defaultContent()
  
```

----
url: https://www.selenium.dev/zh-cn/_print/documentation/webdriver/actions_api/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/webdriver/actions_api/).

# Actions接口

用于向 Web 浏览器提供虚拟化设备输入操作的低级接口.

* 1: [键盘操作](#pg-fd2cfa880cdb3bf2cddf7e81ff5d28f5)
* 2: [鼠标操作](#pg-b0ca95e767f58f38405a772b809a54d4)
* 3: [触控笔操作](#pg-fb0216db56c60c22f64496d00a6e2e62)
* 4: [Scroll wheel actions](#pg-d992cca521987edc08eabbc41baa16e1)

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/ActionsTest.java#L21-L28)

##### /examples/java/src/test/java/dev/selenium/actions\_api/ActionsTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;

public class ActionsTest extends BaseChromeTest {
    @Test
    public void pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        long start = System.currentTimeMillis();

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();

        long duration = System.currentTimeMillis() - start;
        Assertions.assertTrue(duration > 2000);
        Assertions.assertTrue(duration < 3000);
    }

    @Test
    public void releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        Actions actions = new Actions(driver);
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        ((RemoteWebDriver) driver).resetInputState();

        actions.sendKeys("a").perform();
        Assertions.assertEquals("A", String.valueOf(clickable.getAttribute("value").charAt(0)));
        Assertions.assertEquals("a", String.valueOf(clickable.getAttribute("value").charAt(1)));
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_actions.py#L13-L20)

##### /examples/python/tests/actions\_api/test\_actions.py

```py
from time import time

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.by import By


def test_pauses(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    start = time()

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()

    duration = time() - start
    assert duration > 2
    assert duration < 3


def test_releases_all(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .click_and_hold(clickable)\
        .key_down(Keys.SHIFT)\
        .key_down("a")\
        .perform()

    ActionBuilder(driver).clear_actions()

    ActionChains(driver).key_down('a').perform()

    assert clickable.get_attribute('value')[0] == "A"
    assert clickable.get_attribute('value')[1] == "a"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs#L18-L25)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class ActionsTest : BaseChromeTest
    {
        [TestMethod]
        public void Pause()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            DateTime start = DateTime.Now;

            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();

            TimeSpan duration = DateTime.Now - start;
            Assert.IsTrue(duration > TimeSpan.FromSeconds(2));
            Assert.IsTrue(duration < TimeSpan.FromSeconds(3));
        }

        [TestMethod]
        public void ReleaseAll()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            var actions = new Actions(driver);
            actions.ClickAndHold(clickable)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            ((WebDriver)driver).ResetInputState();

            actions.SendKeys("a").Perform();
            var value = clickable.GetAttribute("value");
            Assert.AreEqual("A", value[..1]);
            Assert.AreEqual("a", value.Substring(1, 1));
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/actions_spec.rb#L12-L19)

##### /examples/ruby/spec/actions\_api/actions\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Actions' do
  let(:driver) { start_session }

  it 'pauses' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
    start = Time.now

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform

    duration = Time.now - start
    expect(duration).to be > 2
    expect(duration).to be < 3
  end

  it 'releases all' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    action = driver.action
                   .click_and_hold(clickable)
                   .key_down(:shift)
                   .key_down('a')
    action.perform

    driver.action.release_actions

    action.key_down('a').perform
    expect(clickable.attribute('value')[0]).to eq 'A'
    expect(clickable.attribute('value')[-1]).to eq 'a'
  end
end
```

```js
    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/actionsTest.spec.js#L18-L25)

##### /examples/javascript/test/actionsApi/actionsTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Pause and Release All Actions', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('Pause', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const start = Date.now()

    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()

    const end = Date.now() - start
    assert.ok(end > 2000)
    assert.ok(end < 4000)
  })

  it('Clear', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const clickable = driver.findElement(By.id('clickable'))
    await driver.actions()
      .click(clickable)
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    await driver.actions().clear()
    await driver.actions().sendKeys('a').perform()

    const value = await clickable.getAttribute('value')
    assert.deepStrictEqual('A', value.substring(0, 1))
    assert.deepStrictEqual('a', value.substring(1, 2))
  })
})
```

```kt
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/ActionsTest.kt#L22-L29)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/ActionsTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration

class ActionsTest : BaseTest() {

    @Test
    fun pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val start = System.currentTimeMillis()

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 

        val duration = System.currentTimeMillis() - start
        Assertions.assertTrue(duration > 2000)
        Assertions.assertTrue(duration < 4000)
    }

    @Test
    fun releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        val actions = Actions(driver)
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        (driver as RemoteWebDriver).resetInputState()

        actions.sendKeys("a").perform()
        Assertions.assertEquals("A", clickable.getAttribute("value")!!.get(0).toString())
        Assertions.assertEquals("a", clickable.getAttribute("value")!!.get(1).toString())
    }
}
```

```java
        ((RemoteWebDriver) driver).resetInputState();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/ActionsTest.java#L46)

##### /examples/java/src/test/java/dev/selenium/actions\_api/ActionsTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;

public class ActionsTest extends BaseChromeTest {
    @Test
    public void pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        long start = System.currentTimeMillis();

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();

        long duration = System.currentTimeMillis() - start;
        Assertions.assertTrue(duration > 2000);
        Assertions.assertTrue(duration < 3000);
    }

    @Test
    public void releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        Actions actions = new Actions(driver);
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        ((RemoteWebDriver) driver).resetInputState();

        actions.sendKeys("a").perform();
        Assertions.assertEquals("A", String.valueOf(clickable.getAttribute("value").charAt(0)));
        Assertions.assertEquals("a", String.valueOf(clickable.getAttribute("value").charAt(1)));
    }
}
```

```py
    ActionBuilder(driver).clear_actions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_actions.py#L37)

##### /examples/python/tests/actions\_api/test\_actions.py

```py
from time import time

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.by import By


def test_pauses(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    start = time()

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()

    duration = time() - start
    assert duration > 2
    assert duration < 3


def test_releases_all(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .click_and_hold(clickable)\
        .key_down(Keys.SHIFT)\
        .key_down("a")\
        .perform()

    ActionBuilder(driver).clear_actions()

    ActionChains(driver).key_down('a').perform()

    assert clickable.get_attribute('value')[0] == "A"
    assert clickable.get_attribute('value')[1] == "a"
```

```cs
            ((WebDriver)driver).ResetInputState();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs#L44)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class ActionsTest : BaseChromeTest
    {
        [TestMethod]
        public void Pause()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            DateTime start = DateTime.Now;

            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();

            TimeSpan duration = DateTime.Now - start;
            Assert.IsTrue(duration > TimeSpan.FromSeconds(2));
            Assert.IsTrue(duration < TimeSpan.FromSeconds(3));
        }

        [TestMethod]
        public void ReleaseAll()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            var actions = new Actions(driver);
            actions.ClickAndHold(clickable)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            ((WebDriver)driver).ResetInputState();

            actions.SendKeys("a").Perform();
            var value = clickable.GetAttribute("value");
            Assert.AreEqual("A", value[..1]);
            Assert.AreEqual("a", value.Substring(1, 1));
        }
    }
}
```

```rb
    driver.action.release_actions
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/actions_spec.rb#L36)

##### /examples/ruby/spec/actions\_api/actions\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Actions' do
  let(:driver) { start_session }

  it 'pauses' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
    start = Time.now

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform

    duration = Time.now - start
    expect(duration).to be > 2
    expect(duration).to be < 3
  end

  it 'releases all' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    action = driver.action
                   .click_and_hold(clickable)
                   .key_down(:shift)
                   .key_down('a')
    action.perform

    driver.action.release_actions

    action.key_down('a').perform
    expect(clickable.attribute('value')[0]).to eq 'A'
    expect(clickable.attribute('value')[-1]).to eq 'a'
  end
end
```

```js
    await driver.actions().clear()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/actionsTest.spec.js#L42)

##### /examples/javascript/test/actionsApi/actionsTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Pause and Release All Actions', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('Pause', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const start = Date.now()

    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()

    const end = Date.now() - start
    assert.ok(end > 2000)
    assert.ok(end < 4000)
  })

  it('Clear', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const clickable = driver.findElement(By.id('clickable'))
    await driver.actions()
      .click(clickable)
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    await driver.actions().clear()
    await driver.actions().sendKeys('a').perform()

    const value = await clickable.getAttribute('value')
    assert.deepStrictEqual('A', value.substring(0, 1))
    assert.deepStrictEqual('a', value.substring(1, 2))
  })
})
```

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/ActionsTest.kt#L47)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/ActionsTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration

class ActionsTest : BaseTest() {

    @Test
    fun pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val start = System.currentTimeMillis()

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 

        val duration = System.currentTimeMillis() - start
        Assertions.assertTrue(duration > 2000)
        Assertions.assertTrue(duration < 4000)
    }

    @Test
    fun releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        val actions = Actions(driver)
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        (driver as RemoteWebDriver).resetInputState()

        actions.sendKeys("a").perform()
        Assertions.assertEquals("A", clickable.getAttribute("value")!!.get(0).toString())
        Assertions.assertEquals("a", clickable.getAttribute("value")!!.get(1).toString())
    }
}
```

# 1 - 键盘操作

```java
        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L17-L20)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L10-L13)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L13-L16)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L17-L20)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L19-L22)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L30-L35)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L21-L26)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L30-L35)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L25-L30)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L32-L37)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L32-L37)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .sendKeys("abc")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L45-L47)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L34-L36)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs

            new Actions(driver)
                .SendKeys("abc")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L45-L47)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .send_keys('abc')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L39-L41)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .sendKeys('abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L48-L50)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .sendKeys("abc")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L47-L49)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L59-L62)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L45-L48)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L58-L61)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L51-L54)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L59-L63)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L60-L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L70-L84)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L56-L67)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L72-L82)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L64-L74)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L73-L85)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L74-L86)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

# 2 - 鼠标操作

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L22-L25)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L14-L17)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L11-L14)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    let clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.move({origin: clickable}).press().perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/clickAndHold.spec.js#L14-L16)

##### /examples/javascript/test/actionsApi/mouse/clickAndHold.spec.js

```js
const {By, Builder} = require('selenium-webdriver');

describe('Click and hold', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and mouseDown on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    let clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.move({origin: clickable}).press().perform();
  });
});
```

```kt
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L23-L26)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L34-L37)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L26-L29)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L30-L33)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L22-L25)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    let click = driver.findElement(By.id("click"));
    const actions = driver.actions({async: true});
    await actions.move({origin: click}).click().perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/clickAndRelease.spec.js#L14-L16)

##### /examples/javascript/test/actionsApi/mouse/clickAndRelease.spec.js

```js
const {By,Builder} = require('selenium-webdriver');

describe('Click and release', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    let click = driver.findElement(By.id("click"));
    const actions = driver.actions({async: true});
    await actions.move({origin: click}).click().perform();
  });
});
```

```kt
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L35-L38)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L46-L49)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L37-L40)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L43-L46)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L34-L37)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.contextClick(clickable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/rightClick.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/rightClick.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Right click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and right click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.contextClick(clickable).perform();

    await driver.sleep(500);
    const clicked = await driver.findElement(By.id('click-status')).getText();
    assert.deepStrictEqual(clicked, `context-clicked`)
  });
});
```

```kt
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L47-L50)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L60-L66)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L51-L54)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L59-L63)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L47-L50)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js#L19-L20)

##### /examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js

```js
const {By, Button, Browser, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Should be able to perform BACK click and FORWARD click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Back click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)

    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)
  });

  it('Forward click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();
    await driver.navigate().back();

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)

    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L61-L67)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L78-L84)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L65-L68)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L77-L81)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L61-L64)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js#L32-L33)

##### /examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js

```js
const {By, Button, Browser, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Should be able to perform BACK click and FORWARD click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Back click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)

    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)
  });

  it('Forward click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();
    await driver.navigate().back();

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)

    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L79-L85)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L93-L96)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L76-L79)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L91-L94)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L73-L76)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.doubleClick(clickable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/doubleClick.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/doubleClick.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Double click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Double-click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.doubleClick(clickable).perform();

    await driver.sleep(500);
    const status = await driver.findElement(By.id('click-status')).getText();
    assert.deepStrictEqual(status, `double-clicked`)
  });
});
```

```kt
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L94-L97)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L105-L108)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L87-L90)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L104-L107)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L84-L87)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const hoverable = driver.findElement(By.id("hover"));
    const actions = driver.actions({async: true});
    await actions.move({origin: hoverable}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveToElement.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/moveToElement.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Move to element', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move into an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const hoverable = driver.findElement(By.id("hover"));
    const actions = driver.actions({async: true});
    await actions.move({origin: hoverable}).perform();

    const status = await driver.findElement(By.id('move-status')).getText();
    assert.deepStrictEqual(status, `hovered`)
  });
});
```

```kt
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L106-L109)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L118-L121)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L98-L101)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L132-L135)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L97-L100)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L119-L122)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L131-L136)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L110-L112)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L146-L150)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      driver.action
            .move_to_location(8, 12)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L114-L116)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L27-L28)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L132-L137)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L153-L155)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L126-L128)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L167-L169)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      driver.action
            .move_by(13, 15)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L128-L130)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L40)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L154-L156)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L166-L170)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L139-L143)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L181-L185)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L141-L145)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js#L27-L30)

##### /examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Drag and Drop', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('By Offset', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });

  it('Onto Element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });
});
```

```kt
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L167-L171)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L179-L184)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L151-L156)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L195-L200)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L153-L158)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js#L15-L19)

##### /examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Drag and Drop', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('By Offset', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });

  it('Onto Element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });
});
```

```kt
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L180-L185)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

# 3 - 触控笔操作

```java
        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/PenTest.java#L26-L33)

##### /examples/java/src/test/java/dev/selenium/actions\_api/PenTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PenTest extends BaseChromeTest {
    @Test
    public void usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();

        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    @Test
    public void setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();
        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("-72", moveBy.get("tiltX"));
        Assertions.assertEquals("9", moveBy.get("tiltY"));
        Assertions.assertEquals("86", moveBy.get("twist"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    private Map<String, String> getPropertyInfo(WebElement element) {
        String text = element.getText();
        text = text.substring(text.indexOf(' ') + 1);

        return Arrays.stream(text.split(", "))
                .map(s -> s.split(": "))
                .collect(Collectors.toMap(
                        a -> a[0],
                        a -> a[1]
                ));
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_pen.py#L12-L20)

##### /examples/python/tests/actions\_api/test\_pen.py

```py
import math

from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.interaction import POINTER_PEN
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.by import By


def test_use_pen(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def test_set_pointer_event_properties(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert move_by["tiltX"] == "-72"
    assert move_by["tiltY"] == "9"
    assert move_by["twist"] == "86"
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def properties(element):
    kv = element.text.split(' ', 1)[1].split(', ')
    return {x[0]:x[1] for x in list(map(lambda item: item.split(': '), kv))}
```

```cs
            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs#L19-L28)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class PenTest : BaseChromeTest
    {
        [TestMethod]
        public void UsePen()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        [TestMethod]
        public void SetPointerEventProperties()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual((-72).ToString(), moveBy["tiltX"]);
            Assert.AreEqual((9).ToString(), moveBy["tiltY"]);
            Assert.AreEqual((86).ToString(), moveBy["twist"]);
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        private Dictionary<string, string> getProperties(IWebElement element)
        {
            var str = element.Text;
            str = str[(str.Split()[0].Length + 1)..];
            IEnumerable<string[]> keyValue = str.Split(", ").Select(part => part.Split(":"));
            return keyValue.ToDictionary(split => split[0].Trim(), split => split[1].Trim());
        }

        private bool VerifyEquivalent(decimal expected, string actual)
        {
            var absolute = Math.Abs(expected - decimal.Parse(actual));
            if (absolute <= 1)
            {
                return true;
            }

            throw new Exception("Expected: " + expected + "; but received: " + actual);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/pen_spec.rb#L11-L17)

##### /examples/ruby/spec/actions\_api/pen\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Pen' do
  let(:driver) { start_session }

  it 'uses a pen' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  it 'sets pointer event attributes' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s,
                               'tiltX' => -72.to_s,
                               'tiltY' => 9.to_s,
                               'twist' => 86.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  def properties(element)
    element.text.sub(/.*?\s/, '').split(',').to_h { |item| item.lstrip.split(/\s*:\s*/) }
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/PenTest.kt#L23-L30)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/PenTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import kotlin.collections.Map
import java.time.Duration

class PenTest : BaseTest() {
  
    @Test
    fun usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
    }

    @Test
    fun setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY")) 
	    
        Assertions.assertEquals("-72", moveBy.get("tiltX"))
        Assertions.assertEquals("9", moveBy.get("tiltY"))
        Assertions.assertEquals("86", moveBy.get("twist"))
    }
    
    fun getPropertyInfo(element: WebElement): Map<String, String> {
        var text = element.getText()  
        text = text.substring(text.indexOf(" ")+1)
        return text.split(", ")
        .map { it.split(": ") }
        .map { it.first() to it.last() }
        .toMap() 
    }
}
```

```java
        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/PenTest.java#L67-L81)

##### /examples/java/src/test/java/dev/selenium/actions\_api/PenTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PenTest extends BaseChromeTest {
    @Test
    public void usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();

        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    @Test
    public void setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();
        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("-72", moveBy.get("tiltX"));
        Assertions.assertEquals("9", moveBy.get("tiltY"));
        Assertions.assertEquals("86", moveBy.get("twist"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    private Map<String, String> getPropertyInfo(WebElement element) {
        String text = element.getText();
        text = text.substring(text.indexOf(' ') + 1);

        return Arrays.stream(text.split(", "))
                .map(s -> s.split(": "))
                .collect(Collectors.toMap(
                        a -> a[0],
                        a -> a[1]
                ));
    }
}
```

```py
    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_pen.py#L53-L61)

##### /examples/python/tests/actions\_api/test\_pen.py

```py
import math

from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.interaction import POINTER_PEN
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.by import By


def test_use_pen(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def test_set_pointer_event_properties(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert move_by["tiltX"] == "-72"
    assert move_by["tiltY"] == "9"
    assert move_by["twist"] == "86"
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def properties(element):
    kv = element.text.split(' ', 1)[1].split(', ')
    return {x[0]:x[1] for x in list(map(lambda item: item.split(': '), kv))}
```

```cs
            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs#L64-L77)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class PenTest : BaseChromeTest
    {
        [TestMethod]
        public void UsePen()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        [TestMethod]
        public void SetPointerEventProperties()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual((-72).ToString(), moveBy["tiltX"]);
            Assert.AreEqual((9).ToString(), moveBy["tiltY"]);
            Assert.AreEqual((86).ToString(), moveBy["twist"]);
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        private Dictionary<string, string> getProperties(IWebElement element)
        {
            var str = element.Text;
            str = str[(str.Split()[0].Length + 1)..];
            IEnumerable<string[]> keyValue = str.Split(", ").Select(part => part.Split(":"));
            return keyValue.ToDictionary(split => split[0].Trim(), split => split[1].Trim());
        }

        private bool VerifyEquivalent(decimal expected, string actual)
        {
            var absolute = Math.Abs(expected - decimal.Parse(actual));
            if (absolute <= 1)
            {
                return true;
            }

            throw new Exception("Expected: " + expected + "; but received: " + actual);
        }
    }
}
```

```rb
    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/pen_spec.rb#L50-L56)

##### /examples/ruby/spec/actions\_api/pen\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Pen' do
  let(:driver) { start_session }

  it 'uses a pen' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  it 'sets pointer event attributes' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s,
                               'tiltX' => -72.to_s,
                               'tiltY' => 9.to_s,
                               'twist' => 86.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  def properties(element)
    element.text.sub(/.*?\s/, '').split(',').to_h { |item| item.lstrip.split(/\s*:\s*/) }
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/PenTest.kt#L64-L78)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/PenTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import kotlin.collections.Map
import java.time.Duration

class PenTest : BaseTest() {
  
    @Test
    fun usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
    }

    @Test
    fun setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY")) 
	    
        Assertions.assertEquals("-72", moveBy.get("tiltX"))
        Assertions.assertEquals("9", moveBy.get("tiltY"))
        Assertions.assertEquals("86", moveBy.get("twist"))
    }
    
    fun getPropertyInfo(element: WebElement): Map<String, String> {
        var text = element.getText()  
        text = text.substring(text.indexOf(" ")+1)
        return text.split(", ")
        .map { it.split(": ") }
        .map { it.first() to it.last() }
        .toMap() 
    }
}
```

```java
        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L17-L20)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L11-L14)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L11-L14)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L16-L19)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L18-L21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L29-L33)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L22-L26)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L31-L35)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L22-L26)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L26-L31)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L30-L34)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L42-L46)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L35-L39)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L46-L53)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L34-L38)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L40-L44)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L43-L47)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L57-L61)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L50-L54)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L66-L75)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L57-L61)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L62-L66)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L59-L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L73-L76)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L66-L70)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L89-L97)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L63-L66)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L75-L77)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L75-L78)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

----
url: https://www.selenium.dev/documentation/webdriver/bidi/w3c/script/
----

# Script

```java
        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));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L52-L75)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L32-L53)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L201-L210)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L202-L204)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L219-L229)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L222-L227)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L239-L242)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L237-L239)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L280-L283)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L279-L283)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L293-L299)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L292-L299)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            script.disownBrowsingContextScript(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L322-L322)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    await manager.disownBrowsingContextScript(id, boxId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L330-L330)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            script.disownRealmScript(realmId, List.of(boxId));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L375-L375)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    await manager.disownRealmScript(realmId, boxId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L372-L372)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L391-L392)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L383-L385)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L401-402)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L393-L395)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L411-412)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L403-L405)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L422-423)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L416-L416)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L463-463)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L424-L426)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
                script.removePreloadScript(id);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L486-486)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    await manager.removePreloadScript(scriptId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L471-L471)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L37-L51)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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,
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L26-L43)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L58-L68)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L52-L65)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L75-L85)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.19](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.19.0)

```js
    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()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L73-L86)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

[Add Example](/documentation/about/contributing/#creating-examples)

----
url: https://www.selenium.dev/documentation/grid/advanced_features/
----

# Advanced features of Selenium

To get all the details of the advanced features, understand how it works, and how to set up your own, please browse thorough the following sections.

***

##### [Observability in Selenium Grid](/documentation/grid/advanced_features/observability/)

##### [GraphQL query support](/documentation/grid/advanced_features/graphql_support/)

##### [Grid endpoints](/documentation/grid/advanced_features/endpoints/)

##### [Customizing a Node](/documentation/grid/advanced_features/customize_node/)

##### [External datastore](/documentation/grid/advanced_features/external_datastore/)

----
url: https://www.selenium.dev/documentation/test_practices/
----

# Test Practices

Some guidelines and recommendations on testing from the Selenium project.

A note on “Best Practices”: We’ve intentionally avoided the phrase “Best Practices” in this documentation. No one approach works for all situations. We prefer the idea of “Guidelines and Recommendations.” We encourage you to read through these and thoughtfully decide what approaches will work for you in your particular environment.

Functional testing is challenging to get right for many reasons. As if application state, complexity, and dependencies do not make testing difficult enough, dealing with browsers (especially with cross-browser incompatibilities) makes writing good tests a challenge.

Selenium provides tools to make functional user interaction easier, but does not help you write well-architected test suites. In this chapter, we offer advice, guidelines, and recommendations on how to approach functional web page automation.

This chapter records software design patterns popular amongst many of the users of Selenium that have proven successful over the years.

***

##### [Design patterns and development strategies](/documentation/test_practices/design_strategies/)

##### [Overview of Test Automation](/documentation/test_practices/overview/)

##### [Types of Testing](/documentation/test_practices/testing_types/)

##### [Encouraged behaviors](/documentation/test_practices/encouraged/)

Some guidelines and recommendations on testing from the Selenium project.

##### [Discouraged behaviors](/documentation/test_practices/discouraged/)

Things to avoid when automating browsers with Selenium.

Last modified October 19, 2022: [Update \_index.en.md (#1202) (e2c7842631d)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e2c7842631de88339868f3d8f960b0ed7a1702b6)

----
url: https://www.selenium.dev/documentation/legacy/selenium_3/grid_components/
----

# Components of Grid 3

----
url: https://www.selenium.dev/zh-cn/documentation/grid/configuration/
----

# 配置组件

在这里，您可以看到如何根据公共配置值和特定于组件的配置值分别配置每个网格组件.

***

##### [配置帮助](/zh-cn/documentation/grid/configuration/help/)

获取有关配置网格的所有可用选项的信息.

##### [CLI 选项](/zh-cn/documentation/grid/configuration/cli_options/)

所有网格组件配置CLI选项的详细信息.

##### [Toml配置选项](/zh-cn/documentation/grid/configuration/toml_options/)

使用Toml文件的Grid配置示例.

----
url: https://www.selenium.dev/zh-cn/documentation/legacy/selenium_2/remote_server/
----

# 远程WebDriver服务器

服务器将始终在安装了待测浏览器的机器上运行. 可以从命令行或通过代码配置来使用服务器.

## 从命令行启动服务器

下载 `selenium-server-standalone-{VERSION}.jar` 后, 将其传到具有待测浏览器的电脑上. 然后, 切换到包含此jar文件的目录中, 运行以下命令:

```shell
java -jar selenium-server-standalone-{VERSION}.jar
```

## 运行服务器的注意事项

调用者应调用 `Selenium#stop()` 或 `WebDriver#quit` 以结束每次会话.

Selenium服务器在内存中保留每个运行会话的日志, 这些日志将在调用 `Selenium#stop()` 或 `WebDriver#quit` 时清除. 如果您忘记终止这些会话, 则可能会造成服务器内存泄漏. 如果您保持运行时间非常长的会话, 则可能需要不时执行停止或退出的操作 (或使用-Xmx jvm选项增加内存) .

## 超时 (自2.21版本)

服务器有两种不同的超时, 可以按如下设置:

```shell
java -jar selenium-server-standalone-{VERSION}.jar -timeout=20 -browserTimeout=60
```

```java
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.security.SslSocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;

import javax.servlet.Servlet;
import java.io.File;

import org.openqa.selenium.remote.server.DriverServlet;

public class AppServer {
  private Server server = new Server();

  public AppServer() throws Exception {
    WebAppContext context = new WebAppContext();
    context.setContextPath("");
    context.setWar(new File("."));
    server.addHandler(context);

    context.addServlet(DriverServlet.class, "/wd/*");

    SelectChannelConnector connector = new SelectChannelConnector();
    connector.setPort(3001);
    server.addConnector(connector);

    server.start();
  }
}
```

----
url: https://www.selenium.dev/documentation/legacy/selenium_2/ssl_certs/
----

# Untrusted SSL Certificates

```
WdCertOverrideService.prototype.hasMatchingOverride = function(
    aHostName, aPort, aCert, aOverrideBits, aIsTemporary)
```

The aOverrideBits and aIsTemporary are output arguments. This is where things get a bit tricky: There are three possible override bits:

```
  ERROR_UNTRUSTED: 1,
  ERROR_MISMATCH: 2,
  ERROR_TIME: 4
```

It’s impossible to just set them all, since Firefox expects a perfect match between the offences generated by the certificate and the function’s return value: (security/manager/ssl/src/SSLServerCertVerification.cpp:302):

```
  if (overrideService)
  {
    PRBool haveOverride;
    PRBool isTemporaryOverride; // we don't care
  
    nsrv = overrideService->HasMatchingOverride(hostString, port,
                                                ix509, 
                                                &overrideBits,
                                                &isTemporaryOverride, 
                                                &haveOverride);
    if (NS_SUCCEEDED(nsrv) && haveOverride) 
    {
      // remove the errors that are already overriden
      remaining_display_errors -= overrideBits;
    }
  }

  if (!remaining_display_errors) {
    // all errors are covered by override rules, so let's accept the cert
    return SECSuccess;
  }
```

The exact mapping of violation to error code can be easily seen at security/manager/pki/resources/content/exceptionDialog.js (in Firefox source):

```
  var flags = 0;
  if(gSSLStatus.isUntrusted)
    flags |= overrideService.ERROR_UNTRUSTED;
  if(gSSLStatus.isDomainMismatch)
    flags |= overrideService.ERROR_MISMATCH;
  if(gSSLStatus.isNotValidAtThisTime)
    flags |= overrideService.ERROR_TIME;
```

The SSL status can be obtained from `"@mozilla.org/security/recentbadcerts;1"` usually - However, the certificate (and its status) are added to this service only **after** the call to `hasMatchingOverride`, so there is no easy way to find out the certificate’s SSLStatus. Instead, the checks have to be executed manually.

Two checks are carried out:

* Calling `nsIX509Cert.verifyForUsage`
* Comparing hostname against `nsIX509Cert.commonName`. If those are not equal, `ERROR_MISMATCH` is set.

The second check indicates whether `ERROR_MISMATCH` should be set. The first check should indicate whether `ERROR_UNTRUSTED` and `ERROR_TIME` should be set. Unfortunately, it does not work reliably when the certificate expired **and** is from an untrusted issuer. When the certificate has expired, the return code would be `CERT_EXPIRED` even if it is also untrusted. For this reason, the FirefoxDriver assumes that certificates will be untrusted - it **always** sets the `ERROR_UNTRUSTED` bit - the other two will be set only if the conditions for them are met.

This could pose a problem for someone testing a site with a valid certificate that does not match the host name it’s served from (e.g. test environment serving production certificates). An additional feature for `FirefoxProfile` was added: `FirefoxProfile.setAssumeUntrustedCertificateIssuer`. Calling this function with `false` will turn the `ERROR_UNTRUSTED` bit off and allow a user to work in such situation.

## HTMLUnit

Not tested yet.

## IE

Not implemented yet.

## Chrome

Not implemented yet.

----
url: https://www.selenium.dev/documentation/webdriver/interactions/
----

# Browser interactions

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java#L15)

##### /examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class InteractionsTest extends BaseChromeTest {
    @Test
    public void getTitle() {
        driver.get("https://www.selenium.dev/");
        // get title
        String title = driver.getTitle();
        Assertions.assertEquals(title, "Selenium");
    }

    @Test
    public void getCurrentUrl() {
        driver.get("https://www.selenium.dev/");
        // get current url
        String url = driver.getCurrentUrl();
        Assertions.assertEquals(url, "https://www.selenium.dev/");
    }
}
```

```py
title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_interactions.py#L7)

##### /examples/python/tests/interactions/test\_interactions.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")

title = driver.title
assert title == "Selenium"

url = driver.current_url
assert url == "https://www.selenium.dev/"

driver.quit()
```

```cs
            String title = driver.Title;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs#L37)

##### /examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class InteractionsTest
    {
        [TestMethod]
        public void TestInteractions()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url="https://www.selenium.dev/";
            //GetTitle
            String title = driver.Title;
            Assert.AreEqual(title, "Selenium");

            //GetCurrentURL
            String url = driver.Url;
            Assert.AreEqual(url, "https://www.selenium.dev/");

            //quitting driver
            driver.Quit(); //close all windows
        }
    }
}
```

```rb
  it 'gets the current title' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/browser_spec.rb#L8)

##### /examples/ruby/spec/interactions/browser\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'gets the current title' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_title = driver.title
    expect(current_title).to eq 'Selenium'
  end

  it 'gets the current url' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_url = driver.current_url
    expect(current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    let title = await driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/interactionsIndex.spec.js#L20)

##### /examples/javascript/test/interactions/interactionsIndex.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Should be able to get title and current url', async function () {
    const url = 'https://www.selenium.dev/';
    await driver.get(url);

    //Get Current title
    let title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Get Current url
    let currentUrl = await driver.getCurrentUrl();
    assert.equal(currentUrl, url);
  });
});
```

```kotlin
driver.title
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java#L26)

##### /examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class InteractionsTest extends BaseChromeTest {
    @Test
    public void getTitle() {
        driver.get("https://www.selenium.dev/");
        // get title
        String title = driver.getTitle();
        Assertions.assertEquals(title, "Selenium");
    }

    @Test
    public void getCurrentUrl() {
        driver.get("https://www.selenium.dev/");
        // get current url
        String url = driver.getCurrentUrl();
        Assertions.assertEquals(url, "https://www.selenium.dev/");
    }
}
```

```py
url = driver.current_url
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_interactions.py#L10)

##### /examples/python/tests/interactions/test\_interactions.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")

title = driver.title
assert title == "Selenium"

url = driver.current_url
assert url == "https://www.selenium.dev/"

driver.quit()
```

```cs
            String url = driver.Url;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs#L41)

##### /examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class InteractionsTest
    {
        [TestMethod]
        public void TestInteractions()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url="https://www.selenium.dev/";
            //GetTitle
            String title = driver.Title;
            Assert.AreEqual(title, "Selenium");

            //GetCurrentURL
            String url = driver.Url;
            Assert.AreEqual(url, "https://www.selenium.dev/");

            //quitting driver
            driver.Quit(); //close all windows
        }
    }
}
```

```rb
  it 'gets the current url' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/browser_spec.rb#L14)

##### /examples/ruby/spec/interactions/browser\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'gets the current title' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_title = driver.title
    expect(current_title).to eq 'Selenium'
  end

  it 'gets the current url' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_url = driver.current_url
    expect(current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    let currentUrl = await driver.getCurrentUrl();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/interactionsIndex.spec.js#L24)

##### /examples/javascript/test/interactions/interactionsIndex.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Should be able to get title and current url', async function () {
    const url = 'https://www.selenium.dev/';
    await driver.get(url);

    //Get Current title
    let title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Get Current url
    let currentUrl = await driver.getCurrentUrl();
    assert.equal(currentUrl, url);
  });
});
```

```kotlin
driver.currentUrl
```

***

##### [Browser navigation](/documentation/webdriver/interactions/navigation/)

##### [JavaScript alerts, prompts and confirmations](/documentation/webdriver/interactions/alerts/)

##### [Working with cookies](/documentation/webdriver/interactions/cookies/)

##### [Working with IFrames and frames](/documentation/webdriver/interactions/frames/)

##### [Print Page](/documentation/webdriver/interactions/print_page/)

##### [Working with windows and tabs](/documentation/webdriver/interactions/windows/)

##### [Virtual Authenticator](/documentation/webdriver/interactions/virtual_authenticator/)

A representation of the Web Authenticator model.

----
url: https://www.selenium.dev/documentation/about/
----

# About this documentation

These docs, like the code itself, are maintained 100% by volunteers within the Selenium community. Many have been using it since its inception, but many more have only been using it for a short while, and have given their time to help improve the onboarding experience for new users.

If there is an issue with the documentation, we want to know! The best way to communicate an issue is to visit [https://github.com/seleniumhq/seleniumhq.github.io/issues](//github.com/seleniumhq/seleniumhq.github.io/issues) and search to see whether or not the issue has been filed already. If not, feel free to open one!

Many members of the community are present at the #selenium-docs channel of [Selenium Slack Group](https://inviter.co/seleniumhq). Feel free to drop in and ask questions and if you get help which you think could be of use within these documents, be sure to add your contribution! We can update these documents, but it is much easier for everyone when we get contributions from outside the normal committers.

***

##### [Copyright and attributions](/documentation/about/copyright/)

Copyright, contributions and all attributions for the different projects under the Selenium umbrella.

##### [Contributing to the Selenium site & documentation](/documentation/about/contributing/)

Information on improving documentation and code examples for Selenium

##### [Style guide for Selenium documentation](/documentation/about/style/)

Conventions for contributions to the Selenium documentation and code examples

##### [Musings about how things came to be](/documentation/about/history/)

Details mostly of interest to Selenium devs about how and why certain parts of the project were created

Last modified October 29, 2025: [updated libre chat to selenium slack (#2516) (8f6592219c0)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/8f6592219c0a95a05e238aea2f5ba137fdf7127c)

----
url: https://www.selenium.dev/pt-br/_print/documentation/webdriver/bidi/cdp/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/webdriver/bidi/cdp/).

# Chrome DevTools Protocol

Examples of working with Chrome DevTools Protocol in Selenium. CDP support is temporary until WebDriver BiDi has been implemented.

* 1: [Chrome DevTools Logging Features](#pg-1db7a43e76c32ae52e42bc79e9622d68)
* 2: [Chrome DevTools Network Features](#pg-e593e88ce549f4fa0d392cc84509f012)
* 3: [Chrome DevTools Script Features](#pg-b4fdfcbe35936559487960c32fcb0b08)

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/CdpTest.java#L22-L27)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/CdpTest.java

```java
package dev.selenium.bidi.cdp;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chromium.HasCdp;

import java.util.HashMap;
import java.util.Map;

public class CdpTest extends BaseTest {
  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
  }

  @Test
  public void setCookie() {
    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);

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }
}
```

```py
    cookie = {'name': 'cheese',
              'value': 'gouda',
              'domain': 'www.selenium.dev',
              'secure': True}

    driver.execute_cdp_cmd('Network.setCookie', cookie)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_cdp.py#L2-L7)

##### /examples/python/tests/bidi/cdp/test\_cdp.py

```py
def test_set_cookie(driver):
    cookie = {'name': 'cheese',
              'value': 'gouda',
              'domain': 'www.selenium.dev',
              'secure': True}

    driver.execute_cdp_cmd('Network.setCookie', cookie)

    driver.get('https://www.selenium.dev')
    cheese = driver.get_cookie(cookie['name'])

    assert cheese['value'] == 'gouda'
```

```cs
            var cookie = new Dictionary<string, object>
            {
                { "name", "cheese" },
                { "value", "gouda" },
                { "domain", "www.selenium.dev" },
                { "secure", true }
            };
            ((ChromeDriver)driver).ExecuteCdpCommand("Network.setCookie", cookie);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/CDPTest.cs#L14-L21)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/CDPTest.cs

```cs
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class CDPTest : BaseChromeTest
    {
        [TestMethod]
        public void SetCookie()
        {
            var cookie = new Dictionary<string, object>
            {
                { "name", "cheese" },
                { "value", "gouda" },
                { "domain", "www.selenium.dev" },
                { "secure", true }
            };
            ((ChromeDriver)driver).ExecuteCdpCommand("Network.setCookie", cookie);
            
            driver.Url = "https://www.selenium.dev";
            Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);

        }
    }
}
```

```rb
    driver.execute_cdp('Network.setCookie',
                       name: 'cheese',
                       value: 'gouda',
                       domain: 'www.selenium.dev',
                       secure: true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/cdp_spec.rb#L9-L13)

##### /examples/ruby/spec/bidi/cdp/cdp\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'sets cookie' do
    driver.execute_cdp('Network.setCookie',
                       name: 'cheese',
                       value: 'gouda',
                       domain: 'www.selenium.dev',
                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end
end
```

```java
    ((HasLogEvents) driver).onLogEvent(consoleEvent(e -> messages.add(e.getMessages().get(0))));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/LoggingTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/LoggingTest.java

```java
package dev.selenium.bidi.cdp;

import static org.openqa.selenium.devtools.events.CdpEventTypes.consoleEvent;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.CopyOnWriteArrayList;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.HasLogEvents;
import org.openqa.selenium.support.ui.WebDriverWait;

public class LoggingTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void consoleLogs() {
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    CopyOnWriteArrayList<String> messages = new CopyOnWriteArrayList<>();

    ((HasLogEvents) driver).onLogEvent(consoleEvent(e -> messages.add(e.getMessages().get(0))));

    driver.findElement(By.id("consoleLog")).click();
    driver.findElement(By.id("consoleError")).click();

    wait.until(_d -> messages.size() > 1);
    Assertions.assertTrue(messages.contains("Hello, world!"));
    Assertions.assertTrue(messages.contains("I am console error"));
  }
}
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_logs.py#L11-12)

##### /examples/python/tests/bidi/cdp/test\_logs.py

```py
import pytest
from selenium.webdriver.common.bidi.console import Console
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log


@pytest.mark.trio
async def test_console_log(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
            driver.find_element(by=By.ID, value='consoleLog').click()

        assert messages["message"] == "Hello, world!"


@pytest.mark.trio
async def test_js_error(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
            driver.find_element(by=By.ID, value='jsException').click()

        assert "Error: Not working" in messages.exception_details.exception.description
```

```cs
            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs#L19-L25)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class LoggingTest : BaseChromeTest
    {
        [TestMethod]
        public async Task ConsoleLogs()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("consoleLog")).Click();
            driver.FindElement(By.Id("consoleError")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => messages.Count > 1);
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Hello, world!"));
            Assert.IsTrue(messages.Contains("I am console error"));
        }
        
        [TestMethod]
        public async Task JsErrors()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("jsException")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !messages.IsNullOrEmpty());
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Uncaught"));
        }
    }
}
```

```rb
    driver.on_log_event(:console) { |log| logs << log.args.first }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/logging_spec.rb#L12)

##### /examples/ruby/spec/bidi/cdp/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'listens for console logs' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    logs = []
    driver.on_log_event(:console) { |log| logs << log.args.first }

    driver.find_element(id: 'consoleLog').click
    driver.find_element(id: 'consoleError').click

    Selenium::WebDriver::Wait.new.until { logs.size > 1 }
    expect(logs).to include 'Hello, world!'
    expect(logs).to include 'I am console error'
  end

  it 'listens for js exception' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    exceptions = []
    driver.on_log_event(:exception) { |exception| exceptions << exception }

    driver.find_element(id: 'jsException').click

    Selenium::WebDriver::Wait.new.until { exceptions.any? }
    expect(exceptions.first&.description).to include 'Error: Not working'
  end
end
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_logs.py#L22-L23)

##### /examples/python/tests/bidi/cdp/test\_logs.py

```py
import pytest
from selenium.webdriver.common.bidi.console import Console
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log


@pytest.mark.trio
async def test_console_log(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
            driver.find_element(by=By.ID, value='consoleLog').click()

        assert messages["message"] == "Hello, world!"


@pytest.mark.trio
async def test_js_error(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
            driver.find_element(by=By.ID, value='jsException').click()

        assert "Error: Not working" in messages.exception_details.exception.description
```

```cs
            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs#L41-L47)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class LoggingTest : BaseChromeTest
    {
        [TestMethod]
        public async Task ConsoleLogs()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("consoleLog")).Click();
            driver.FindElement(By.Id("consoleError")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => messages.Count > 1);
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Hello, world!"));
            Assert.IsTrue(messages.Contains("I am console error"));
        }
        
        [TestMethod]
        public async Task JsErrors()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("jsException")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !messages.IsNullOrEmpty());
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Uncaught"));
        }
    }
}
```

```rb
    driver.on_log_event(:exception) { |exception| exceptions << exception }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/logging_spec.rb#L26)

##### /examples/ruby/spec/bidi/cdp/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'listens for console logs' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    logs = []
    driver.on_log_event(:console) { |log| logs << log.args.first }

    driver.find_element(id: 'consoleLog').click
    driver.find_element(id: 'consoleError').click

    Selenium::WebDriver::Wait.new.until { logs.size > 1 }
    expect(logs).to include 'Hello, world!'
    expect(logs).to include 'I am console error'
  end

  it 'listens for js exception' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    exceptions = []
    driver.on_log_event(:exception) { |exception| exceptions << exception }

    driver.find_element(id: 'jsException').click

    Selenium::WebDriver::Wait.new.until { exceptions.any? }
    expect(exceptions.first&.description).to include 'Error: Not working'
  end
end
```

```java
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L41-L43)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
        credentials = base64.b64encode("admin:admin".encode()).decode()
        auth = {'authorization': 'Basic ' + credentials}
        await connection.session.execute(connection.devtools.network.set_extra_http_headers(Headers(auth)))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L13-15)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L25-L32)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L9-L11)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      HttpResponse res = next.execute(req);
                      contentType.add(res.getHeader("Content-Type"));
                      return res;
                    })) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L56-L65)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L46-L51)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L20-L24)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    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!"))))) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L75-L85)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L62-L73)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L31-L35)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L97-L110)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L85-L97)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    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
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L42-L46)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L125-L126)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    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())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L26-L28)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L114-L118)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L56-L57)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    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()));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L142-L157)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L37-L44)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L136-L143)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L68-L71)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    devTools.send(
            Browser.setDownloadBehavior(
                    Browser.SetDownloadBehaviorBehavior.ALLOWANDNAME,
                    Optional.empty(),
                    Optional.of(""),
                    Optional.of(true)));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L171-L176)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    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
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L82-L88)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    ScriptKey key = ((JavascriptExecutor) driver).pin("return arguments;");
    List<Object> arguments =
        (List<Object>) ((JavascriptExecutor) driver).executeScript(key, 1, true, element);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/ScriptTest.java#L32-L34)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/ScriptTest.java

```java
package dev.selenium.bidi.cdp;

import static org.openqa.selenium.devtools.events.CdpEventTypes.domMutation;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.HasLogEvents;
import org.openqa.selenium.support.ui.WebDriverWait;

public class ScriptTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void pinScript() {
    driver.get("https://www.selenium.dev/selenium/web/xhtmlTest.html");
    WebElement element = driver.findElement(By.id("id1"));

    ScriptKey key = ((JavascriptExecutor) driver).pin("return arguments;");
    List<Object> arguments =
        (List<Object>) ((JavascriptExecutor) driver).executeScript(key, 1, true, element);

    Assertions.assertEquals(List.of(1L, true, element), arguments);
  }

  @Test
  public void mutatedElements() {
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    CopyOnWriteArrayList<WebElement> mutations = new CopyOnWriteArrayList<>();

    ((HasLogEvents) driver).onLogEvent(domMutation(e -> mutations.add(e.getElement())));

    driver.findElement(By.id("reveal")).click();

    wait.until(_d -> !mutations.isEmpty());
    Assertions.assertEquals(mutations.get(0), driver.findElement(By.id("revealed")));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs#L21-L22)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs

```cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class ScriptTest : BaseChromeTest
    {
        [TestMethod]
        public async Task PinScript()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/xhtmlTest.html";
            var element = driver.FindElement(By.Id("id1"));

            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);

            var expected = new List<object>
            {
                1L,
                true,
                element
            };
            CollectionAssert.AreEqual(expected, (ICollection)arguments);
        }

        [TestMethod]
        public async Task MutatedElements()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            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();

            driver.FindElement(By.Id("reveal")).Click();
            
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !mutations.IsNullOrEmpty());
            await monitor.DisableDomMutationMonitoring();
            monitor.StopEventMonitoring();

            var revealed = driver.FindElement(By.Id("revealed")); 
            Assert.AreEqual(revealed, mutations[0]);
        }
    }
}
```

```rb
    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/script_spec.rb#L12-L13)

##### /examples/ruby/spec/bidi/cdp/script\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Script' do
  let(:driver) { start_session }

  it 'pins script' do
    driver.get('https://www.selenium.dev/selenium/web/xhtmlTest.html')
    element = driver.find_element(id: 'id1')

    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)

    expect(arguments).to eq([1, true, element])
  end

  it 'gets mutated elements' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'

    mutations = []
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }

    driver.find_element(id: 'reveal').click
    Selenium::WebDriver::Wait.new(timeout: 30).until { mutations.any? }

    expect(mutations).to include(driver.find_element(id: 'revealed'))
  end
end
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).mutation_events() as event:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_script.py#L10-L11)

##### /examples/python/tests/bidi/cdp/test\_script.py

```py
import pytest
import trio
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

@pytest.mark.trio
async def test_mutation(driver):
    async with driver.bidi_connection() as session:
        async with Log(driver, session).mutation_events() as event:
            await trio.to_thread.run_sync(lambda: driver.get('https://www.selenium.dev/selenium/web/dynamic.html'))
            await trio.to_thread.run_sync(lambda: WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "reveal"))))
            await trio.to_thread.run_sync(lambda: driver.find_element(By.ID, "reveal").click())

    assert event["element"] == driver.find_element(By.ID, "revealed")
```

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs#L39-L46)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs

```cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class ScriptTest : BaseChromeTest
    {
        [TestMethod]
        public async Task PinScript()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/xhtmlTest.html";
            var element = driver.FindElement(By.Id("id1"));

            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);

            var expected = new List<object>
            {
                1L,
                true,
                element
            };
            CollectionAssert.AreEqual(expected, (ICollection)arguments);
        }

        [TestMethod]
        public async Task MutatedElements()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            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();

            driver.FindElement(By.Id("reveal")).Click();
            
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !mutations.IsNullOrEmpty());
            await monitor.DisableDomMutationMonitoring();
            monitor.StopEventMonitoring();

            var revealed = driver.FindElement(By.Id("revealed")); 
            Assert.AreEqual(revealed, mutations[0]);
        }
    }
}
```

```rb
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/script_spec.rb#L22)

##### /examples/ruby/spec/bidi/cdp/script\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Script' do
  let(:driver) { start_session }

  it 'pins script' do
    driver.get('https://www.selenium.dev/selenium/web/xhtmlTest.html')
    element = driver.find_element(id: 'id1')

    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)

    expect(arguments).to eq([1, true, element])
  end

  it 'gets mutated elements' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'

    mutations = []
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }

    driver.find_element(id: 'reveal').click
    Selenium::WebDriver::Wait.new(timeout: 30).until { mutations.any? }

    expect(mutations).to include(driver.find_element(id: 'revealed'))
  end
end
```

----
url: https://www.selenium.dev/documentation/webdriver/browsers/
----

# Supported Browsers

Each browser has custom capabilities and unique features.

***

##### [Chrome specific functionality](/documentation/webdriver/browsers/chrome/)

These are capabilities and features specific to Google Chrome browsers.

##### [Edge specific functionality](/documentation/webdriver/browsers/edge/)

These are capabilities and features specific to Microsoft Edge browsers.

##### [Firefox specific functionality](/documentation/webdriver/browsers/firefox/)

These are capabilities and features specific to Mozilla Firefox browsers.

##### [IE specific functionality](/documentation/webdriver/browsers/internet_explorer/)

These are capabilities and features specific to Microsoft Internet Explorer browsers.

##### [Safari specific functionality](/documentation/webdriver/browsers/safari/)

These are capabilities and features specific to Apple Safari browsers.

Last modified March 16, 2025: [\[browser\] remove arabic workaround (#2218)\[deploy site\] (57164eff4c5)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/57164eff4c5927e121ce069534cfbad62fb8133b)

----
url: https://www.selenium.dev/documentation/grid/architecture/
----

# Grid architecture

|               | Event Bus | Distributor | Node | Router | Session Map | Session Queue |
| ------------- | --------- | ----------- | ---- | ------ | ----------- | ------------- |
| Event Bus     | X         |             |      |        |             |               |
| Distributor   | ✅         | X           | ✅    |        |             | ✅             |
| Node          | ✅         |             | X    |        |             |               |
| Router        |           |             | ✅    | X      | ✅           |               |
| Session Map   |           |             |      |        | X           |               |
| Session Queue | ✅         |             |      |        |             | X             |

| Name               | Type    | Description                                                                                                                                                                                                                                  |
| ------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| availability       | string  | A string which is one of `up`, `draining`, or `down`. The important one is `draining`, which indicates that no new sessions should be sent to the Node, and once the last session on it closes, the Node will exit or restart.               |
| externalUrl        | string  | The URI that the other components in the Grid should connect to.                                                                                                                                                                             |
| lastSessionCreated | integer | The epoch timestamp of when the last session was created on this Node. The Distributor will attempt to send new sessions to the Node that has been idle longest if all other things are equal.                                               |
| maxSessionCount    | integer | Although a session count can be inferred by counting the number of available slots, this integer value is used to determine the maximum number of sessions that should be running simultaneously on the Node before it is considered “full”. |
| nodeId             | string  | A UUID used to identify this instance of the Node.                                                                                                                                                                                           |
| osInfo             | object  | An object with `arch`, `name`, and `version` fields. This is used by the Grid UI and the GraphQL queries.                                                                                                                                    |
| slots              | array   | An array of Slot objects (described below)                                                                                                                                                                                                   |
| version            | string  | The version of the Node (for Selenium, this will match the Selenium version number)                                                                                                                                                          |

It is recommended to put values in all fields.

### The Slot Object

The Slot object represents a single slot within a Node. A “slot” is where a single session may be run. It is possible that a Node will have more slots than it can run concurrently. For example, a node may be able to run up 10 sessions, but they could be any combination of Chrome, Edge, or Firefox; in this case, the Node would indicate a “max session count” of 10, and then also say it has 10 slots for Chrome, 10 for Edge, and 10 for Firefox.

| Name        | Type   | Description                                                                                                                                                                  |
| ----------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id          | string | UUID to refer to the slot                                                                                                                                                    |
| lastStarted | string | When the slot last had a session started, in ISO-8601 format                                                                                                                 |
| stereotype  | object | The minimal set of [capabilities](https://w3c.github.io/webdriver/#dfn-merging-capabilities) this slot will match against. A minimal example is `{"browserName": "firefox"}` |
| session     | object | The Session object (see below)                                                                                                                                               |

### The Session Object

This represents a running session within a slot

| Name         | Type   | Description                                                                                                                                                                  |
| ------------ | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| capabilities | object | The actual capabilities provided by the session. Will match the return value from the [new session](https://w3c.github.io/webdriver/#new-session) command                    |
| startTime    | string | The start time of the session in ISO-8601 format                                                                                                                             |
| stereotype   | object | The minimal set of [capabilities](https://w3c.github.io/webdriver/#dfn-merging-capabilities) this slot will match against. A minimal example is `{"browserName": "firefox"}` |
| uri          | string | The URI used by the Node to communicate with the session                                                                                                                     |

Last modified August 29, 2022: [Updating Grid architecture (9df8227bc4c)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/9df8227bc4c6065cd41406a239e3b3c527191456)

----
url: https://www.selenium.dev/_print/documentation/test_practices/discouraged/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/test_practices/discouraged/).

# Discouraged behaviors

Things to avoid when automating browsers with Selenium.

* 1: [Captchas](#pg-3b5620c52a2bef6c4d263b6166817252)
* 2: [File downloads](#pg-412b120e2f3e7939c790abf3c78fe23c)
* 3: [HTTP response codes](#pg-b10eceb097750b67d81f2781a6a7826c)
* 4: [Gmail, email and Facebook logins](#pg-f94ff72a0e04621b23443ef2c2946b5c)
* 5: [Test dependency](#pg-592156e95c121f26c09a41092841d50b)
* 6: [Performance testing](#pg-ca2d7e5feff08f93a1b71dd68ea8bba8)
* 7: [Link spidering](#pg-7093b50bd3c1a0db58ef8ce55b3bc209)
* 8: [Two Factor Authentication](#pg-224ad84522a037ac1a20e467084f55e5)

# 1 - Captchas

CAPTCHA, short for *Completely Automated Public Turing test to tell Computers and Humans Apart*, is explicitly designed to prevent automation, so do not try! There are two primary strategies to get around CAPTCHA checks:

* Disable CAPTCHAs in your test environment
* Add a hook to allow tests to bypass the CAPTCHA

# 2 - File downloads

Whilst it is possible to start a download by clicking a link with a browser under Selenium’s control, the API does not expose download progress, making it less than ideal for testing downloaded files. This is because downloading files is not considered an important aspect of emulating user interaction with the web platform. Instead, find the link using Selenium (and any required cookies) and pass it to a HTTP request library like [curl](https:////curl.se/).

The [HtmlUnit driver](https://github.com/SeleniumHQ/htmlunit-driver) can download attachments by accessing them as input streams by implementing the [AttachmentHandler](https://htmlunit.sourceforge.io/apidocs/com/gargoylesoftware/htmlunit/attachment/AttachmentHandler.html) interface. The AttachmentHandler can then be added to the [HtmlUnit](https://htmlunit.sourceforge.io/) WebClient.

# 3 - HTTP response codes

For some browser configurations in Selenium RC, Selenium acted as a proxy between the browser and the site being automated. This meant that all browser traffic passed through Selenium could be captured or manipulated. The `captureNetworkTraffic()` method purported to capture all of the network traffic between the browser and the site being automated, including HTTP response codes.

Selenium WebDriver is a completely different approach to browser automation, preferring to act more like a user. This is represented in the way you write tests with WebDriver. In automated functional testing, checking the status code is not a particularly important detail of a test’s failure; the steps that preceded it are more important.

The browser will always represent the HTTP status code, imagine for example a 404 or a 500 error page. A simple way to “fail fast” when you encounter one of these error pages is to check the page title or content of a reliable point (e.g. the `<h1>` tag) after every page load. If you are using the page object model, you can include this check in your class constructor or similar point where the page load is expected. Occasionally, the HTTP code may even be represented in the browser’s error page and you could use WebDriver to read this and improve your debugging output.

Checking the webpage itself is in line with WebDriver’s ideal practice of representing and asserting upon the user’s view of the website.

If you insist, an advanced solution to capturing HTTP status codes is to replicate the behaviour of Selenium RC by using a proxy. WebDriver API provides the ability to set a proxy for the browser, and there are a number of proxies that will programmatically allow you to manipulate the contents of requests sent to and received from the web server. Using a proxy lets you decide how you want to respond to redirection response codes. Additionally, not every browser makes the response codes available to WebDriver, so opting to use a proxy allows you to have a solution that works for every browser.

# 4 - Gmail, email and Facebook logins

For multiple reasons, logging into sites like Gmail and Facebook using WebDriver is not recommended. Aside from being against the usage terms for these sites (where you risk having the account shut down), it is slow and unreliable.

The ideal practice is to use the APIs that email providers offer, or in the case of Facebook the developer tools service which exposes an API for creating test accounts, friends and so forth. Although using an API might seem like a bit of extra hard work, you will be paid back in speed, reliability, and stability. The API is also unlikely to change, whereas webpages and HTML locators change often and require you to update your test framework.

Logging in to third party sites using WebDriver at any point of your test increases the risk of your test failing because it makes your test longer. A general rule of thumb is that longer tests are more fragile and unreliable.

WebDriver implementations that are [W3C conformant](//w3c.github.io/webdriver/webdriver-spec.html) also annotate the `navigator` object with a `WebDriver` property so that Denial of Service attacks can be mitigated.

# 5 - Test dependency

A common idea and misconception about automated testing is regarding a specific test order. Your tests should be able to run in **any** order, and not rely on other tests to complete in order to be successful.

# 6 - Performance testing

Performance testing using Selenium and WebDriver is generally not advised. Not because it is incapable, but because it is not optimised for the job and you are unlikely to get good results.

It may seem ideal to performance test in the context of the user but a suite of WebDriver tests are subjected to many points of external and internal fragility which are beyond your control; for example browser startup speed, speed of HTTP servers, response of third party servers that host JavaScript or CSS, and the instrumentation penalty of the WebDriver implementation itself. Variation at these points will cause variation in your results. It is difficult to separate the difference between the performance of your website and the performance of external resources, and it is also hard to tell what the performance penalty is for using WebDriver in the browser, especially if you are injecting scripts.

The other potential attraction is “saving time” — carrying out functional and performance tests at the same time. However, functional and performance tests have opposing objectives. To test functionality, a tester may need to be patient and wait for loading, but this will cloud the performance testing results and vice versa.

To improve the performance of your website, you will need to be able to analyse overall performance independent of environment differences, identify poor code practices, breakdown of performance of individual resources (i.e. CSS or JavaScript), in order to know what to improve. There are performance testing tools available that can do this job already, that provide reporting and analysis, and can even make improvement suggestions.

Example (open source) packages to use are: [JMeter](/)

# 7 - Link spidering

Using WebDriver to spider through links is not a recommended practice. Not because it cannot be done, but because WebDriver is definitely not the most ideal tool for this. WebDriver needs time to start up, and can take several seconds, up to a minute depending on how your test is written, just to get to the page and traverse through the DOM.

Instead of using WebDriver for this, you could save a ton of time by executing a [curl](https://curl.se/) command, or using a library such as BeautifulSoup since these methods do not rely on creating a browser and navigating to a page. You are saving tonnes of time by not using WebDriver for this task.

# 8 - Two Factor Authentication

----
url: https://www.selenium.dev/ja/documentation/webdriver/elements/finders/
----

# Web要素の検索

提供されたロケーターの値に基づいて要素を検索します。

Seleniumを使用する最も基本的な側面の1つは、操作する要素の参照を取得することです。 Seleniumは、要素を一意に識別するための多数の組み込み[ロケーター戦略](https://www.selenium.dev/ja/documentation/webdriver/elements/locators/)を提供します。 非常に高度なシナリオでロケーターを使用する方法はたくさんあります。 このドキュメントの目的のために、このHTMLスニペットについて考えてみましょう。

```html
<ol id="vegetables">
 <li class="potatoes">…
 <li class="onions">…
 <li class="tomatoes"><span>Tomato is a Vegetable</span>…
</ol>
<ul id="fruits">
  <li class="bananas">…
  <li class="apples">…
  <li class="tomatoes"><span>Tomato is a Fruit</span>…
</ul>
```

```java
WebElement vegetable = driver.findElement(By.className("tomatoes"));
  
```

```python
vegetable = driver.find_element(By.CLASS_NAME, "tomatoes")
  
```

```csharp
var vegetable = driver.FindElement(By.ClassName("tomatoes"));
  
```

```rb
      driver.find_element(class: 'tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L10)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const vegetable = await driver.findElement(By.className('tomatoes'));
  
```

```kotlin
val vegetable: WebElement = driver.findElement(By.className("tomatoes"))
  
```

```java
WebElement fruits = driver.findElement(By.id("fruits"));
WebElement fruit = fruits.findElement(By.className("tomatoes"));
  
```

```python
fruits = driver.find_element(By.ID, "fruits")
fruit = fruits.find_element(By.CLASS_NAME,"tomatoes")
  
```

```csharp
IWebElement fruits = driver.FindElement(By.Id("fruits"));
IWebElement fruit = fruits.FindElement(By.ClassName("tomatoes"));
  
```

```rb
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L14-L15)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const fruits = await driver.findElement(By.id('fruits'));
const fruit = fruits.findElement(By.className('tomatoes'));
  
```

```kotlin
val fruits = driver.findElement(By.id("fruits"))
val fruit = fruits.findElement(By.className("tomatoes"))
  
```

```java
WebElement shadowHost = driver.findElement(By.cssSelector("#shadow_host"));
SearchContext shadowRoot = shadowHost.getShadowRoot();
WebElement shadowContent = shadowRoot.findElement(By.cssSelector("#shadow_content"));
```

```python
shadow_host = driver.find_element(By.CSS_SELECTOR, '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(By.CSS_SELECTOR, '#shadow_content')
```

```csharp
var shadowHost = _driver.FindElement(By.CssSelector("#shadow_host"));
var shadowRoot = shadowHost.GetShadowRoot();
var shadowContent = shadowRoot.FindElement(By.CssSelector("#shadow_content"));
```

```ruby
shadow_host = @driver.find_element(css: '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(css: '#shadow_content')
```

```java
WebElement fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"));
  
```

```python
fruit = driver.find_element(By.CSS_SELECTOR,"#fruits .tomatoes")
  
```

```csharp
var fruit = driver.FindElement(By.CssSelector("#fruits .tomatoes"));
  
```

```rb
      driver.find_element(css: '#fruits .tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L19)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const fruit = await driver.findElement(By.css('#fruits .tomatoes'));
  
```

```kotlin
val fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"))
  
```

```java
List<WebElement> plants = driver.findElements(By.tagName("li"));
  
```

```python
plants = driver.find_elements(By.TAG_NAME, "li")
  
```

```csharp
IReadOnlyList<IWebElement> plants = driver.FindElements(By.TagName("li"));
  
```

```rb
      driver.find_elements(tag_name: 'li')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L23)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const plants = await driver.findElements(By.tagName('li'));
  
```

```kotlin
val plants: List<WebElement> = driver.findElements(By.tagName("li"))
  
```

```java
List<WebElement> elements = driver.findElements(By.tagName("li"));

for (WebElement element : elements) {
    System.out.println("Paragraph text:" + element.getText());
}
  
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Firefox()

    # Navigate to Url
driver.get("https://www.example.com")

    # Get all the elements available with tag name 'p'
elements = driver.find_elements(By.TAG_NAME, 'p')

for e in elements:
    print(e.text)
  
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using System.Collections.Generic;

namespace FindElementsExample {
 class FindElementsExample {
  public static void Main(string[] args) {
   IWebDriver driver = new FirefoxDriver();
   try {
    // Navigate to Url
    driver.Navigate().GoToUrl("https://example.com");

    // Get all the elements available with tag name 'p'
    IList < IWebElement > elements = driver.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }

   } finally {
    driver.Quit();
   }
  }
 }
}
  
```

```rb
      elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L27-L28)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
   
   require 'spec_helper'
   
   RSpec.describe 'Element Finders' do
     let(:driver) { start_session }
   
     context 'without executing finders', skip: 'these are just examples, not actual tests' do
       it 'finds the first matching element' do
         driver.find_element(class: 'tomatoes')
       end
   
       it 'uses a subset of the dom to find an element' do
         fruits = driver.find_element(id: 'fruits')
         fruits.find_element(class: 'tomatoes')
       end
   
       it 'uses an optimized locator' do
         driver.find_element(css: '#fruits .tomatoes')
       end
   
       it 'finds all matching elements' do
         driver.find_elements(tag_name: 'li')
       end
   
       it 'gets an element from a collection' do
         elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'finds element from element' do
         element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'find active element' do
         driver.find_element(css: '[name="q"]').send_keys('webElement')
         driver.switch_to.active_element.attribute('title')
       end
     end
   end
   
```

```javascript
const {Builder, By} = require('selenium-webdriver');
(async function example() {
    let driver = await new Builder().forBrowser('firefox').build();
    try {
        // Navigate to Url
        await driver.get('https://www.example.com');

        // Get all the elements available with tag 'p'
        let elements = await driver.findElements(By.css('p'));
        for(let e of elements) {
            console.log(await e.getText());
        }
    }
    finally {
        await driver.quit();
    }
})();
  
```

```kotlin
import org.openqa.selenium.By
import org.openqa.selenium.firefox.FirefoxDriver

fun main() {
    val driver = FirefoxDriver()
    try {
        driver.get("https://example.com")
        // Get all the elements available with tag name 'p'
        val elements = driver.findElements(By.tagName("p"))
        for (element in elements) {
            println("Paragraph text:" + element.text)
        }
    } finally {
        driver.quit()
    }
}
  
```

```java
  import org.openqa.selenium.By;
  import org.openqa.selenium.WebDriver;
  import org.openqa.selenium.WebElement;
  import org.openqa.selenium.chrome.ChromeDriver;
  import java.util.List;

  public class findElementsFromElement {
      public static void main(String[] args) {
          WebDriver driver = new ChromeDriver();
          try {
              driver.get("https://example.com");

              // Get element with tag name 'div'
              WebElement element = driver.findElement(By.tagName("div"));

              // Get all the elements available with tag name 'p'
              List<WebElement> elements = element.findElements(By.tagName("p"));
              for (WebElement e : elements) {
                  System.out.println(e.getText());
              }
          } finally {
              driver.quit();
          }
      }
  }
  
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://www.example.com")
##get elements from parent element using TAG_NAME

    # Get element with tag name 'div'
element = driver.find_element(By.TAG_NAME, 'div')

    # Get all the elements available with tag name 'p'
elements = element.find_elements(By.TAG_NAME, 'p')
for e in elements:
    print(e.text)

##get elements from parent element using XPATH
##NOTE: in order to utilize XPATH from current element, you must add "." to beginning of path

    # Get first element of tag 'ul'
element = driver.find_element(By.XPATH, '//ul')

    # get children of tag 'ul' with tag 'li'
elements  = element.find_elements(By.XPATH, './/li')
for e in elements:
    print(e.text)
  
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace FindElementsFromElement {
 class FindElementsFromElement {
  public static void Main(string[] args) {
   IWebDriver driver = new ChromeDriver();
   try {
    driver.Navigate().GoToUrl("https://example.com");

    // Get element with tag name 'div'
    IWebElement element = driver.FindElement(By.TagName("div"));

    // Get all the elements available with tag name 'p'
    IList < IWebElement > elements = element.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }
   } finally {
    driver.Quit();
   }
  }
 }
}
  
```

```rb
      element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L32-L34)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
   
   require 'spec_helper'
   
   RSpec.describe 'Element Finders' do
     let(:driver) { start_session }
   
     context 'without executing finders', skip: 'these are just examples, not actual tests' do
       it 'finds the first matching element' do
         driver.find_element(class: 'tomatoes')
       end
   
       it 'uses a subset of the dom to find an element' do
         fruits = driver.find_element(id: 'fruits')
         fruits.find_element(class: 'tomatoes')
       end
   
       it 'uses an optimized locator' do
         driver.find_element(css: '#fruits .tomatoes')
       end
   
       it 'finds all matching elements' do
         driver.find_elements(tag_name: 'li')
       end
   
       it 'gets an element from a collection' do
         elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'finds element from element' do
         element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'find active element' do
         driver.find_element(css: '[name="q"]').send_keys('webElement')
         driver.switch_to.active_element.attribute('title')
       end
     end
   end
   
```

```javascript
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = new Builder()
          .forBrowser('chrome')
          .build();

      await driver.get('https://www.example.com');

      // Get element with tag name 'div'
      let element = driver.findElement(By.css("div"));

      // Get all the elements available with tag name 'p'
      let elements = await element.findElements(By.css("p"));
      for(let e of elements) {
          console.log(await e.getText());
      }
  })();
  
```

```kotlin
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://example.com")

          // Get element with tag name 'div'
          val element = driver.findElement(By.tagName("div"))

          // Get all the elements available with tag name 'p'
          val elements = element.findElements(By.tagName("p"))
          for (e in elements) {
              println(e.text)
          }
      } finally {
          driver.quit()
      }
  }
  
```

```java
  import org.openqa.selenium.*;
  import org.openqa.selenium.chrome.ChromeDriver;

  public class activeElementTest {
    public static void main(String[] args) {
      WebDriver driver = new ChromeDriver();
      try {
        driver.get("http://www.google.com");
        driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement");

        // Get attribute of current active element
        String attr = driver.switchTo().activeElement().getAttribute("title");
        System.out.println(attr);
      } finally {
        driver.quit();
      }
    }
  }
  
```

```python
  from selenium import webdriver
  from selenium.webdriver.common.by import By

  driver = webdriver.Chrome()
  driver.get("https://www.google.com")
  driver.find_element(By.CSS_SELECTOR, '[name="q"]').send_keys("webElement")

    # Get attribute of current active element
  attr = driver.switch_to.active_element.get_attribute("title")
  print(attr)
  
```

```csharp
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;

    namespace ActiveElement {
     class ActiveElement {
      public static void Main(string[] args) {
       IWebDriver driver = new ChromeDriver();
       try {
        // Navigate to Url
        driver.Navigate().GoToUrl("https://www.google.com");
        driver.FindElement(By.CssSelector("[name='q']")).SendKeys("webElement");

        // Get attribute of current active element
        string attr = driver.SwitchTo().ActiveElement().GetAttribute("title");
        System.Console.WriteLine(attr);
       } finally {
        driver.Quit();
       }
      }
     }
    }
  
```

```rb
      driver.find_element(css: '[name="q"]').send_keys('webElement')
        driver.switch_to.active_element.attribute('title')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L38-L39)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
  
  require 'spec_helper'
  
  RSpec.describe 'Element Finders' do
    let(:driver) { start_session }
  
    context 'without executing finders', skip: 'these are just examples, not actual tests' do
      it 'finds the first matching element' do
        driver.find_element(class: 'tomatoes')
      end
  
      it 'uses a subset of the dom to find an element' do
        fruits = driver.find_element(id: 'fruits')
        fruits.find_element(class: 'tomatoes')
      end
  
      it 'uses an optimized locator' do
        driver.find_element(css: '#fruits .tomatoes')
      end
  
      it 'finds all matching elements' do
        driver.find_elements(tag_name: 'li')
      end
  
      it 'gets an element from a collection' do
        elements = driver.find_elements(:tag_name, 'p')
        elements.each { |e| puts e.text }
      end
  
      it 'finds element from element' do
        element = driver.find_element(:tag_name, 'div')
        elements = element.find_elements(:tag_name, 'p')
        elements.each { |e| puts e.text }
      end
  
      it 'find active element' do
        driver.find_element(css: '[name="q"]').send_keys('webElement')
        driver.switch_to.active_element.attribute('title')
      end
    end
  end
  
```

```javascript
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = await new Builder().forBrowser('chrome').build();
      await driver.get('https://www.google.com');
      await  driver.findElement(By.css('[name="q"]')).sendKeys("webElement");

      // Get attribute of current active element
      let attr = await driver.switchTo().activeElement().getAttribute("title");
      console.log(`${attr}`)
  })();
  
```

```kotlin
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://www.google.com")
          driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement")

          // Get attribute of current active element
          val attr = driver.switchTo().activeElement().getAttribute("title")
          print(attr)
      } finally {
          driver.quit()
      }
  }
  
```

最終更新 September 6, 2025: [changed driver to element (#2471) (daea0ec2a80)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/daea0ec2a80e796aaed225697d8cb307cc68ca81)

----
url: https://www.selenium.dev/ja/documentation/webdriver/troubleshooting/upgrade_to_selenium_4/
----

# Selenium4にアップグレードする方法

```java
DesiredCapabilities caps = DesiredCapabilities.firefox();
caps.setCapability("platform", "Windows 10");
caps.setCapability("version", "92");
caps.setCapability("build", myTestBuild);
caps.setCapability("name", myTestName);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), caps);
```

```javascript
caps = {};
caps['browserName'] = 'Firefox';
caps['platform'] = 'Windows 10';
caps['version'] = '92';
caps['build'] = myTestBuild;
caps['name'] = myTestName;
```

```csharp
DesiredCapabilities caps = new DesiredCapabilities();
caps.SetCapability("browserName", "firefox");
caps.SetCapability("platform", "Windows 10");
caps.SetCapability("version", "92");
caps.SetCapability("build", myTestBuild);
caps.SetCapability("name", myTestName);
var driver = new RemoteWebDriver(new Uri(CloudURL), caps);
```

```rb
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L123-L130)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```python
caps = {}
caps['browserName'] = 'firefox'
caps['platform'] = 'Windows 10'
caps['version'] = '92'
caps['build'] = my_test_build
caps['name'] = my_test_name
driver = webdriver.Remote(cloud_url, desired_capabilities=caps)
```

```java
FirefoxOptions browserOptions = new FirefoxOptions();
browserOptions.setPlatformName("Windows 10");
browserOptions.setBrowserVersion("92");
Map<String, Object> cloudOptions = new HashMap<>();
cloudOptions.put("build", myTestBuild);
cloudOptions.put("name", myTestName);
browserOptions.setCapability("cloud:options", cloudOptions);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), browserOptions);
```

```javascript
capabilities = {
  browserName: 'firefox',
  browserVersion: '92',
  platformName: 'Windows 10',
  'cloud:options': {
     build: myTestBuild,
     name: myTestName,
  }
}
```

```csharp
var browserOptions = new FirefoxOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "92";
var cloudOptions = new Dictionary<string, object>();
cloudOptions.Add("build", myTestBuild);
cloudOptions.Add("name", myTestName);
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);
var driver = new RemoteWebDriver(new Uri(CloudURL), browserOptions);
```

```rb
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L38-L47)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```python
from selenium.webdriver.firefox.options import Options as FirefoxOptions
options = FirefoxOptions()
options.browser_version = '92'
options.platform_name = 'Windows 10'
cloud_options = {}
cloud_options['build'] = my_test_build
cloud_options['name'] = my_test_name
options.set_capability('cloud:options', cloud_options)
driver = webdriver.Remote(cloud_url, options=options)
```

### Javaで要素ユーティリティメソッドを検索する

Javaバインディング（`FindsBy` インターフェイス）の要素を検索するユーティリティメソッドは、内部使用のみを目的としていたため、削除されました。 次のコードサンプルは、これを分かりやすく説明しています。

`findElement *` で単一の要素を検索する。

Before

```java

driver.findElementByClassName("className");
driver.findElementByCssSelector(".className");
driver.findElementById("elementId");
driver.findElementByLinkText("linkText");
driver.findElementByName("elementName");
driver.findElementByPartialLinkText("partialText");
driver.findElementByTagName("elementTagName");
driver.findElementByXPath("xPath");
```

After

```java

driver.findElement(By.className("className"));
driver.findElement(By.cssSelector(".className"));
driver.findElement(By.id("elementId"));
driver.findElement(By.linkText("linkText"));
driver.findElement(By.name("elementName"));
driver.findElement(By.partialLinkText("partialText"));
driver.findElement(By.tagName("elementTagName"));
driver.findElement(By.xpath("xPath"));
```

`findElements *` で複数の要素を検索する。

Before

```java

driver.findElementsByClassName("className");
driver.findElementsByCssSelector(".className");
driver.findElementsById("elementId");
driver.findElementsByLinkText("linkText");
driver.findElementsByName("elementName");
driver.findElementsByPartialLinkText("partialText");
driver.findElementsByTagName("elementTagName");
driver.findElementsByXPath("xPath");
```

After

```java

driver.findElements(By.className("className"));
driver.findElements(By.cssSelector(".className"));
driver.findElements(By.id("elementId"));
driver.findElements(By.linkText("linkText"));
driver.findElements(By.name("elementName"));
driver.findElements(By.partialLinkText("partialText"));
driver.findElements(By.tagName("elementTagName"));
driver.findElements(By.xpath("xPath"));
```

## 依存関係のアップグレード

以下のサブセクションを確認してSelenium4をインストールし、プロジェクトの依存関係をアップグレードしてください。

### Java

Seleniumをアップグレードするプロセスは、使用されているビルドツールによって異なります。 Javaで最も一般的なものである[Maven](https://maven.apache.org/)と[Gradle](https://gradle.org/)について説明します。 必要なJavaの最小バージョンはまだ8です。

#### Maven

Before

```xml

<dependencies>
  <!-- more dependencies ... -->
  <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.141.59</version>
  </dependency>
  <!-- more dependencies ... -->
</dependencies>
```

After

```xml

<dependencies>
    <!-- more dependencies ... -->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.4.0</version>
    </dependency>
    <!-- more dependencies ... -->
</dependencies>
```

変更を加えた後、`pom.xml` ファイルと同じディレクトリで `mvn clean compile` を実行できます。

#### Gradle

Before

```jsonpath

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.141.59'
}
test {
    useJUnitPlatform()
}
```

After

```jsonpath

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '4.4.0'
}
test {
    useJUnitPlatform()
}
```

変更を加えた後、 `build.gradle` ファイルと同じディレクトリで `./gradlew cleanbuild` を実行できます。

すべてのJavaリリースを確認するには、 [MVNRepository](https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java) にアクセスしてください。

### C\#

C#でSelenium4の更新を取得する場所は [NuGet](https://www.nuget.org/) です。 [`Selenium.WebDriver`](https://www.nuget.org/packages/Selenium.WebDriver/4.4.0) パッケージの下で、最新バージョンに更新するための手順を入手できます。 Visual Studio内では、NuGetパッケージマネージャーを使用して次の操作を実行できます。

```shell
PM> Install-Package Selenium.WebDriver -Version 4.4.0
```

### Python

Pythonを使用するための最も重要な変更は、最低限必要なバージョンです。 Selenium 4には、Python3.7以降が必要です。 詳細については、[Python Package Index](https://pypi.org/project/selenium/4.4.3/)を参照してください。 コマンドラインからアップグレードするには、次のコマンドを実行できます。

```shell
pip install selenium==4.4.3
```

### Ruby

Selenium 4の更新の詳細は、RubyGemsの[selenium-webdriver](https://rubygems.org/gems/selenium-webdriver/versions/4.4.0)で確認できます。 最新バージョンをインストールするには、次のコマンドを実行できます。

```shell
gem install selenium-webdriver
```

Gemfileには下記のように追加します。

```shell
gem 'selenium-webdriver', '~> 4.4.0'
```

### JavaScript

selenium-webdriverパッケージは、Nodeパッケージマネージャーの[npmjs](https://www.npmjs.com)にあります。 Selenium4は[here](https://www.npmjs.com/package/selenium-webdriver/v/4.4.0)にあります。 これをインストールするには、次のいずれかを実行します。

```shell
npm install selenium-webdriver
```

または、package.jsonを更新して、 `npm install` を実行します。

```json
{
  "name": "selenium-tests",
  "version": "1.0.0",
  "dependencies": {
    "selenium-webdriver": "^4.4.0"
  }
}
```

## 潜在的なエラーと非推奨メッセージ

これは、Selenium4にアップグレードした後に発生する可能性のある非推奨メッセージを克服するのに役立つ一連のコード例です。

### Java

#### 待機とタイムアウト

タイムアウトで受信するパラメーターは、期待値 `(long time, TimeUnit unit)` から期待値 `(Duration duration)` に替わりました。

Before

```java

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(2, TimeUnit.MINUTES);
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
```

After

```java

driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().timeouts().scriptTimeout(Duration.ofMinutes(2));
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
```

現在、待機も異なるパラメーターを期待しています。 `WebDriverWait`は、秒とミリ秒単位のタイムアウトに、 `long` ではなく`Duration`を期待するようになりました。 `FluentWait` の `withTimeout` および `pollingEvery` ユーティリティメソッドは、期待値 `(long time, TimeUnit unit)` から `(Duration duration)` に替わりました。

Before

```java

new WebDriverWait(driver, 3)
.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(30, TimeUnit.SECONDS)
  .pollingEvery(5, TimeUnit.SECONDS)
  .ignoring(NoSuchElementException.class);
```

After

```java

new WebDriverWait(driver, Duration.ofSeconds(3))
  .until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

  Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(Duration.ofSeconds(30))
  .pollingEvery(Duration.ofSeconds(5))
  .ignoring(NoSuchElementException.class);
```

#### マージCapabilitiesは、もはや呼び出し元のオブジェクトを変更しなくなりました

以前は、別のCapabilitiesセットを別のセットにマージすることが可能であり、呼び出し元のオブジェクトを変更していました。 今は、ここで、マージ操作の結果を割り当てる必要があります。

Before

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options.merge(capabilities);
As a result, the `options` object was getting modified.
```

After

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options = options.merge(capabilities);
The result of the `merge` call needs to be assigned to an object.
```

#### 古いFirefox

GeckoDriverが登場する前は、SeleniumプロジェクトにはFirefoxを自動化するためのドライバー実装がありました（バージョン<48）。 ただし、この実装は最近のバージョンのFirefoxでは機能しないため、もう必要ありません。 Selenium 4にアップグレードする際の大きな問題を回避するために、`setLegacy` オプションは非推奨として表示されます。 古い実装の使用をやめ、GeckoDriverのみに依存することをお勧めします。 次のコードは、アップグレード後に非推奨になった`setLegacy` 行を示しています。

```java
FirefoxOptions options = new FirefoxOptions();
options.setLegacy(true);
```

#### `BrowserType`

`BrowserType` インターフェースは長い間使用されてきましたが、新しい `Browser` インターフェースを優先して非推奨になります。

Before

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", BrowserType.FIREFOX);
```

After

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", Browser.FIREFOX);
```

### C\#

#### `AddAdditionalCapability` は非推奨になりました

その代わりに、 `AddAdditionalOption` をお勧めします。 これを示す例を次に示します。

Before

```cs

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalCapability("cloud:options", cloudOptions, true);
```

After

```cs

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);
```

### Python

#### `execute_pathは非推奨になりました。Serviceオブジェクトを渡してください`

Selenium 4では、非推奨の警告を防ぐために、Serviceオブジェクトからドライバーの `executable_path` を設定する必要があります。 （または、PATHを設定せず、代わりに必要なドライバーがシステムPATH上にあることを確認してください。）

Before

```python

from selenium import webdriver
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(
    executable_path=CHROMEDRIVER_PATH, 
    options=options
)
```

After

```python

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
options = webdriver.ChromeOptions()
service = ChromeService(executable_path=CHROMEDRIVER_PATH)
driver = webdriver.Chrome(service=service, options=options)
```

## まとめ

Selenium 4にアップグレードする際に考慮すべき主な変更点を確認しました。 アップグレードのためにテストコードを準備する際にカバーするさまざまな側面について説明します。 これには、新しいバージョンのSeleniumを使用する時に発生する可能性のある潜在的な問題を防ぐ方法の提案も含まれます。 最後に、アップグレード後に発生する可能性のある一連の問題についても説明し、それらの問題に対する潜在的な修正を共有しました。

*これは元々は <https://saucelabs.com/resources/articles/how-to-upgrade-to-selenium-4> に投稿されました*

----
url: https://www.selenium.dev/zh-cn/_print/documentation/legacy/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/legacy/).

# Legacy

在此部分，您可以找到与Selenium的旧组件有关的所有文档. 这样做纯粹是出于历史原因，而不是鼓励使用已废弃的组件.

* 1: [Selenium RC (Selenium 1)](#pg-4bf330fd5a475db1e4da06cb7c681d5e)
* 2: [Selenium 2](#pg-0732b4f345393ba2bef87c26733d9d8b)
* * 2.1: [从RC迁移到WebDriver](#pg-23e90ee960cb2d855aefe8e77f95e70b)
  * 2.2: [远程WebDriver服务器](#pg-4385b6f362b0596ebcd161689f59adf4)
  3: [Selenium 3](#pg-e279bf25ef6f679a74567eae8d28a0d2)
* * 3.1: [服务网格 3](#pg-ac76bae276f27fd0f1424e73b7d95663)
  * 3.2: [配置自己的服务网格](#pg-31b83379d2b863eb0549de7e457f5733)
  * 3.3: [服务网格的组件](#pg-7b2bda126f0ba862a2f42215dac75b96)
  4: [Legacy Selenium IDE](#pg-5131ec21377a8d67404a3f8a494a56d0)
  * 4.1: [HTML runner](#pg-79b55613fab8efd3102a974a15d92b90)

# 1 - Selenium RC (Selenium 1)

```shell
    java -jar selenium-server-standalone-<version-number>.jar
```

通过创建包含上述命令的批处理或Shell可执行文件 (Windows上为.bat, Linux上为.sh), 可以简化此操作. 然后在桌面上对该可执行文件创建快捷方式, 只需双击该图标即可启动服务器.

为了使服务器运行, 您需要安装Java并正确配置PATH环境变量才能从控制台运行它. 您可以通过在控制台上运行以下命令来检查是否正确安装了Java.

```shell
       java -version
```

|                   |                            |             |
| ----------------- | -------------------------- | ----------- |
| open              | /                          |             |
| type              | q                          | selenium rc |
| clickAndWait      | btnG                       |             |
| assertTextPresent | Results \* for selenium rc |             |

注意：此示例适用于Google搜索页面 <http://www.google.com>

### Selenese作为编程代码

这是(通过Selenium-IDE)导出到每种支持的编程语言的测试脚本. 如果您具有基本的面向对象编程语言的基础知识, 则可以通过阅读以下示例之一 来了解Selenium如何运行Selenese命令. 要查看特定语言的示例, 请选择以下按钮之一.

#### CSharp

```csharp

        using System;
        using System.Text;
        using System.Text.RegularExpressions;
        using System.Threading;
        using NUnit.Framework;
        using Selenium;

        namespace SeleniumTests
        {
            [TestFixture]
            public class NewTest
            {
                private ISelenium selenium;
                private StringBuilder verificationErrors;
                
                [SetUp]
                public void SetupTest()
                {
                    selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
                    selenium.Start();
                    verificationErrors = new StringBuilder();
                }
                
                [TearDown]
                public void TeardownTest()
                {
                    try
                    {
                        selenium.Stop();
                    }
                    catch (Exception)
                    {
                        // Ignore errors if unable to close the browser
                    }
                    Assert.AreEqual("", verificationErrors.ToString());
                }
                
                [Test]
                public void TheNewTest()
                {
                    selenium.Open("/");
                    selenium.Type("q", "selenium rc");
                    selenium.Click("btnG");
                    selenium.WaitForPageToLoad("30000");
                    Assert.AreEqual("selenium rc - Google Search", selenium.GetTitle());
                }
            }
        }
```

#### Java

```java
      
	  /** Add JUnit framework to your classpath if not already there 
	   *  for this example to work
	  */
      package com.example.tests;

      import com.thoughtworks.selenium.*;
      import java.util.regex.Pattern;

      public class NewTest extends SeleneseTestCase {
          public void setUp() throws Exception {
              setUp("http://www.google.com/", "*firefox");
          }
            public void testNew() throws Exception {
                selenium.open("/");
                selenium.type("q", "selenium rc");
                selenium.click("btnG");
                selenium.waitForPageToLoad("30000");
                assertTrue(selenium.isTextPresent("Results * for selenium rc"));
          }
      }
```

#### Php

```php
      <?php

      require_once 'PHPUnit/Extensions/SeleniumTestCase.php';

      class Example extends PHPUnit_Extensions_SeleniumTestCase
      {
        function setUp()
        {
          $this->setBrowser("*firefox");
          $this->setBrowserUrl("http://www.google.com/");
        }

        function testMyTestCase()
        {
          $this->open("/");
          $this->type("q", "selenium rc");
          $this->click("btnG");
          $this->waitForPageToLoad("30000");
          $this->assertTrue($this->isTextPresent("Results * for selenium rc"));
        }
      }
      ?>
```

#### Python

```python

     from selenium import selenium
      import unittest, time, re

      class NewTest(unittest.TestCase):
          def setUp(self):
              self.verificationErrors = []
              self.selenium = selenium("localhost", 4444, "*firefox",
                      "http://www.google.com/")
              self.selenium.start()
         
          def test_new(self):
              sel = self.selenium
              sel.open("/")
              sel.type("q", "selenium rc")
              sel.click("btnG")
              sel.wait_for_page_to_load("30000")
              self.failUnless(sel.is_text_present("Results * for selenium rc"))
         
          def tearDown(self):
              self.selenium.stop()
              self.assertEqual([], self.verificationErrors)
```

#### Ruby

```ruby

      require "selenium/client"
      require "test/unit"

      class NewTest < Test::Unit::TestCase
        def setup
          @verification_errors = []
          if $selenium
            @selenium = $selenium
          else
            @selenium =  Selenium::Client::Driver.new("localhost", 4444, "*firefox", "http://www.google.com/", 60);
            @selenium.start
          end
          @selenium.set_context("test_new")
        end

        def teardown
          @selenium.stop unless $selenium
          assert_equal [], @verification_errors
        end

        def test_new
          @selenium.open "/"
          @selenium.type "q", "selenium rc"
          @selenium.click "btnG"
          @selenium.wait_for_page_to_load "30000"
          assert @selenium.is_text_present("Results * for selenium rc")
        end
      end
```

```java
    selenium = new DefaultSelenium("localhost", 4444, "*iehta", "http://www.google.com/");
```

Selenium-IDE生成的代码将如下所示. 此示例具有手动添加的注释, 以提高清晰度.

```java
   package com.example.tests;
   // We specify the package of our tests

   import com.thoughtworks.selenium.*;
   // This is the driver's import. You'll use this for instantiating a
   // browser and making it do what you need.

   import java.util.regex.Pattern;
   // Selenium-IDE add the Pattern module because it's sometimes used for 
   // regex validations. You can remove the module if it's not used in your 
   // script.

   public class NewTest extends SeleneseTestCase {
   // We create our Selenium test case

         public void setUp() throws Exception {
           setUp("http://www.google.com/", "*firefox");
                // We instantiate and start the browser
         }

         public void testNew() throws Exception {
              selenium.open("/");
              selenium.type("q", "selenium rc");
              selenium.click("btnG");
              selenium.waitForPageToLoad("30000");
              assertTrue(selenium.isTextPresent("Results * for selenium rc"));
              // These are the real test steps
        }
   }
```

### `C#`

.NET客户端驱动程序可与Microsoft.NET一起使用. 它可以与任何.NET测试框架( 如NUnit或Visual Studio 2005 Team System)一起使用.

Selenium-IDE假定您将使用NUnit作为测试框架. 您可以在下面的生成的代码中看到这一点. 它包含NUnit的using语句以及相应的NUnit属性, 这些属性标识测试类的每个成员函数的角色.

您可能必须将测试类从" NewTest"重命名为您自己选择的名称. 另外, 您将需要在语句中更改浏览器打开参数:

```csharp
    selenium = new DefaultSelenium("localhost", 4444, "*iehta", "http://www.google.com/");
```

生成的代码将类似于此.

```csharp

    using System;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading;
    using NUnit.Framework;
    using Selenium;
    
    namespace SeleniumTests

    {
        [TestFixture]

        public class NewTest

        {
        private ISelenium selenium;

        private StringBuilder verificationErrors;

        [SetUp]

        public void SetupTest()

        {
            selenium = new DefaultSelenium("localhost", 4444, "*iehta",
            "http://www.google.com/");

            selenium.Start();

            verificationErrors = new StringBuilder();
        }

        [TearDown]

        public void TeardownTest()
        {
            try
            {
            selenium.Stop();
            }

            catch (Exception)
            {
            // Ignore errors if unable to close the browser
            }

            Assert.AreEqual("", verificationErrors.ToString());
        }
        [Test]

        public void TheNewTest()
        {
            // Open Google search engine.        
            selenium.Open("http://www.google.com/"); 
            
            // Assert Title of page.
            Assert.AreEqual("Google", selenium.GetTitle());
            
            // Provide search term as "Selenium OpenQA"
            selenium.Type("q", "Selenium OpenQA");
            
            // Read the keyed search term and assert it.
            Assert.AreEqual("Selenium OpenQA", selenium.GetValue("q"));
            
            // Click on Search button.
            selenium.Click("btnG");
            
            // Wait for page to load.
            selenium.WaitForPageToLoad("5000");
            
            // Assert that "www.openqa.org" is available in search results.
            Assert.IsTrue(selenium.IsTextPresent("www.openqa.org"));
            
            // Assert that page title is - "Selenium OpenQA - Google Search"
            Assert.AreEqual("Selenium OpenQA - Google Search", 
                         selenium.GetTitle());
        }
        }
    }
```

您可以允许NUnit管理测试的执行. 或者, 您可以编写一个简单的 `main()` 程序, 该程序实例化测试对象并依次运行三个方法 `SetupTest()`, `TheNewTest()`和 `TeardownTest()` .

### Python

Pyunit是用于Python的测试框架.

基本测试结构是:

```python

   from selenium import selenium
   # This is the driver's import.  You'll use this class for instantiating a
   # browser and making it do what you need.

   import unittest, time, re
   # This are the basic imports added by Selenium-IDE by default.
   # You can remove the modules if they are not used in your script.

   class NewTest(unittest.TestCase):
   # We create our unittest test case

       def setUp(self):
           self.verificationErrors = []
           # This is an empty array where we will store any verification errors
           # we find in our tests

           self.selenium = selenium("localhost", 4444, "*firefox",
                   "http://www.google.com/")
           self.selenium.start()
           # We instantiate and start the browser

       def test_new(self):
           # This is the test code.  Here you should put the actions you need
           # the browser to do during your test.
            
           sel = self.selenium
           # We assign the browser to the variable "sel" (just to save us from 
           # typing "self.selenium" each time we want to call the browser).
            
           sel.open("/")
           sel.type("q", "selenium rc")
           sel.click("btnG")
           sel.wait_for_page_to_load("30000")
           self.failUnless(sel.is_text_present("Results * for selenium rc"))
           # These are the real test steps

       def tearDown(self):
           self.selenium.stop()
           # we close the browser (I'd recommend you to comment this line while
           # you are creating and debugging your tests)

           self.assertEqual([], self.verificationErrors)
           # And make the test fail if we found that any verification errors
           # were found
```

### Ruby

Selenium-IDE的旧版本(2.0之前的版本)生成 需要旧Selenium gem的Ruby代码. 因此, 建议如下更新IDE生成的所有Ruby脚本:

1. 在第一行, 修改 `require "selenium"` 为 `require "selenium/client"`

2. 在第十一行, 修改 `Selenium::SeleniumDriver.new` 为 `Selenium::Client::Driver.new`

您可能还希望将类名更改为比"无标题"更具信息性的名称, 并将测试方法的名称更改为 “test\_untitled"以外的名称.

这是一个通过修改Selenium IDE 生成的Ruby代码创建的简单示例, 如上所述.

```ruby

   # load the Selenium-Client gem
   require "selenium/client"

   # Load Test::Unit, Ruby's default test framework.
   # If you prefer RSpec, see the examples in the Selenium-Client
   # documentation.
   require "test/unit"

   class Untitled < Test::Unit::TestCase

     # The setup method is called before each test.
     def setup

       # This array is used to capture errors and display them at the
       # end of the test run.
       @verification_errors = []

       # Create a new instance of the Selenium-Client driver.
       @selenium = Selenium::Client::Driver.new \
         :host => "localhost",
         :port => 4444,
         :browser => "*chrome",
         :url => "http://www.google.com/",
         :timeout_in_second => 60

       # Start the browser session
       @selenium.start

       # Print a message in the browser-side log and status bar
       # (optional).
       @selenium.set_context("test_untitled")

     end

     # The teardown method is called after each test.
     def teardown

       # Stop the browser session.
       @selenium.stop

       # Print the array of error messages, if any.
       assert_equal [], @verification_errors
     end

     # This is the main body of your test.
     def test_untitled
     
       # Open the root of the site we specified when we created the
       # new driver instance, above.
       @selenium.open "/"

       # Type 'selenium rc' into the field named 'q'
       @selenium.type "q", "selenium rc"

       # Click the button named "btnG"
       @selenium.click "btnG"

       # Wait for the search results page to load.
       # Note that we don't need to set a timeout here, because that
       # was specified when we created the new driver instance, above.
       @selenium.wait_for_page_to_load

       begin

          # Test whether the search results contain the expected text.
	  # Notice that the star (*) is a wildcard that matches any
	  # number of characters.
	  assert @selenium.is_text_present("Results * for selenium rc")
	  
       rescue Test::Unit::AssertionFailedError
       
          # If the assertion fails, push it onto the array of errors.
	  @verification_errors << $!

       end
     end
   end
```

### Perl, PHP

文档团队的成员尚未将Selenium RC与Perl或PHP一起使用. 如果您将Selenium RC和这两种语言一起使用, 请联系文档团队(请参阅贡献一章). 我们很乐意提供一些您的经验和示例, 以支持Perl和PHP用户.

## 学习 API

Selenium RC API使用命名约定, 假设您了解Selenese, 则大部分接口将是不言自明的. 但是, 在这里, 我们解释了最关键且可能不太明显的方面.

### 启动浏览器

#### CSharp

```csharp
      selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
      selenium.Start();
```

#### Java

```java

      setUp("http://www.google.com/", "*firefox");
```

#### Perl

```perl
      my $sel = Test::WWW::Selenium->new( host => "localhost", 
                                          port => 4444, 
                                          browser => "*firefox", 
                                          browser_url => "http://www.google.com/" );
```

#### Php

```php
      $this->setBrowser("*firefox");
      $this->setBrowserUrl("http://www.google.com/");
```

#### Python

```python
      self.selenium = selenium("localhost", 4444, "*firefox",
                               "http://www.google.com/")
      self.selenium.start()
```

#### Ruby

```ruby
      @selenium = Selenium::ClientDriver.new("localhost", 4444, "*firefox", "http://www.google.com/", 10000);
      @selenium.start
```

```
    selenium.type("field-id","string to type")
```

|                   |                              |               |
| ----------------- | ---------------------------- | ------------- |
| open              | /                            |               |
| type              | q                            | selenium rc   |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium rc   |               |
| type              | q                            | selenium ide  |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium ide  |               |
| type              | q                            | selenium grid |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium grid |               |

该代码已重复执行3次相同的步骤. 但是, 同一代码的多个副本不是良好的编程习惯, 因为维护起来需要做更多的工作. 通过使用编程语言, 我们可以遍历搜索结果以提供更灵活和可维护的解决方案.

#### 在 `C#` 中

```csharp
   // Collection of String values.
   String[] arr = {"ide", "rc", "grid"};    
        
   // Execute loop for each String in array 'arr'.
   foreach (String s in arr) {
       sel.open("/");
       sel.type("q", "selenium " +s);
       sel.click("btnG");
       sel.waitForPageToLoad("30000");
       assertTrue("Expected text: " +s+ " is missing on page."
       , sel.isTextPresent("Results * for selenium " + s));
    }
```

### 条件陈述

为了说明在测试中的使用条件, 我们将从一个示例开始. 当页面上没有预期的元素时, 会发生运行Selenium测试时遇到的常见问题. 例如, 当运行以下行时:

```
   selenium.type("q", "selenium " +s);
```

如果页面上没有元素"q", 则抛出异常:

```java
   com.thoughtworks.selenium.SeleniumException: ERROR: Element q not found
```

这可能会导致测试中止. 对于某些测试, 这就是您想要的. 但是通常这是不希望的, 因为您的测试脚本还有许多其他后续测试需要执行.

更好的方法是先验证元素是否确实存在, 然后在元素不存在时采取替代方法. 让我们用Java看一下

```java
   // If element is available on page then perform type operation.
   if(selenium.isElementPresent("q")) {
       selenium.type("q", "Selenium rc");
   } else {
       System.out.printf("Element: " +q+ " is not available on page.")
   }
```

这种方法的优点是即使页面上某些UI元素不可用, 也可以继续执行测试.

### 从测试中执行JavaScript

在执行Selenium不直接支持的应用程序时, JavaScript非常方便. Selenium API的 **getEval** 方法.

考虑具有复选框的应用程序, 该复选框没有静态标识符. 在这种情况下, 可以评估Selenium RC中的JavaScript以获取所有复选框的ID, 然后执行它们.

```java
   public static String[] getAllCheckboxIds () { 
		String script = "var inputId  = new Array();";// Create array in java script.
		script += "var cnt = 0;"; // Counter for check box ids.  
		script += "var inputFields  = new Array();"; // Create array in java script.
		script += "inputFields = window.document.getElementsByTagName('input');"; // Collect input elements.
		script += "for(var i=0; i<inputFields.length; i++) {"; // Loop through the collected elements.
		script += "if(inputFields[i].id !=null " +
		"&& inputFields[i].id !='undefined' " +
		"&& inputFields[i].getAttribute('type') == 'checkbox') {"; // If input field is of type check box and input id is not null.
		script += "inputId[cnt]=inputFields[i].id ;" + // Save check box id to inputId array.
		"cnt++;" + // increment the counter.
		"}" + // end of if.
		"}"; // end of for.
		script += "inputId.toString();" ;// Convert array in to string.			
		String[] checkboxIds = selenium.getEval(script).split(","); // Split the string.
		return checkboxIds;
    }
```

计算页面上的图像数量:

```java
   selenium.getEval("window.document.images.length;");
```

记住要在DOM表达式的情况下使用window对象, 因为默认情况下是指Selenium窗口, 而不是测试窗口.

## 服务器选项

启动服务器时, 命令行选项可用于更改默认服务器行为.

回想一下, 通过运行以下命令来启动服务器.

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar
```

要查看选项列表, 请使用 `-h` 选项运行服务器.

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar -h
```

您会看到服务器可以使用的所有选项的列表 以及每个选项的简要说明. 提供的描述并不总是足够的, 因此我们提供了一些更重要选项的解释.

### 代理配置

如果您的AUT在需要身份验证的HTTP代理后面, 则应使用以下命令配置http.proxyHost, http.proxyPort, http.proxyUser 和http.proxyPassword.

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar -Dhttp.proxyHost=proxy.com -Dhttp.proxyPort=8080 -Dhttp.proxyUser=username -Dhttp.proxyPassword=password
```

### 多窗口模式

如果您使用的是Selenium 1.0, 则可能会跳过本节, 因为多窗口模式是默认行为. 但是, 在版本1.0之前, Selenium默认在子frame中运行测试中的应用程序, 如下所示.

某些应用程序无法在子框架中正常运行, 需要将其加载到窗口的顶部框架中. 多窗口模式选项允许AUT在单独的窗口中运行, 而不是在默认帧中运行, 然后在默认帧中可以拥有所需的顶部帧.

对于旧版本的Selenium, 您必须使用以下选项明确指定多窗口模式:

```bash
   -multiwindow 
```

从Selenium RC 1.0开始, 如果您想在一个框架内运行测试(即使用早期Selenium版本的标准), 则可以使用选项将此状态指定给Selenium服务器

```bash
   -singlewindow 
```

### 指定Firefox配置文件

除非您为每个实例分别指定一个配置文件, 否则Firefox将不会同时运行两个实例. Selenium RC 1.0和更高版本会自动在单独的配置文件中运行, 因此, 如果您使用的是Selenium 1.0, 则可以跳过本节. 但是, 如果您使用的是旧版本的Selenium, 或者需要使用特定的配置文件进行测试 (例如添加https证书或安装了一些插件), 则需要明确指定配置文件.

首先, 要创建一个单独的Firefox配置文件, 请遵循以下步骤. 打开Windows"开始"菜单, 选择"运行", 然后键入并输入以下内容之一:

```bash
   firefox.exe -profilemanager 
```

```bash
   firefox.exe -P 
```

使用对话框创建新的配置文件. 然后, 当您运行Selenium服务器时, 告诉它使用带有服务器命令行选项 *-firefoxProfileTemplate* 的 新Firefox配置文件, 并使用其文件名和目录路径指定配置文件的路径.

```bash
   -firefoxProfileTemplate "path to the profile" 
```

**注意**: 确保将您的个人资料放在默认文件夹之外的新文件夹中！！！！ 如果删除配置文件, 则Firefox配置文件管理器工具将删除文件夹中的所有文件, 无论它们是否是配置文件.

有关Firefox配置文件的更多信息, 请参见 [Mozilla的知识库](http://support.mozilla.com/en/kb/Managing+profiles)

### 使用-htmlSuite在服务器内直接运行Selenese

通过将html文件传递到服务器的命令行, 可以直接在Selenium 服务器中运行Selenese html文件. 例如:

```bash
   java -jar selenium-server-standalone-<version-number>.jar -htmlSuite "*firefox" 
   "http://www.google.com" "c:\absolute\path\to\my\HTMLSuite.html" 
   "c:\absolute\path\to\my\results.html"
```

这将自动启动您的HTML套件, 运行所有测试并保存带有结果的漂亮HTML报告.

*注意:* 使用此选项时, 服务器将启动测试并等待指定的秒数以完成测试； 否则, 服务器将停止测试. 如果在这段时间内未完成测试, 则该命令将以非零的退出代码退出, 并且不会生成任何结果文件.

此命令行很长, 因此在键入时要小心. 请注意, 这要求您传递HTML Selenese套件, 而不是单个测试. 另请注意-htmlSuite选项与 `-interactive`不兼容, 您不能同时运行两者e.

### Selenium 服务器日志

#### 服务端日志

启动Selenium服务器时, **-log** 选项可用于 将Selenium服务器报告的有价值的调试信息 记录到文本文件中.

```bash
   java -jar selenium-server-standalone-<version-number>.jar -log selenium.log
```

该日志文件比标准控制台日志更详细 (它包含DEBUG级别的日志消息). 日志文件还包括记录器名称和记录消息的线程的ID号. 例如:

```bash
   20:44:25 DEBUG [12] org.openqa.selenium.server.SeleniumDriverResourceHandler - 
   Browser 465828/:top frame1 posted START NEW
```

消息格式为

```bash
   TIMESTAMP(HH:mm:ss) LEVEL [THREAD] LOGGER - MESSAGE
```

此消息可能是多行.

#### 浏览器端日志

浏览器端的JavaScript(Selenium Core)也记录重要消息. 在许多情况下, 这些对于最终用户比常规的Selenium 服务器日志更有用. 要访问浏览器端日志, 请将 **-browserSideLog**参数传递给Selenium服务器.

```bash
   java -jar selenium-server-standalone-<version-number>.jar -browserSideLog
```

**-browserSideLog** 必须与 **-log** 参数结合使用, 以将browserSideLogs(以及所有其他DEBUG级别的日志记录消息)记录到文件中.

## 指定特定浏览器的路径

您可以为Selenium RC指定到特定浏览器的路径. 如果您使用同一浏览器的不同版本, 并且希望使用特定的浏览器, 这将很有用. 另外, 它用于允许您的测试在Selenium RC不直接支持的浏览器上运行. 在指定运行模式时, 请使用\*custom说明符, 后跟浏览器可执行文件的完整路径:

```bash
   *custom <path to browser> 
```

```bash
   cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\MyBrowser.exe&2=http://www.google.com
```

### 使用不同的浏览器配置运行测试

通常, Selenium RC自动配置浏览器, 但是如果您使用”\*custom"运行模式启动浏览器, 则可以强制Selenium RC照原样启动浏览器, 而无需使用自动配置.

例如, 您可以使用这样的自定义配置启动Firefox:

```bash
   cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\firefox.exe&2=http://www.google.com
```

请注意, 以这种方式启动浏览器时, 必须手动配置浏览器以将Selenium服务器用作代理. 通常, 这仅意味着打开浏览器首选项并将"localhost:4444"指定为HTTP代理, 但是不同浏览器的说明可能会有根本不同. 有关详细信息, 请查阅浏览器的文档.

请注意, Mozilla浏览器的启动和停止方式可能会有所不同. 可能需要设置MOZ\_NO\_REMOTE环境变量, 以使Mozilla浏览器的行为更加可预测. Unix用户应避免使用Shell脚本启动浏览器. 通常最好直接使用二进制可执行文件(例如firefox-bin).

## 解决常见问题

在开始使用Selenium RC时, 通常会遇到一些潜在的问题. 我们在这里介绍它们及其解决方案.

### 无法连接到服务器

当您的测试程序无法连接到Selenium 服务器时, Selenium会在您的测试程序中引发异常. 它应该显示此消息或类似的消息:

```bash
    "Unable to connect to remote server (Inner Exception Message: 
	No connection could be made because the target machine actively 
	refused it )"
    
	(using .NET and XP Service Pack 2) 
```

如果看到这样的消息, 请确保已启动Selenium服务器. 如果是这样, 则Selenium客户端库和Selenium服务器之间的连接存在问题.

从Selenium RC开始时, 大多数人开始是在同一台计算机上运行测试程序(带有Selenium客户端库) 和Selenium服务器. 为此, 请使用"localhost"作为连接参数. 我们建议您以这种方式开始, 因为它可以减少您入门时可能出现的网络问题的影响. 假设您的操作系统具有典型的网络和TCP/IP设置, 那么您应该没有什么困难. 实际上, 许多人选择以这种方式运行测试.

但是, 如果您确实想在远程计算机上运行Selenium服务器, 则假设两台计算机之间具有有效的TCP/IP连接, 则连接应该很好.

如果连接困难, 可以使用常用的网络工具, 例如*ping*, *telnet*, *ifconfig(Unix)/ipconfig* (Windows) 等, 以确保您具有有效的网络连接. 如果不熟悉这些, 则系统管理员可以为您提供帮助.

### 无法加载浏览器

好的, 这并非友好的错误消息, 很抱歉, 但是如果Selenium服务器无法加载浏览器, 您可能会看到此错误.

```bash
    (500) Internal Server Error
```

```bash
    Error:  java.lang.RuntimeException: Firefox refused shutdown while 
    preparing a profile 
```

以下是来自服务器的完整错误消息:

```bash
    16:20:03.919 INFO - Preparing Firefox profile... 
    16:20:27.822 WARN - GET /selenium-server/driver/?cmd=getNewBrowserSession&1=*fir 
    efox&2=http%3a%2f%2fsage-webapp1.qa.idc.com HTTP/1.1 
    java.lang.RuntimeException: Firefox refused shutdown while preparing a profile 
            at org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLaunc 
    her.waitForFullProfileToBeCreated(FirefoxCustomProfileLauncher.java:277) 
    ... 
    Caused by: org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLaunc 
    her$FileLockRemainedException: Lock file still present! C:\DOCUME~1\jsvec\LOCALS 
    ~1\Temp\customProfileDir203138\parent.lock 
```

要解决此问题, 请参阅"指定单独的Firefox配置文件"部分

### 版本问题

确保您的Selenium版本支持您的浏览器版本. 例如, Selenium RC 0.92不支持Firefox3. 有时您可能很幸运(例如我). 但不要忘记检查您使用的Selenium版本支持哪些浏览器版本. 如有疑问, 请使用最新版本的Selenium和浏览器使用最广泛的版本.

### 启动服务器时出现错误消息: “(不支持的major.minor版本49.0)”

此错误表明您使用的Java版本不正确. Selenium服务器需要Java 1.5或更高版本.

要检查您的Java版本, 请从命令行运行.

```bash
   java -version
```

您应该看到一条消息, 显示Java版本.

```bash
   java version "1.5.0_07"
   Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03)
   Java HotSpot(TM) Client VM (build 1.5.0_07-b03, mixed mode)
```

```bash
   cmd=getNewBrowserSession&1=*firefox /usr/local/firefox/firefox-bin&2=http://www.google.com
```

```bash
   /usr/lib/firefox-x.x.x/ 
```

其中x.x.x是您当前拥有的版本号. 因此, 要将该路径添加到用户的路径. 您将必须将以下内容添加到您的.bashrc文件中:

```bash
   export PATH="$PATH:/usr/lib/firefox-x.x.x/"
```

如有必要, 您可以在测试中直接指定firefox-bin的路径, 如下所示:

```bash
   "*firefox /usr/lib/firefox-x.x.x/firefox-bin"
```

### IE和样式属性

如果您在Internet Explorer上运行测试, 则无法使用其 `style` 属性来查找元素. 例如:

```bash
    //td[@style="background-color:yellow"]
```

这将在Firefox, Opera或Safari中完美运行, 但不适用于IE. IE将 `@style` 中的键解释为大写. 因此, 即使源代码是小写的, 您也应该使用:

```bash
    //td[@style="BACKGROUND-COLOR:yellow"]
```

如果您的测试打算在多个浏览器上运行, 那么这将是一个问题, 但是您可以轻松地对测试进行编码以检测情况 并尝试仅在IE中运行的替代定位器.

### 遇到错误-随着\*googlechrome浏览器的关闭, “无法将对象转换为原始值”

为避免此错误, 您必须使用禁用 同源策略检查的选项启动浏览器:

```bash
   selenium.start("commandLineFlags=--disable-web-security");
```

### IE中遇到的错误-“无法打开应用程序窗口；弹出窗口阻止程序已启用？”

为避免此错误, 您必须配置浏览器： 禁用弹出窗口阻止程序, 并取消选中工具»选项»安全中的"启用保护模式"选项.

***

1. 代理人是中间的第三人, 两人之间传球. 它充当将AUT传送到浏览器的"网络服务器". 作为代理, Selenium服务器可以"说谎"AUT的真实URL. [↩︎](#fnref:1)

2. 启动浏览器时使用的配置文件将localhost:4444设置为HTTP代理, 这就是为什么浏览器执行的任何HTTP请求都将通过Selenium服务器并且响应将通过它而不是真实服务器通过的原因. [↩︎](#fnref:2)

# 2 - Selenium 2

Selenium 2 是以实现了WebDriver代码重写的Selenium 1.

# 2.1 - 从RC迁移到WebDriver

```java
Selenium selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.yoursite.com");
selenium.start();
```

应该这样替换:

```java
WebDriver driver = new FirefoxDriver();
Selenium selenium = new WebDriverBackedSelenium(driver, "http://www.yoursite.com");
```

## 下一步

一旦测试成功执行, 下一步就是迁移实际的测试代码以使用WebDriver API. 根据代码的抽象程度, 这可能是一个短暂的过程, 也可能是一个漫长的过程. 在这两种情况下, 方法都是相同的, 可以简单地总结一下：修改代码以在使用新API时进行编辑.

如果您需要从Selenium实例中提取基础WebDriver实现, 则只需将其强制转换为WrapsDriver:

```java
WebDriver driver = ((WrapsDriver) selenium).getWrappedDriver();
```

这使您可以继续正常传递Selenium实例, 但可以根据需要解包WebDriver实例.

有时, 您的代码库将主要使用较新的API. 此时, 您可以翻转关系, 使用WebDriver并按需实例化Selenium实例:

```java
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);
```

## 常见问题

幸运的是, 您不是第一个进行此迁移的人, 因此这里有其他人已经看到的一些常见问题以及如何解决它们.

### 单击和键入更加完整

Selenium RC测试中的常见模式如下所示:

```java
selenium.type("name", "exciting tex");
selenium.keyDown("name", "t");
selenium.keyPress("name", "t");
selenium.keyUp("name", "t");
```

```java
Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(30));
WebElement element= wait.until(visibilityOfElementLocated(By.id("some_id")));
```

其中"visibilityOfElementLocated"实现为:

```java
public ExpectedCondition<WebElement> visibilityOfElementLocated(final By locator) {
  return new ExpectedCondition<WebElement>() {
    public WebElement apply(WebDriver driver) {
      WebElement toReturn = driver.findElement(locator);
      if (toReturn.isDisplayed()) {
        return toReturn;
      }
      return null;
    }
  };
}
```

这看起来很复杂, 但这几乎是所有样板代码. 唯一有趣的一点是, 将反复评估"ExpectedCondition", 直到"apply"方法返回的结果既不是"null" 也不是Boolean.FALSE.

当然, 添加所有这些"等待"调用可能会使您的代码混乱. 如果是这样, 并且您的需求很简单, 请考虑使用隐式等待:

```java
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
```

```java
String name = selenium.getEval(
    "selenium.browserbot.findElement('id=foo', browserbot.getCurrentWindow()).tagName");
```

变成:

```java
WebElement element = driver.findElement(By.id("foo"));
String name = (String) ((JavascriptExecutor) driver).executeScript(
    "return arguments[0].tagName", element);
```

请注意, 传入的"element"变量如何显示为JS标准"arguments"数组中的第一项.

### 执行JavaScript不会返回任何内容

WebDriver的JavascriptExecutor将包装所有JS并将其评估为匿名表达式. 这意味着您需要使用"return"关键字:

```java
String title = selenium.getEval("browserbot.getCurrentWindow().document.title");
```

变成:

```java
((JavascriptExecutor) driver).executeScript("return document.title;");
```

# 2.2 - 远程WebDriver服务器

服务器将始终在安装了待测浏览器的机器上运行. 可以从命令行或通过代码配置来使用服务器.

## 从命令行启动服务器

下载 `selenium-server-standalone-{VERSION}.jar` 后, 将其传到具有待测浏览器的电脑上. 然后, 切换到包含此jar文件的目录中, 运行以下命令:

```shell
java -jar selenium-server-standalone-{VERSION}.jar
```

## 运行服务器的注意事项

调用者应调用 `Selenium#stop()` 或 `WebDriver#quit` 以结束每次会话.

Selenium服务器在内存中保留每个运行会话的日志, 这些日志将在调用 `Selenium#stop()` 或 `WebDriver#quit` 时清除. 如果您忘记终止这些会话, 则可能会造成服务器内存泄漏. 如果您保持运行时间非常长的会话, 则可能需要不时执行停止或退出的操作 (或使用-Xmx jvm选项增加内存) .

## 超时 (自2.21版本)

服务器有两种不同的超时, 可以按如下设置:

```shell
java -jar selenium-server-standalone-{VERSION}.jar -timeout=20 -browserTimeout=60
```

```java
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.security.SslSocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;

import javax.servlet.Servlet;
import java.io.File;

import org.openqa.selenium.remote.server.DriverServlet;

public class AppServer {
  private Server server = new Server();

  public AppServer() throws Exception {
    WebAppContext context = new WebAppContext();
    context.setContextPath("");
    context.setWar(new File("."));
    server.addHandler(context);

    context.addServlet(DriverServlet.class, "/wd/*");

    SelectChannelConnector connector = new SelectChannelConnector();
    connector.setPort(3001);
    server.addConnector(connector);

    server.start();
  }
}
```

# 3 - Selenium 3

Selenium 3是摒除了Selenium RC代码的WebDriver实现. 其已被实现了W3C WebDriver规范的Selenium 4所替代.

# 3.1 - 服务网格 3

# 3.2 - 配置自己的服务网格

```shell
java -jar selenium-server-standalone.jar -role hub
```

转发器(hub)默认会监听4444端口，你也可以通过打开浏览器访问<http://localhost:4444/grid/console>来查看转发器(hub)的状态。

如果需要改变默认端口，你可以添加`-port`加上一个数字作为参数来代表你期望监听的端口， 同时，所有其他的可选参数都可以在下面这个JSON配置文件里找到。

你已经在上面获得了一个简单命令，当然如果你希望一些更高级的配置， 方便起见，你也可以指定一个JSON格式的配置文件来配置并启动你的转发器(hub)。 你可以这么做：

```shell
java -jar selenium-server-standalone.jar -role hub -hubConfig hubConfig.json -debug
```

下面你可以看到一个配置文件`hubConfig.json`的例子。 我们会在第二步深入探讨怎么来提供节点配置文件。

```json
{
  "_comment" : "Configuration for Hub - hubConfig.json",
  "host": ip,
  "maxSession": 5,
  "port": 4444,
  "cleanupCycle": 5000,
  "timeout": 300000,
  "newSessionWaitTimeout": -1,
  "servlets": [],
  "prioritizer": null,
  "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
  "throwOnCapabilityNotPresent": true,
  "nodePolling": 180000,
  "platform": "WINDOWS"}
```

### 第二部: 启动节点

无论你期望你的服务网格使用新的WebDriver的功能，还是Selenium 1 RC的功能，或者2者皆有。 你都只需要使用`selenium-server-standalone.jar`来启动节点。

```shell
java -jar selenium-server-standalone.jar -role node -hub http://localhost:4444
```

如果不通过`-port`来指定端口，会选一个可用端口。你也可以在一个终端机上运行多个节点， 但是如果你这么做了，你需要意识到当你的测试使用截屏会引发你的系统内存资源和问题。

#### 配置节点的可选参数

正如前面提到的，作为一个向下兼容，“wd"和”rc”这两个角色都是节点角色的合法的自己。 当节点同时允许RC饿WebDriver的远程链接时，这些角色限制了远程连接使用的API。

通过在命令行中设置JVM属性(\_在-jar参数前\_使用`-D`参数)，会被传递到节点里： `-Dwebdriver.chrome.driver=chromedriver.exe`

#### 使用JSON配置节点

你也可以使用JSON配置文件来启动服务网格节点

```shell
java -Dwebdriver.chrome.driver=chromedriver.exe -jar selenium-server-standalone.jar -role node -nodeConfig node1Config.json
```

这里是一个配置文件`nodeConfig.json`的例子:

```json
{
  "capabilities": [
    {
      "browserName": "firefox",
      "acceptSslCerts": true,
      "javascriptEnabled": true,
      "takesScreenshot": false,
      "firefox_profile": "",
      "browser-version": "27",
      "platform": "WINDOWS",
      "maxInstances": 5,
      "firefox_binary": "",
      "cleanSession": true
    },
    {
      "browserName": "chrome",
      "maxInstances": 5,
      "platform": "WINDOWS",
      "webdriver.chrome.driver": "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"
    },
    {
      "browserName": "internet explorer",
      "maxInstances": 1,
      "platform": "WINDOWS",
      "webdriver.ie.driver": "C:/Program Files (x86)/Internet Explorer/iexplore.exe"
    }
  ],
  "configuration": {
    "_comment" : "Configuration for Node",
    "cleanUpCycle": 2000,
    "timeout": 30000,
    "proxy": "org.openqa.grid.selenium.proxy.WebDriverRemoteProxy",
    "port": 5555,
    "host": ip,
    "register": true,
    "hubPort": 4444,
    "maxSession": 5
  }
}
```

```shell
java -jar selenium-server-standalone.jar -role hub -log log.txt
```

使用你习惯的文本编辑器来打开日志文件(例子里用的log.txt)，查找"ERROR"日志来定位你的问题。

### 使用 `-debug` 参数

同时，你也可以通过使用`-debug`来向控制台打印debug日志。 启动Selenium服务网格的转发器(hub)或节点的时候使用`-debug`参数。下面是一个例子：

```shell
java -jar selenium-server-standalone.jar -role hub -debug
```

# 3.3 - 服务网格的组件


# 4 - Legacy Selenium IDE

```html
<tr>
    <td>Command</td>
    <td>target (locator)</td>
    <td>Value</td>
</tr>
```

|            |              |       |
| ---------- | ------------ | ----- |
| verifyText | //div//a\[2] | Login |

The parameters are not always required; it depends on the command. In some cases both are required, in others one parameter is required, and in still others the command may take no parameters at all. Here are a couple more examples:

|                   |             |                         |
| ----------------- | ----------- | ----------------------- |
| goBackAndWait     |             |                         |
| verifyTextPresent |             | Welcome to My Home Page |
| type              | id=phone    | (555) 666-7066          |
| type              | id=address1 | ${myVariableAddress}    |

```html
<table>
    <tr><td>open</td><td>/download/</td><td></td></tr>
    <tr><td>assertTitle</td><td></td><td>Downloads</td></tr>
    <tr><td>verifyText</td><td>//h2</td><td>Downloads</td></tr>
</table>
```

Rendered as a table in a browser this would look like the following:

|             |            |           |
| ----------- | ---------- | --------- |
| open        | /download/ |           |
| assertTitle |            | Downloads |
| verifyText  | //h2       | Downloads |

The Selenese HTML syntax can be used to write and run tests without requiring knowledge of a programming language. With a basic knowledge of selenese and Selenium-IDE you can quickly produce and run testcases.

## Test Suites

A test suite is a collection of tests. Often one will run all the tests in a test suite as one continuous batch-job.

When using Selenium-IDE, test suites also can be defined using a simple HTML file. The syntax again is simple. An HTML table defines a list of tests where each row defines the filesystem path to each test. An example tells it all.

```html
<html>
<head>
<title>Test Suite Function Tests - Priority 1</title>
</head>
<body>
<table>
  <tr><td><b>Suite Of Tests</b></td></tr>
  <tr><td><a href="./Login.html">Login</a></td></tr>
  <tr><td><a href="./SearchValues.html">Test Searching for Values</a></td></tr>
  <tr><td><a href="./SaveValues.html">Test Save</a></td></tr>
</table>
</body>
</html>
```

| Command     | Target     | Value        |
| ----------- | ---------- | ------------ |
| open        | /download/ |              |
| assertTitle |            | Downloads    |
| verifyText  | //h2       | Downloads    |
| assertTable | 1.2.1      | Selenium IDE |
| verifyTable | 1.2.2      | June 3, 2008 |
| verifyTable | 1.2.3      | 1.0 beta 2   |

The above example first opens a page and then “asserts” that the correct page is loaded by comparing the title with the expected value. Only if this passes will the following command run and “verify” that the text is present in the expected location. The test case then “asserts” the first column in the second row of the first table contains the expected value, and only if this passed will the remaining cells in that row be “verified”.

### **verifyTextPresent**

The command `verifyTextPresent` is used to verify specific text exists somewhere on the page. It takes a single argument–the text pattern to be verified. For example:

| Command           | Target             | Value |
| ----------------- | ------------------ | ----- |
| verifyTextPresent | Marketing Analysis |       |

This would cause Selenium to search for, and verify, that the text string “Marketing Analysis” appears somewhere on the page currently being tested. Use verifyTextPresent when you are interested in only the text itself being present on the page. Do not use this when you also need to test where the text occurs on the page.

### **verifyElementPresent**

Use this command when you must test for the presence of a specific UI element, rather than its content. This verification does not check the text, only the HTML tag. One common use is to check for the presence of an image.

| Command              | Target      | Value |
| -------------------- | ----------- | ----- |
| verifyElementPresent | //div/p/img |       |

This command verifies that an image, specified by the existence of an HTML tag, is present on the page, and that it follows a

tag and a

tag. The first (and only) parameter is a locator for telling the Selenese command how to find the element. Locators are explained in the next section.

`verifyElementPresent` can be used to check the existence of any HTML tag within the page. You can check the existence of links, paragraphs, divisions

, etc. Here are a few more examples.

| Command              | Target                        | Value |
| -------------------- | ----------------------------- | ----- |
| verifyElementPresent | //div/p                       |       |
| verifyElementPresent | //div/a                       |       |
| verifyElementPresent | id=Login                      |       |
| verifyElementPresent | link=Go to Marketing Research |       |
| verifyElementPresent | //a\[2]                       |       |
| verifyElementPresent | //head/title                  |       |

These examples illustrate the variety of ways a UI element may be tested. Again, locators are explained in the next section.

### **verifyText**

Use `verifyText` when both the text and its UI element must be tested. verifyText must use a locator. If you choose an *XPath* or *DOM* locator, you can verify that specific text appears at a specific location on the page relative to other UI components on the page.

| Command    | Target              | Value                                                               |
| ---------- | ------------------- | ------------------------------------------------------------------- |
| verifyText | //table/tr/td/div/p | This is my text and it occurs right after the div inside the table. |

## Locating Elements

For many Selenium commands, a target is required. This target identifies an element in the content of the web application, and consists of the location strategy followed by the location in the format `locatorType=location`. The locator type can be omitted in many cases. The various locator types are explained below with examples for each.

### Locating by Identifier

This is probably the most common method of locating elements and is the catch-all default when no recognized locator type is used. With this strategy, the first element with the id attribute value matching the location will be used. If no element has a matching id attribute, then the first element with a name attribute matching the location will be used.

For instance, your page source could have id and name attributes as follows:

```html
  <html>
   <body>
    <form id="loginForm">
     <input name="username" type="text" />
     <input name="password" type="password" />
     <input name="continue" type="submit" value="Login" />
    </form>
   </body>
  <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
    </body>
   <html>
```

* `id=loginForm` (3)

### Locating by Name

The name locator type will locate the first element with a matching name attribute. If multiple elements have the same value for a name attribute, then you can use filters to further refine your location strategy. The default filter type is value (matching the value attribute).

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
  <html>
   <body>
    <p>Are you sure you want to do this?</p>
    <a href="continue.html">Continue</a> 
    <a href="cancel.html">Cancel</a>
  </body>
  <html>
```

* `link=Continue` (4)
* `link=Cancel` (5)

### Locating by DOM

The Document Object Model represents an HTML document and can be accessed using JavaScript. This location strategy takes JavaScript that evaluates to an element on the page, which can be simply the element’s location using the hierarchical dotted notation.

Since only `dom` locators start with “document”, it is not necessary to include the `dom=` label when specifying a DOM locator.

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input class="required" name="username" type="text" />
      <input class="required passfield" name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | glob:\*Film\*Television\*             |       |

The actual title of the page reached by clicking on the link was “De Anza Film And Television Department - Menu”. By using a pattern rather than the exact text, the `verifyTitle` will pass as long as the two words “Film” and “Television” appear (in that order) anywhere in the page’s title. For example, if the page’s owner should shorten the title to just “Film & Television Department,” the test would still pass. Using a pattern for both a link and a simple test that the link worked (such as the `verifyTitle` above does) can greatly reduce the maintenance for such test cases.

#### Regular Expression Patterns

*Regular expression* patterns are the most powerful of the three types of patterns that Selenese supports. Regular expressions are also supported by most high-level programming languages, many text editors, and a host of tools, including the Linux/Unix command-line utilities **grep**, **sed**, and **awk**. In Selenese, regular expression patterns allow a user to perform many tasks that would be very difficult otherwise. For example, suppose your test needed to ensure that a particular table cell contained nothing but a number. `regexp: [0-9]+` is a simple pattern that will match a decimal number of any length.

Whereas Selenese globbing patterns support only the **\*** and **\[ ]** (character class) features, Selenese regular expression patterns offer the same wide array of special characters that exist in JavaScript. Below are a subset of those special characters:

| PATTERN | MATCH                                                                            |
| ------- | -------------------------------------------------------------------------------- |
| .       | any single character                                                             |
| \[ ]    | character class: any single character that appears inside the brackets           |
| \*      | quantifier: 0 or more of the preceding character (or group)                      |
| +       | quantifier: 1 or more of the preceding character (or group)                      |
| ?       | quantifier: 0 or 1 of the preceding character (or group)                         |
| {1,5}   | quantifier: 1 through 5 of the preceding character (or group)                    |
| \|      | alternation: the character/group on the left or the character/group on the right |
| ( )     | grouping: often used with alternation and/or quantifier                          |

Regular expression patterns in Selenese need to be prefixed with either `regexp:` or `regexpi:`. The former is case-sensitive; the latter is case-insensitive.

A few examples will help clarify how regular expression patterns can be used with Selenese commands. The first one uses what is probably the most commonly used regular expression pattern–**.\*** (“dot star”). This two-character sequence can be translated as “0 or more occurrences of any character” or more simply, “anything or nothing.” It is the equivalent of the one-character globbing pattern **\*** (a single asterisk).

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | regexp:.\*Film.\*Television.\*        |       |

The example above is functionally equivalent to the earlier example that used globbing patterns for this same test. The only differences are the prefix (**regexp:** instead of **glob:**) and the “anything or nothing” pattern (**.\*** instead of just **\***).

The more complex example below tests that the Yahoo! Weather page for Anchorage, Alaska contains info on the sunrise time:

| Command           | Target                                            | Value |
| ----------------- | ------------------------------------------------- | ----- |
| open              | <http://weather.yahoo.com/forecast/USAK0012.html> |       |
| verifyTextPresent | regexp:Sunrise: \*\[0-9]{1,2}:\[0-9]{2} \[ap]m    |       |

Let’s examine the regular expression above one part at a time:

|              |                                                      |
| ------------ | ---------------------------------------------------- |
| `Sunrise: *` | The string **Sunrise:** followed by 0 or more spaces |
| `[0-9]{1,2}` | 1 or 2 digits (for the hour of the day)              |
| `:`          | The character **:** (no special characters involved) |
| `[0-9]{2}`   | 2 digits (for the minutes) followed by a space       |
| `[ap]m`      | “a” or “p” followed by “m” (am or pm)                |

#### Exact Patterns

The **exact** type of Selenium pattern is of marginal usefulness. It uses no special characters at all. So, if you needed to look for an actual asterisk character (which is special for both globbing and regular expression patterns), the **exact** pattern would be one way to do that. For example, if you wanted to select an item labeled “Real \*” from a dropdown, the following code might work or it might not. The asterisk in the `glob:Real *` pattern will match anything or nothing. So, if there was an earlier select option labeled “Real Numbers,” it would be the option selected rather than the “Real \*” option.

| Command | Target   | Value        |
| ------- | -------- | ------------ |
| select  | //select | glob:Real \* |

In order to ensure that the “Real \*” item would be selected, the `exact:` prefix could be used to create an **exact** pattern as shown below:

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| select  | //select | exact:Real \* |

But the same effect could be achieved via escaping the asterisk in a regular expression pattern:

| Command | Target   | Value            |
| ------- | -------- | ---------------- |
| select  | //select | regexp:Real \\\* |

| Command | Target            | Value |
| ------- | ----------------- | ----- |
| store   | <paul@mysite.org> |       |

Later in your script, you’ll want to use the stored value of your variable. To access the value of a variable, enclose the variable in curly brackets ({}) and precede it with a dollar sign like this.

| Command    | Target  | Value         |
| ---------- | ------- | ------------- |
| verifyText | //div/p | \\${userName} |

A common use of variables is for storing input for an input field.

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| type    | id=login | \\${userName} |

| Command         | Target                                         | Value       |
| --------------- | ---------------------------------------------- | ----------- |
| store           | 10                                             | hits        |
| storeXpathCount | //blockquote                                   | blockquotes |
| storeEval       | storedVars\[‘hits’].storedVars\[‘blockquotes’] | paragraphs  |

This next example illustrates how a JavaScript snippet can include calls to methods, in this case the JavaScript String object’s `toUpperCase` method and `toLowerCase` method.

| Command   | Target                            | Value |
| --------- | --------------------------------- | ----- |
| store     | Edith Wharton                     | name  |
| storeEval | storedVars\[’name’].toUpperCase() | uc    |
| storeEval | storedVars\[’name’].toUpperCase() | lc    |

#### JavaScript Usage with Non-Script Parameters

JavaScript can also be used to help generate values for parameters, even when the parameter is not specified to be of type **script**.\
However, in this case, special syntax is required–the *entire* parameter value must be prefixed by `javascript{` with a trailing `}`, which encloses the JavaScript snippet, as in `javascript{*yourCodeHere*}`. Below is an example in which the `type` command’s second parameter `value` is generated via JavaScript code using this special syntax:

| Command | Target            | Value                                                 |
| ------- | ----------------- | ----------------------------------------------------- |
| store   | league of nations | searchString                                          |
| type    | q                 | javascript{storedVars\[‘searchString’].toUpperCase()} |

## *echo* - The Selenese Print Command

Selenese has a simple command that allows you to print text to your test’s output. This is useful for providing informational progress notes in your test which display on the console as your test is running. These notes also can be used to provide context within your test result reports, which can be useful for finding where a defect exists on a page in the event your test finds a problem. Finally, echo statements can be used to print the contents of Selenium variables.

| Command | Target                    | Value |
| ------- | ------------------------- | ----- |
| echo    | Testing page footer now.  |       |
| echo    | Username is \\${userName} |       |

## Alerts, Popups, and Multiple Windows

Suppose that you are testing a page that looks like this.

```html
  <!DOCTYPE HTML>
  <html>
  <head>
    <script type="text/javascript">
      function output(resultText){
        document.getElementById('output').childNodes[0].nodeValue=resultText;
      }

      function show_confirm(){
        var confirmation=confirm("Chose an option.");
        if (confirmation==true){
          output("Confirmed.");
        }
        else{
          output("Rejected!");
        }
      }
      
      function show_alert(){
        alert("I'm blocking!");
        output("Alert is gone.");
      }
      function show_prompt(){
        var response = prompt("What's the best web QA tool?","Selenium");
        output(response);
      }
      function open_window(windowName){
        window.open("newWindow.html",windowName);
      }
      </script>
  </head>
  <body>

    <input type="button" id="btnConfirm" onclick="show_confirm()" value="Show confirm box" />
    <input type="button" id="btnAlert" onclick="show_alert()" value="Show alert" />
    <input type="button" id="btnPrompt" onclick="show_prompt()" value="Show prompt" />
    <a href="newWindow.html" id="lnkNewWindow" target="_blank">New Window Link</a>
    <input type="button" id="btnNewNamelessWindow" onclick="open_window()" value="Open Nameless Window" />
    <input type="button" id="btnNewNamedWindow" onclick="open_window('Mike')" value="Open Named Window" />

    <br />
    <span id="output">
    </span>
  </body>
  </html>
```

The user must respond to alert/confirm boxes, as well as moving focus to newly opened popup windows. Fortunately, Selenium can cover JavaScript pop-ups.

But before we begin covering alerts/confirms/prompts in individual detail, it is helpful to understand the commonality between them. Alerts, confirmation boxes and prompts all have variations of the following

| Command                   | Description                                                           |
| ------------------------- | --------------------------------------------------------------------- |
| assertFoo(pattern)        | throws error if pattern doesn’t match the text of the pop-up          |
| assertFooPresent          | throws error if pop-up is not available                               |
| assertFooNotPresent       | throws error if any pop-up is present                                 |
| storeFoo(variable)        | stores the text of the pop-up in a variable                           |
| storeFooPresent(variable) | stores the text of the pop-up in a variable and returns true or false |

When running under Selenium, JavaScript pop-ups will not appear. This is because the function calls are actually being overridden at runtime by Selenium’s own JavaScript. However, just because you cannot see the pop-up doesn’t mean you don’t have to deal with it. To handle a pop-up, you must call its `assertFoo(pattern)` function. If you fail to assert the presence of a pop-up your next command will be blocked and you will get an error similar to the following `[error] Error: There was an unexpected Confirmation! [Chose an option.]`

### Alerts

Let’s start with alerts because they are the simplest pop-up to handle. To begin, open the HTML sample above in a browser and click on the “Show alert” button. You’ll notice that after you close the alert the text “Alert is gone.” is displayed on the page. Now run through the same steps with Selenium IDE recording, and verify the text is added after you close the alert. Your test will look something like this:

| Command           | Target         | Value |
| ----------------- | -------------- | ----- |
| open              | /              |       |
| click             | btnAlert       |       |
| assertAlert       | I’m blocking!  |       |
| verifyTextPresent | Alert is gone. |       |

You may be thinking “That’s odd, I never tried to assert that alert.” But this is Selenium-IDE handling and closing the alert for you. If you remove that step and replay the test you will get the following error `[error] Error: There was an unexpected Alert! [I'm blocking!]`. You must include an assertion of the alert to acknowledge its presence.

If you just want to assert that an alert is present but either don’t know or don’t care what text it contains, you can use `assertAlertPresent`. This will return true or false, with false halting the test.

### Confirmations

Confirmations behave in much the same way as alerts, with `assertConfirmation` and `assertConfirmationPresent` offering the same characteristics as their alert counterparts. However, by default Selenium will select OK when a confirmation pops up. Try recording clicking on the “Show confirm box” button in the sample page, but click on the “Cancel” button in the popup, then assert the output text. Your test may look something like this:

| Command                        | Target            | Value |
| ------------------------------ | ----------------- | ----- |
| open                           | /                 |       |
| click                          | btnConfirm        |       |
| chooseCancelOnNextConfirmation |                   |       |
| assertConfirmation             | Choose an option. |       |
| verifyTextPresent              | Rejected          |       |

The `chooseCancelOnNextConfirmation` function tells Selenium that all following confirmation should return false. It can be reset by calling chooseOkOnNextConfirmation.

You may notice that you cannot replay this test, because Selenium complains that there is an unhandled confirmation. This is because the order of events Selenium-IDE records causes the click and chooseCancelOnNextConfirmation to be put in the wrong order (it makes sense if you think about it, Selenium can’t know that you’re cancelling before you open a confirmation) Simply switch these two commands and your test will run fine.

### Prompts

Prompts behave in much the same way as alerts, with `assertPrompt` and `assertPromptPresent` offering the same characteristics as their alert counterparts. By default, Selenium will wait for you to input data when the prompt pops up. Try recording clicking on the “Show prompt” button in the sample page and enter “Selenium” into the prompt. Your test may look something like this:

| Command            | Target                       | Value |
| ------------------ | ---------------------------- | ----- |
| open               | /                            |       |
| answerOnNextPrompt | Selenium!                    |       |
| click              | id=btnPrompt                 |       |
| assertPrompt       | What’s the best web QA tool? |       |
| verifyTextPresent  | Selenium!                    |       |

```html
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Sample Selenium Test Suite</title>
    </head>
    <body>
        <table cellpadding="1" cellspacing="1" border="1">
            <thead>
                <tr><td>Test Cases for De Anza A-Z Directory Links</td></tr>
            </thead>
        <tbody>
            <tr><td><a href="./a.html">A Links</a></td></tr>
            <tr><td><a href="./b.html">B Links</a></td></tr>
            <tr><td><a href="./c.html">C Links</a></td></tr>
            <tr><td><a href="./d.html">D Links</a></td></tr>
        </tbody>
        </table>
    </body>
</html>
```

***

*error loading test case: no command found*

You’ve used **File=>Open** to try to open a test suite file. Use **File=>Open Test Suite** instead.

An enhancement request has been raised to improve this error message. See [issue 1010](http://code.google.com/p/selenium/issues/detail?id=1010).

***

This type of **error** may indicate a timing problem, i.e., the element specified by a locator in your command wasn’t fully loaded when the command was executed. Try putting a **pause 5000** before the command to determine whether the problem is indeed related to timing. If so, investigate using an appropriate **waitFor\*** or **\*AndWait** command before the failing command.

***

Whenever your attempt to use variable substitution fails as is the case for the **open** command above, it indicates that you haven’t actually created the variable whose value you’re trying to access. This is sometimes due to putting the variable in the **Value** field when it should be in the **Target** field or vice versa. In the example above, the two parameters for the **store** command have been erroneously placed in the reverse order of what is required. For any Selenese command, the first required parameter must go in the **Target** field, and the second required parameter (if one exists) must go in the **Value** field.

***

*error loading test case: \[Exception… “Component returned failure code: 0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND) \[nsIFileInputStream.init]” nresult: “0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND)” location: “JS frame :: chrome://selenium-ide/content/file-utils.js :: anonymous :: line 48” data: no]*

One of the test cases in your test suite cannot be found. Make sure that the test case is indeed located where the test suite indicates it is located. Also, make sure that your actual test case files have the .html extension both in their filenames, and in the test suite file where they are referenced.

An enhancement request has been raised to improve this error message. See [issue 1011](http://code.google.com/p/selenium/issues/detail?id=1011).

***

Your extension file’s contents have not been read by Selenium-IDE. Be sure you have specified the proper pathname to the extensions file via **Options=>Options=>General** in the **Selenium Core extensions** field. Also, Selenium-IDE must be restarted after any change to either an extensions file *or* to the contents of the **Selenium Core extensions** field.

# 4.1 - HTML runner

```shell
[user@localhost ~]$ cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

[user@localhost ~]$ rpm -qa | egrep -i "xvfb|java-1.8|firefox"
xorg-x11-server-Xvfb-1.19.3-11.el7.x86_64
firefox-52.4.0-1.el7.centos.x86_64
java-1.8.0-openjdk-1.8.0.151-1.b12.el7_4.x86_64
java-1.8.0-openjdk-headless-1.8.0.151-1.b12.el7_4.x86_64
```

Test Suite 示例：

```html
[user@localhost ~]$ cat testsuite.html
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
  <title>Test Suite</title>
</head>
<body>
<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium"><tbody>
<tr><td><b>Test Suite</b></td></tr>
<tr><td><a href="YOUR-TEST-SCENARIO.html">YOUR-TEST-SCENARIO</a></td></tr>
</tbody></table>
</body>
</html>
```

## 如何运行 selenium-html-runner headless

现在，最重要的部分，一个如何运行 selenium-html-runner 的例子！ 您的体验可能因软件组合而异 - geckodriver / FF / html-runner 版本。

```shell
xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
```

```shell
[user@localhost ~]$ xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "*firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
Multi-window mode is longer used as an option and will be ignored.
1510061109691   geckodriver     INFO    geckodriver 0.18.0
1510061109708   geckodriver     INFO    Listening on 127.0.0.1:2885
1510061110162   geckodriver::marionette INFO    Starting browser /usr/bin/firefox with args ["-marionette"]
1510061111084   Marionette      INFO    Listening on port 43229
1510061111187   Marionette      WARN    TLS certificate errors will be ignored for this session
Nov 07, 2017 1:25:12 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
2017-11-07 13:25:12.714:INFO::main: Logging initialized @3915ms to org.seleniumhq.jetty9.util.log.StdErrLog
2017-11-07 13:25:12.804:INFO:osjs.Server:main: jetty-9.4.z-SNAPSHOT
2017-11-07 13:25:12.822:INFO:osjsh.ContextHandler:main: Started o.s.j.s.h.ContextHandler@87a85e1{/tests,null,AVAILABLE}
2017-11-07 13:25:12.843:INFO:osjs.AbstractConnector:main: Started ServerConnector@52102734{HTTP/1.1,[http/1.1]}{0.0.0.0:31892}
2017-11-07 13:25:12.843:INFO:osjs.Server:main: Started @4045ms
Nov 07, 2017 1:25:13 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |open | /auth_mellon.php |  |
Nov 07, 2017 1:25:14 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |waitForPageToLoad | 3000 |  |
.
.
.etc

<td>result:</td>
<td>PASS</td>
```

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/interactions/alerts/
----

# JavaScript 警告框,提示框和确认框

```java

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L36-L41)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L12-L18)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See an example alert")).Click();

//Wait for the alert to be displayed and store it in a variable
IAlert alert = wait.Until(ExpectedConditions.AlertIsPresent());

//Store the alert text in a variable
string text = alert.Text;

//Press the OK button
alert.Accept();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L15-L22)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L19-L21)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See an example alert")).click()

//Wait for the alert to be displayed and store it in a variable
val alert = wait.until(ExpectedConditions.alertIsPresent())

//Store the alert text in a variable
val text = alert.getText()

//Press the OK button
alert.accept()
  
```

```java
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L131-L138)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L26-L32)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See a sample confirm")).Click();

//Wait for the alert to be displayed
wait.Until(ExpectedConditions.AlertIsPresent());

//Store the alert in a variable
IAlert alert = driver.SwitchTo().Alert();

//Store the alert in a variable for reuse
string text = alert.Text;

//Press the Cancel button
alert.Dismiss();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L28-L35)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L30-L32)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See a sample confirm")).click()

//Wait for the alert to be displayed
wait.until(ExpectedConditions.alertIsPresent())

//Store the alert in a variable
val alert = driver.switchTo().alert()

//Store the alert in a variable for reuse
val text = alert.text

//Press the Cancel button
alert.dismiss()
  
```

```java
        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L79-L84)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L40-L47)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See a sample prompt")).Click();

//Wait for the alert to be displayed and store it in a variable
IAlert alert = wait.Until(ExpectedConditions.AlertIsPresent());

//Type your message
alert.SendKeys("Selenium");

//Press the OK button
alert.Accept();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L41-L48)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L42-L45)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See a sample prompt")).click()

//Wait for the alert to be displayed and store it in a variable
val alert = wait.until(ExpectedConditions.alertIsPresent())

//Type your message
alert.sendKeys("Selenium")

//Press the OK button
alert.accept()
  
```

最后修改 August 14, 2025: [Fixing path for code block (c7fcb0099f5)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/c7fcb0099f58ba4d4dd467a8c6667f6130749d82)

----
url: https://www.selenium.dev/documentation/legacy/selenium_2/firefox_driver/
----

# Legacy Firefox Driver

| **Property**                  | **What it means**                                                                                                                                                                 |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| webdriver.firefox.bin         | The location of the binary used to control firefox.                                                                                                                               |
| webdriver.firefox.marionette  | Boolean value, if set on standalone-server will ignore any “marionette” desired capability requested and force firefox to use GeckoDriver (true) or Legacy Firefox Driver (false) |
| webdriver.firefox.profile     | The name of the profile to use when starting firefox. This defaults to webdriver creating an anonymous profile                                                                    |
| webdriver.firefox.useExisting | **Never use in production** Use a running instance of firefox if one is present                                                                                                   |
| webdriver.firefox.logfile     | Log file to dump firefox stdout/stderr to                                                                                                                                         |

Normally the Firefox binary is assumed to be in the default location for your particular operating system:

| **OS**  | **Expected Location of Firefox**                     |
| ------- | ---------------------------------------------------- |
| Linux   | firefox (found using “which”)                        |
| Mac     | /Applications/Firefox.app/Contents/MacOS/firefox-bin |
| Windows | %PROGRAMFILES%\Mozilla Firefox\firefox.exe           |

By default, the Firefox driver creates an anonymous profile

### Running with firebug

Download the firebug xpi file from mozilla and start the profile as follows:

```
   File file = new File("firebug-1.8.1.xpi");
   FirefoxProfile firefoxProfile = new FirefoxProfile();
   firefoxProfile.addExtension(file);
   firefoxProfile.setPreference("extensions.firebug.currentVersion", "1.8.1"); // Avoid startup screen

   WebDriver driver = new FirefoxDriver(firefoxProfile);
```

## FirefoxDriver Internals

(Previously located: <https://github.com/SeleniumHQ/selenium/wiki/FirefoxDriver-Internals>)

The FirefoxDriver is largely written in the form of a Firefox extension. Language bindings control the driver by connecting over a socket and sending commands (described in the JsonWireProtocol page) in UTF-8. The extension makes use of the XPCOM primitives offered by Firefox in order to do its work. The important thing to notice is that the command names map directly on to methods exposed on the “FirefoxDriver.prototype” in the javascript code.

### Working on the FirefoxDriver Code

Firstly, make sure that there’s no old version of the FirefoxDriver installed:

* Start firefox’s profile manager: `firefox -ProfileManager`
* Delete the existing WebDriver profile if there is one. Delete the files too (it’s an option that’s offered when you delete the profile in the profile manager)

Secondly, take a look at the [Mozilla Developer Center](http://developer.mozilla.org/en/docs/Extensions), particularly the section to do with [setting up an extension development environment](http://developer.mozilla.org/en/docs/Setting_up_extension_development_environment). You should now be ready to edit code. It’s best to create a test around the area of code that you’re working on, and to run this using the `SingleTestSuite`. The FirefoxDriver logs errors to Firefox’s error console (“Tools->Error Console”), so if a test fails, that’s a great place to start looking.

To actually log information to the console, use the “`Utils.dumpn()`” method in your javascript code. If you find that you’d like to examine an object in detail, use the “`Utils.dump()`” method, which will report which interfaces an object implements, as well as outputting as much information as it can to the console..

### Flow of Control: Starting Firefox

The following steps are performed when instantiating an instance of the FirefoxDriver:

1. Grab the “locking port”

----
url: https://www.selenium.dev/documentation/legacy/selenium_3/
----

# Selenium 3

Selenium 3 was the implementation of WebDriver without the Selenium RC Code. It has since been replaced with Selenium 4, which implements the W3C WebDriver specification.

***

##### [Grid 3](/documentation/legacy/selenium_3/grid_3/)

Selenium Grid 3 supported WebDriver without Selenium RC code. Grid 3 was completely rewritten for the new Grid 4.

##### [Setting up your own Grid 3](/documentation/legacy/selenium_3/grid_setup/)

Quick start guide for setting up Grid 3.

##### [Components of Grid 3](/documentation/legacy/selenium_3/grid_components/)

Description of Hub and Nodes for Grid 3.

----
url: https://www.selenium.dev/pt-br/documentation/grid/advanced_features/
----

# Características avançadas

Para obter todos os detalhes dos recursos avançados, entenda como funciona e como configurar crie o seu próprio, navegue pelas seções a seguir.

***

##### [Observabilidade](/pt-br/documentation/grid/advanced_features/observability/)

##### [Suporte a buscas em GraphQL](/pt-br/documentation/grid/advanced_features/graphql_support/)

##### [Rotas da Grid](/pt-br/documentation/grid/advanced_features/endpoints/)

##### [Personalizando um Nó](/pt-br/documentation/grid/advanced_features/customize_node/)

##### [External datastore](/pt-br/documentation/grid/advanced_features/external_datastore/)

----
url: https://www.selenium.dev/zh-cn/_print/documentation/webdriver/support_features/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/webdriver/support_features/).

# Support features

针对更高层面功能的额外支持类.

* 1: [期望状态的等待](#pg-ac213eccad8e0550782dfbe0907960ec)
* 2: [命令监听器](#pg-4d347a4c6b6308b10db6431c825c45da)
* 3: [同颜色一起工作](#pg-edfb74a9d3262c82ae81f16b9730085c)
* 4: [线程守卫](#pg-830a71d40e5708fb519ae11144dc82fb)
* 5: [使用选择列表元素](#pg-9a457f2e1f60852531f70b4d351cd147)

Selenium的核心库试图提供底层以及普适的功能. 每种语言的支持类都为常见交互提供特定的包装器, 可用于简化某些行为.

# 1 - 期望状态的等待

```py
    wait = WebDriverWait(driver, timeout=2)
    wait.until(EC.visibility_of_element_located((By.ID, "revealed")))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_expected_conditions.py#L14-L15)

##### /examples/python/tests/support/test\_expected\_conditions.py

```py
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

# Expected Conditions API Documentation:
# https://www.selenium.dev/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html


def test_expected_condition(driver):
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html")
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(EC.visibility_of_element_located((By.ID, "revealed")))

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"
```

.NET stopped supporting Expected Conditions in Selenium 4 to minimize maintenance hassle and redundancy.

Ruby makes frequent use of blocks, procs and lambdas and does not need Expected Conditions classes

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

# 2 - 命令监听器


# 3 - 同颜色一起工作

```java
import org.openqa.selenium.support.Color;
  
```

```python
from selenium.webdriver.support.color import Color
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
include Selenium::WebDriver::Support
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
import org.openqa.selenium.support.Color
```

```java
private final Color HEX_COLOUR = Color.fromString("#2F7ED8");
private final Color RGB_COLOUR = Color.fromString("rgb(255, 255, 255)");
private final Color RGB_COLOUR = Color.fromString("rgb(40%, 20%, 40%)");
private final Color RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)");
private final Color RGBA_COLOUR = Color.fromString("rgba(40%, 20%, 40%, 0.5)");
private final Color HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)");
private final Color HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)");
  
```

```python
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
private val HEX_COLOUR = Color.fromString("#2F7ED8")
private val RGB_COLOUR = Color.fromString("rgb(255, 255, 255)")
private val RGB_COLOUR_PERCENT = Color.fromString("rgb(40%, 20%, 40%)")
private val RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)")
private val RGBA_COLOUR_PERCENT = Color.fromString("rgba(40%, 20%, 40%, 0.5)")
private val HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)")
private val HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)")
  
```

```java
private final Color BLACK = Color.fromString("black");
private final Color CHOCOLATE = Color.fromString("chocolate");
private final Color HOTPINK = Color.fromString("hotpink");
  
```

```python
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
private val BLACK = Color.fromString("black")
private val CHOCOLATE = Color.fromString("chocolate")
private val HOTPINK = Color.fromString("hotpink")
  
```

```java
private final Color TRANSPARENT = Color.fromString("transparent");
  
```

```python
TRANSPARENT = Color.from_string('transparent')
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
TRANSPARENT = Color.from_string('transparent')
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
private val TRANSPARENT = Color.fromString("transparent")
  
```

```java
Color loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"));

Color loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"));
  
```

```python
login_button_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('color'))

login_button_background_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('background-color'))
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
login_button_colour = Color.from_string(driver.find_element(id: 'login').css_value('color'))

login_button_background_colour = Color.from_string(driver.find_element(id: 'login').css_value('background-color'))
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
val loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"))

val loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"))
  
```

```java
assert loginButtonBackgroundColour.equals(HOTPINK);
  
```

```python
assert login_button_background_colour == HOTPINK
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
assert(login_button_background_colour == HOTPINK)
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
assert(loginButtonBackgroundColour.equals(HOTPINK))
  
```

```java
assert loginButtonBackgroundColour.asHex().equals("#ff69b4");
assert loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)");
assert loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)");
  
```

```python
assert login_button_background_colour.hex == '#ff69b4'
assert login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)'
assert login_button_background_colour.rgb == 'rgb(255, 105, 180)'
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
assert(login_button_background_colour.hex == '#ff69b4')
assert(login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)')
assert(login_button_background_colour.rgb == 'rgb(255, 105, 180)')
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
assert(loginButtonBackgroundColour.asHex().equals("#ff69b4"))
assert(loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)"))
assert(loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)"))
  
```

颜色不再是问题.

# 4 - 线程守卫

此类仅在Java中可用

ThreadGuard检查是否仅从创建驱动程序的同一线程中调用了驱动程序. 线程问题 (尤其是在Parallel中运行测试时) 可能遇到神秘并且难以诊断错误. 使用此包装器可以防止此类错误,\
并且在发生此类情况时会抛出异常.

以下的示例模拟一种线程冲突的情况:

```java
public class DriverClash {
  //thread main (id 1) created this driver
  private WebDriver protectedDriver = ThreadGuard.protect(new ChromeDriver());

  static {
    System.setProperty("webdriver.chrome.driver", "<Set path to your Chromedriver>");
  }

  //Thread-1 (id 24) is calling the same driver causing the clash to happen
  Runnable r1 = () -> {protectedDriver.get("https://selenium.dev");};
  Thread thr1 = new Thread(r1);

  void runThreads(){
    thr1.start();
  }

  public static void main(String[] args) {
    new DriverClash().runThreads();
  }
}
```

结果如下所示:

```text
Exception in thread "Thread-1" org.openqa.selenium.WebDriverException:
Thread safety error; this instance of WebDriver was constructed
on thread main (id 1)and is being accessed by thread Thread-1 (id 24)
This is not permitted and *will* cause undefined behaviour
```

# 5 - 使用选择列表元素

```html
<select name="selectomatic">
    <option selected="selected" id="non_multi_option" value="one">One</option>
    <option value="two">Two</option>
    <option value="four">Four</option>
    <option value="still learning how to count, apparently">Still learning how to count, apparently</option>
</select>
```

### 复选

此选择列表允许同时选定和取消选择多个选项. 这仅适用于具有 `multiple` 属性的 `<select>`元素.

```html
<select name="multi" id="multi" multiple="multiple">
    <option selected="selected" value="eggs">Eggs</option>
    <option value="ham">Ham</option>
    <option selected="selected" value="sausages">Sausages</option>
    <option value="onion gravy">Onion gravy</option>
</select>
```

```java
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L23-L24)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L9-L10)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L23-L24)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L13-L14)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js

  it('Select an option', async function () {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L18-L19)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L20-L21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        List<WebElement> optionList = select.getOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L51)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    option_list = select.options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L37)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            IList<IWebElement> optionList = select.Options;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L52)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    option_list = select.options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L40)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L45)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val optionList = select.getOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L48)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L54)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    selected_option_list = select.all_selected_options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L40)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L56)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    selected_option_list = select.selected_options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L43)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L51)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val selectedOptionList = select.getAllSelectedOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L51)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByVisibleText("Four");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L30)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_visible_text('Four')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L16)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByText("Four");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L30)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:text, 'Four')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L20)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L25)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByVisibleText("Four")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L27)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByValue("two");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L33)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_value('two')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L19)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByValue("two");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L33)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:value, 'two')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L23)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await fourElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L28)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByValue("two")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L30)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByIndex(3);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L36)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_index(3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L22)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByIndex(3);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L36)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:index, 3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L26)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await twoElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L31)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByIndex(3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L33)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

### 禁用的选项

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

具有 `disabled` 属性的选项可能无法被选择.

```html
    <select name="single_disabled">
      <option id="sinlge_disabled_1" value="enabled">Enabled</option>
      <option id="sinlge_disabled_2" value="disabled" disabled="disabled">Disabled</option>
    </select>
```

*
*
*
*
*
*

```java
        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L77-L79)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L60-L61)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L77)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L62-L64)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L73-L76)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L74-L76)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.deselectByValue("eggs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L66)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.deselect_by_value('eggs')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L49)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.DeselectByValue("eggs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L65)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.deselect_by(:value, 'eggs')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L52)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await gravyElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L63)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.deselectByValue("eggs")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

----
url: https://www.selenium.dev/documentation/webdriver/getting_started/first_script/
----

# Write your first Selenium script

```java
        WebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver = webdriver.Chrome()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L4)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L11)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver = Selenium::WebDriver.for :chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L3)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    driver = await new Builder().forBrowser(Browser.CHROME).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L8)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver = ChromeDriver()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L16)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.get("https://www.selenium.dev/selenium/web/web-form.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L6)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L13)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.get('https://www.selenium.dev/selenium/web/web-form.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L5)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L9)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.get("https://www.selenium.dev/selenium/web/web-form.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L18)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#16)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L8)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var title = driver.Title;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L15)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L7)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let title = await driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L11)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L20)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L18)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.implicitly_wait(0.5)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L10)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L17)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.manage.timeouts.implicit_wait = 500
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L9)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.manage().setTimeouts({implicit: 500});
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L14)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L23)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L20-L21)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L12-L13)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L19-L20)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L11-L12)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L16-L17)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L25-L26)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        textBox.sendKeys("Selenium");
        submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L23-L24)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
text_box.send_keys("Selenium")
submit_button.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L15-L16)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        textBox.SendKeys("Selenium");
        submitButton.Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
text_box.send_keys('Selenium')
submit_button.click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L14-L15)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await textBox.sendKeys('Selenium');
    await submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L19-L20)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        textBox.sendKeys("Selenium")
        submitButton.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L28-L29)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        WebElement message = driver.findElement(By.id("message"));
        message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-27)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
message = driver.find_element(by=By.ID, value="message")
text = message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L18-19)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-26)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
message = driver.find_element(id: 'message')
message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L17-18)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L22-23)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val message = driver.findElement(By.id("message"))
        val value = message.getText()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-32)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L21)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L28)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L20)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L28)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L35)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```md
mvn exec:java -D"exec.mainClass"="dev.selenium.getting_started.FirstScript" -D"exec.classpathScope"=test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/README.md#L60)

##### /examples/java/README.md

````md
# Running Selenium Java Tests
The following steps will guide you on how to 
run Selenium Java tests using a repository 
of `SeleniumHQ/seleniumhq.github.io` examples.

## Initial Setup

### Prerequisites

Ensure that Java Development Kit (JDK) and Maven 
are installed on your system. If they are not installed, 
you will need to download and install them. You can 
find detailed installation guides for both on their 
respective official sites.

### Clone the repository
First, we need to get the Selenium Java examples 
on your local machine. This can be done by 
cloning the `SeleniumHQ/seleniumhq.github.io` Git repository. 
Run the following command in your terminal:

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```
## Navigate to the java directory
After cloning the repository, navigate into the 
directory where the Selenium Java examples are 
located. Run the following command:

```bash
cd seleniumhq.github.io/examples/java
```

## Running the Tests
### Install dependencies
Before running the tests, we need to install all 
necessary dependencies. Maven, a software 
project management tool, can do this for us. 
Run the following command:

```bash
mvn test-compile
```

### Run all tests
To verify if everything is installed correctly and 
functioning properly, we should run all 
available tests. This can be done with the following command:

```bash
mvn test
```

Please be patient! If this is your first time running these tests, 
it might take a while to download and verify all necessary browser drivers.

## Execute a specific example
To run a specific Selenium Java example, use the following command:
```bash
mvn exec:java -D"exec.mainClass"="dev.selenium.getting_started.FirstScript" -D"exec.classpathScope"=test
```

Make sure to replace `dev.selenium.getting_started.FirstScript` with the path and name of the example you want to run.
````

```md
pytest path/to/test_script.py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/README.md#L58)

##### /examples/python/README.md

````md
# Running tests from Selenium Python examples

#### 1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

#### 2. Navigate to `python` directory

```
cd seleniumhq.github.io/examples/python
```

#### 3. Create a virtual environment

- On Windows:

```
py -m venv venv
venv\Scripts\activate
```

- On Linux/Mac:

```
python3 -m venv venv
source venv/bin/activate
```

#### 4. Install dependencies:

```
pip install -r requirements.txt
```

> for help, see: https://packaging.python.org/en/latest/tutorials/installing-packages

#### 5. Run tests

- Run all tests with the default Python interpreter:

```
pytest
```

- Run all tests with every installed/supported Python interpreter:

```
tox
```

> Please have some patience - If you are doing it for the first time, it will take a little while to download the browser drivers

- Run a specific example:

```
pytest path/to/test_script.py
```

> Make sure to replace `path/to/test_script.py` with the path and name of the example you want to run
````

```md
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/README.md#L55)

##### /examples/dotnet/README.md

````md
# Running Selenium .NET (C#) Tests

The following steps will guide you on how to  
run Selenium .NET (C#) tests using the examples  
from the `SeleniumHQ/seleniumhq.github.io` repository.

## Initial Setup

### Prerequisites

Ensure you have the following installed:

- [.NET SDK (8.0 or later)](https://dotnet.microsoft.com/en-us/download)
- An IDE like [Visual Studio](https://visualstudio.microsoft.com/) or [Visual Studio Code](https://code.visualstudio.com/)
- [.NET CLI tools](https://learn.microsoft.com/en-us/dotnet/core/tools/)

### Clone the repository

Clone the Selenium documentation repository to your local machine:

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

## Navigate to the .NET directory
### Change into the .NET examples directory:

```bash
cd seleniumhq.github.io/examples/dotnet/SeleniumDocs
```

## Running the Tests
### Restore dependencies
Install necessary dependencies using the .NET CLI:

```bash
dotnet restore
```

### Run all tests
To run all available tests:

```bash
dotnet test
```

### Run a Specific Test Method
To run a specific test method using its fully qualified name:

```bash
dotnet test --filter "FullyQualifiedName=Namespace.ClassName.MethodName"
```
For example:
```bash
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

You can also filter by test name only (if it's unique):
```bash
dotnet test --filter "Name=EightComponents"
```
````

```md
ruby example_script.rb
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/README.md#L36)

##### /examples/ruby/README.md

````md
# Running all tests from Selenium ruby example

Follow these steps to run all test example from selenium ruby

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `ruby` directory

```
cd seleniumhq.github.io/examples/ruby
```

3. Install dependencies using bundler

```
bundler install
```

4. Run all tests

```
bundle exec rspec
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a ruby script

Use this command to run a ruby script and follow the first script example

```
ruby example_script.rb
```
````

```md
node example_script.spec.js
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/README.md#L36)

##### /examples/javascript/README.md

````md
# Running all tests from Selenium javascript example

Follow these steps to run all test example from selenium javascript

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `javascript` directory

```
cd seleniumhq.github.io/examples/javascript
```

3. Install dependencies using node

```
npm install
```

4. Run all all tests

```
npm test
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a javascript test

Use this command to run a JavaScript and follow the first script example

```
node example_script.spec.js
```
````

[Add Example](/documentation/about/contributing/#creating-examples)

## Next Steps

Most Selenium users execute many sessions and need to organize them to minimize duplication and keep the code more maintainable. Read on to learn about how to put this code into context for your use case with [Using Selenium](https://www.selenium.dev/documentation/webdriver/getting_started/using_selenium/).

Last modified January 23, 2026: [fix: gh-codeblock pointing to an incorrect line (#2552) (00b92fbefcb)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/00b92fbefcb2d1176bc8ab81c6a3252cb7f33faa)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/getting_started/first_script/
----

# 编写第一个Selenium脚本

```java
        WebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver = webdriver.Chrome()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L4)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L11)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver = Selenium::WebDriver.for :chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L3)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    driver = await new Builder().forBrowser(Browser.CHROME).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L8)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver = ChromeDriver()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L16)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.get("https://www.selenium.dev/selenium/web/web-form.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L6)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L13)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.get('https://www.selenium.dev/selenium/web/web-form.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L5)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L9)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.get("https://www.selenium.dev/selenium/web/web-form.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L18)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#16)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L8)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var title = driver.Title;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L15)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L7)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let title = await driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L11)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L20)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L18)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.implicitly_wait(0.5)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L10)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L17)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.manage.timeouts.implicit_wait = 500
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L9)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.manage().setTimeouts({implicit: 500});
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L14)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L23)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L20-L21)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L12-L13)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L19-L20)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L11-L12)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L16-L17)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L25-L26)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        textBox.sendKeys("Selenium");
        submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L23-L24)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
text_box.send_keys("Selenium")
submit_button.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L15-L16)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        textBox.SendKeys("Selenium");
        submitButton.Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
text_box.send_keys('Selenium')
submit_button.click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L14-L15)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await textBox.sendKeys('Selenium');
    await submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L19-L20)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        textBox.sendKeys("Selenium")
        submitButton.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L28-L29)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        WebElement message = driver.findElement(By.id("message"));
        message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-27)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
message = driver.find_element(by=By.ID, value="message")
text = message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L18-19)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-26)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
message = driver.find_element(id: 'message')
message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L17-18)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L22-23)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val message = driver.findElement(By.id("message"))
        val value = message.getText()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-32)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L21)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L28)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L20)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L28)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L35)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```md
mvn exec:java -D"exec.mainClass"="dev.selenium.getting_started.FirstScript" -D"exec.classpathScope"=test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/README.md#L60)

##### /examples/java/README.md

````md
# Running Selenium Java Tests
The following steps will guide you on how to 
run Selenium Java tests using a repository 
of `SeleniumHQ/seleniumhq.github.io` examples.

## Initial Setup

### Prerequisites

Ensure that Java Development Kit (JDK) and Maven 
are installed on your system. If they are not installed, 
you will need to download and install them. You can 
find detailed installation guides for both on their 
respective official sites.

### Clone the repository
First, we need to get the Selenium Java examples 
on your local machine. This can be done by 
cloning the `SeleniumHQ/seleniumhq.github.io` Git repository. 
Run the following command in your terminal:

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```
## Navigate to the java directory
After cloning the repository, navigate into the 
directory where the Selenium Java examples are 
located. Run the following command:

```bash
cd seleniumhq.github.io/examples/java
```

## Running the Tests
### Install dependencies
Before running the tests, we need to install all 
necessary dependencies. Maven, a software 
project management tool, can do this for us. 
Run the following command:

```bash
mvn test-compile
```

### Run all tests
To verify if everything is installed correctly and 
functioning properly, we should run all 
available tests. This can be done with the following command:

```bash
mvn test
```

Please be patient! If this is your first time running these tests, 
it might take a while to download and verify all necessary browser drivers.

## Execute a specific example
To run a specific Selenium Java example, use the following command:
```bash
mvn exec:java -D"exec.mainClass"="dev.selenium.getting_started.FirstScript" -D"exec.classpathScope"=test
```

Make sure to replace `dev.selenium.getting_started.FirstScript` with the path and name of the example you want to run.
````

````md
```
````

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/README.md#L35)

##### /examples/python/README.md

````md
# Running tests from Selenium Python examples

#### 1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

#### 2. Navigate to `python` directory

```
cd seleniumhq.github.io/examples/python
```

#### 3. Create a virtual environment

- On Windows:

```
py -m venv venv
venv\Scripts\activate
```

- On Linux/Mac:

```
python3 -m venv venv
source venv/bin/activate
```

#### 4. Install dependencies:

```
pip install -r requirements.txt
```

> for help, see: https://packaging.python.org/en/latest/tutorials/installing-packages

#### 5. Run tests

- Run all tests with the default Python interpreter:

```
pytest
```

- Run all tests with every installed/supported Python interpreter:

```
tox
```

> Please have some patience - If you are doing it for the first time, it will take a little while to download the browser drivers

- Run a specific example:

```
pytest path/to/test_script.py
```

> Make sure to replace `path/to/test_script.py` with the path and name of the example you want to run
````

```md
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/README.md#L55)

##### /examples/dotnet/README.md

````md

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

## Navigate to the .NET directory
### Change into the .NET examples directory:

```bash
cd seleniumhq.github.io/examples/dotnet/SeleniumDocs
```

## Running the Tests
### Restore dependencies
Install necessary dependencies using the .NET CLI:

```bash
dotnet restore
```

### Run all tests
To run all available tests:

```bash
dotnet test
```

### Run a Specific Test Method
To run a specific test method using its fully qualified name:

```bash
dotnet test --filter "FullyQualifiedName=Namespace.ClassName.MethodName"
```
For example:
```bash
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

You can also filter by test name only (if it's unique):
```bash
dotnet test --filter "Name=EightComponents"
```
````

```md
ruby example_script.rb
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/README.md#L36)

##### /examples/ruby/README.md

````md
# Running all tests from Selenium ruby example

Follow these steps to run all test example from selenium ruby

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `ruby` directory

```
cd seleniumhq.github.io/examples/ruby
```

3. Install dependencies using bundler

```
bundler install
```

4. Run all tests

```
bundle exec rspec
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a ruby script

Use this command to run a ruby script and follow the first script example

```
ruby example_script.rb
```
````

```md
node example_script.spec.js
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/README.md#L36)

##### /examples/javascript/README.md

````md
# Running all tests from Selenium javascript example

Follow these steps to run all test example from selenium javascript

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `javascript` directory

```
cd seleniumhq.github.io/examples/javascript
```

3. Install dependencies using node

```
npm install
```

4. Run all all tests

```
npm test
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a javascript test

Use this command to run a JavaScript and follow the first script example

```
node example_script.spec.js
```
````

[Add Example](/documentation/about/contributing/#creating-examples)

## 接下来的步骤

大多数 Selenium 用户执行许多会话， 需要组织它们以最大限度地减少重复并维持代码更易于维护. 请继续阅读，了解如何将此代码放入您用例的上下文中 [使用 Selenium](https://www.selenium.dev/zh-cn/documentation/webdriver/getting_started/using_selenium/).

最后修改 October 30, 2025: [Update "First Script" documentation with C# example from .NET README (#2478) (e55b319492d)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e55b319492d1e4062020fe6c23d46dae22b4b2aa)

## Development Partners

[](https://www.browserstack.com/automate?utm_campaign=open-source-sponsor\&utm_campaigncode=701OW000009sQwVYAU\&utm_medium=partnered\&utm_source=seleniumorg)

[](https://saucelabs.com/resources/topic-hub/selenium?utm_source=selenium\&utm_medium=website\&utm_campaign=selenium-sponsorship-fy25)

[](https://www.testmuai.com)

## Selenium Level Sponsors

[](https://brightdata.com/?utm_source=brand\&utm_campaign=brnd-mkt_partners_selenium)

[](https://applitools.com/)

[](https://www.thordata.com/?ls=waOicIkB\&lk=selenium)

## Support the Selenium Project

Learn more or view the full list of sponsors.

[Learn more**](/sponsors)

----
url: https://www.selenium.dev/_print/documentation/ie_driver_server/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/ie_driver_server/).

# IE Driver Server

The Internet Explorer Driver is a standalone server that implements the WebDriver specification.

* 1: [Internet Explorer Driver Internals](#pg-00fdd2cd8e8fe5a9568fcebae1f97c1a)

| Switch                         | Meaning                                                                                                                                                        |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| –port=`<portNumber>`           | Specifies the port on which the HTTP server of the IE driver will listen for commands from language bindings. Defaults to 5555.                                |
| –host=`<hostAdapterIPAddress>` | Specifies the IP address of the host adapter on which the HTTP server of the IE driver will listen for commands from language bindings. Defaults to 127.0.0.1. |
| –log-level=`<logLevel>`        | Specifies the level at which logging messages are output. Valid values are FATAL, ERROR, WARN, INFO, DEBUG, and TRACE. Defaults to FATAL.                      |
| –log-file=`<logFile>`          | Specifies the full path and file name of the log file. Defaults to stdout.                                                                                     |
| –extract-path=`<path>`         | Specifies the full path to the directory used to extract supporting files used by the server. Defaults to the TEMP directory if not specified.                 |
| –silent                        | Suppresses diagnostic output when the server is started.                                                                                                       |

## Important System Properties

The following system properties (read using `System.getProperty()` and set using `System.setProperty()` in Java code or the “`-DpropertyName=value`” command line flag) are used by the `InternetExplorerDriver`:

| **Property**                      | **What it means**                                                                                                                              |
| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `webdriver.ie.driver`             | The location of the IE driver binary.                                                                                                          |
| `webdriver.ie.driver.host`        | Specifies the IP address of the host adapter on which the IE driver will listen.                                                               |
| `webdriver.ie.driver.loglevel`    | Specifies the level at which logging messages are output. Valid values are FATAL, ERROR, WARN, INFO, DEBUG, and TRACE. Defaults to FATAL.      |
| `webdriver.ie.driver.logfile`     | Specifies the full path and file name of the log file.                                                                                         |
| `webdriver.ie.driver.silent`      | Suppresses diagnostic output when the IE driver is started.                                                                                    |
| `webdriver.ie.driver.extractpath` | Specifies the full path to the directory used to extract supporting files used by the server. Defaults to the TEMP directory if not specified. |

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/actions_api/wheel/
----

# Ações de Roda de Rolagem

```java
        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L17-L20)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L11-L14)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L11-L14)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L16-L19)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L18-L21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L29-L33)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L22-L26)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L31-L35)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L22-L26)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L26-L31)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L30-L34)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L42-L46)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L35-L39)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L46-L53)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L34-L38)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L40-L44)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L43-L47)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L57-L61)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L50-L54)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L66-L75)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L48-L52)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L57-L61)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L59-L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L73-L76)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L66-L70)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L89-L97)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L63-L66)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L75-L77)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L75-L78)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

----
url: https://www.selenium.dev/documentation/legacy/selenium_2/grid_2/
----

# Selenium grid 2

> This example will show you how to start the Selenium 2 Hub, and register both a WebDriver node and a Selenium 1 RC legacy node. We’ll also show you how to call the grid from Java. The hub and nodes are shown here running on the same machine, but of course you can copy the selenium-server-standalone to multiple machines. Note: The selenium-server-standalone package includes the Hub, WebDriver, and legacy RC needed to run the grid. Ant is not required anymore. You can download the selenium-server-standalone-`*`.jar from <http://selenium-release.storage.googleapis.com/index.html> This walk-through assumes you already have Java installed.

**Step 1: Start the hub**

The Hub is the central point that will receive all the test request and distribute them the the right nodes.

Open a command prompt and navigate to the directory where you copied the selenium-server-standalone file. Type the following command:

```
java -jar selenium-server-standalone-<version>.jar -role hub
```

The hub will automatically start-up using port 4444 by default. To change the default port, you can add the optional parameter -port when you run the command. You can view the status of the hub by opening a browser window and navigating to: http\://localhost:4444/grid/console

**Step 2: Start the nodes**

Regardless on whether you want to run a grid with new WebDriver functionality, or a grid with Selenium 1 RC functionality, or both at the same time, you use the same selenium-server-standalone jar file to start the nodes.

```
java -jar selenium-server-standalone-<version>.jar -role node  -hub http://localhost:4444/grid/register
```

Note: The port defaults to 5555 if not specified whenever the “-role” option is provided and is not hub.

For backwards compatibility “wd” and “rc” roles are still a valid subset of the “node” role. But those roles limit the types of remote connections to their corresponding API, while “node” allows both RC and WebDriver remote connections.

### Using grid to run tests

( using java as an example ) Now that the grid is in-place, we need to access the grid from our test cases. For the Selenium 1 RC nodes, you can continue to use the DefaultSelenium object and pass in the hub information:

```
Selenium selenium = new DefaultSelenium(“localhost”, 4444, “*firefox”, “http://www.google.com”);
```

For WebDriver nodes, you will need to use the **RemoteWebDriver** and the **DesiredCapabilities** object to define which browser, version and platform you wish to use. Create the target browser capabilities you want to run the tests against:

```
DesiredCapabilities capability = DesiredCapabilities.firefox();
```

Pass that into the RemoteWebDriver object:

```
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
```

The hub will then assign the test to a matching node.

A node matches if all the requested capabilities are met. To request specific capabilities on the grid, specify them before passing it into the WebDriver object.

```
capability.setBrowserName();
capability.setPlatform();
capability.setVersion()
capability.setCapability(,);
```

Example: A node registered with the setting:

```
 -browser  browserName=firefox,version=3.6,platform=LINUX
```

> will be a match for:

```
capability.setBrowserName(“firefox” ); 
capability.setPlatform(“LINUX”);  
capability.setVersion(“3.6”);
```

and would also be a match for

```
capability.setBrowserName(“firefox” ); 
capability.setVersion(“3.6”);
```

The capabilities that are not specified will be ignored. If you specify capabilities that do not exist on your grid (for example, your test specifies Firefox version 4.0, but have no Firefox 4 instance) then there will be no match and the test will fail to run.

## Configuring the nodes

The node can be configured in 2 different ways; one is by specifying command-line parameters, the other is by specifying a JSON file.

### Configuring the nodes by command line

By default, starting the node allows for concurrent use of 11 browsers…: 5 Firefox, 5 Chrome, 1 Internet Explorer. The maximum number of concurrent tests is set to 5 by default. To change this and other browser settings, you can pass in parameters to each -browser switch (each switch represents a node based on your parameters). If you use the -browser parameter, the default browsers will be ignored and only what you specify command line will be used.

```
-browser browserName=firefox,version=3.6,maxInstances=5,platform=LINUX
```

This setting starts 5 Firefox 3.6 nodes on a Linux machine.

If your remote machine has multiple versions of Firefox you’d like to use, you can map the location of each binary to a particular version on the same machine:

```
-browser browserName=firefox,version=3.6,firefox_binary=/home/myhomedir/firefox36/firefox,maxInstances=3,platform=LINUX -browser browserName=firefox,version=4,firefox_binary=/home/myhomedir/firefox4/firefox,maxInstances=4,platform=LINUX
```

Tip: If you need to provide a space somewhere in your browser parameters, then surround the parameters with quotation marks:

```
-browser “browserName=firefox,version=3.6,firefox_binary=c:\Program Files\firefox ,maxInstances=3, platform=WINDOWS”
```

### Optional parameters

* `-port 4444` (4444 is default)
* `-host <IP | hostname>` specify the hostname or IP. usually not needed and determined automatically. For exotic network configuration, network with VPN, specifying the host might be necessary.
* `-timeout 30` (300 is default) The timeout in seconds before the hub automatically releases a node that hasn’t received any requests for more than the specified number of seconds. After this time, the node will be released for another test in the queue. This helps to clear client crashes without manual intervention. To remove the timeout completely, specify -timeout 0 and the hub will never release the node.

> Note: This is NOT the WebDriver timeout for all ”wait for WebElement” type of commands.

> java -jar selenium-server-standalone.jar -role node -nodeConfig nodeconfig.json

A sample nodeconfig file for server version 3.x.x (>= beta4) can be seen at <https://github.com/SeleniumHQ/selenium/blob/selenium-3.141.59/java/server/src/org/openqa/grid/common/defaults/DefaultNodeWebDriver.json>

A sample nodeconfig file for server version 2.x.x can be seen at <https://github.com/SeleniumHQ/selenium/blob/selenium-2.53.0/java/server/src/org/openqa/grid/common/defaults/DefaultNode.json>

Note: the `configuration { ... }` object in version 2.x.x has been flattened in version 3.x.x (>= beta4)

### Configuring the hub by JSON

> java -jar selenium-server-standalone.jar -role hub -hubConfig hubconfig.json

A sample hubconfig.json file can be seen at <https://github.com/SeleniumHQ/selenium/blob/selenium-3.141.59/java/server/src/org/openqa/grid/common/defaults/DefaultHub.json>

## Hub diagnostic messages

Upon detecting anomalous usage patterns, the hub can give the following message:

```
Client requested session XYZ that was terminated due to REASON
```

| **Reason**                   | **Cause/fix**                                                                                                                                                                   |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| TIMEOUT                      | The session timed out because the client did not access it within the timeout. If the client has been somehow suspended, this may happen when it wakes up                       |
| BROWSER\_TIMEOUT             | The node timed out the browser because it was hanging for too long (parameter browserTimeout)                                                                                   |
| ORPHAN                       | A client waiting in queue has given up once it was offered a new session                                                                                                        |
| CLIENT\_STOPPED\_SESSION     | The session was stopped using an ordinary call to stop/quit on the client. Why are you using it again??                                                                         |
| CLIENT\_GONE                 | The client process (*your* code) appears to have died or otherwise not responded to our requests, intermittent network issues may also cause                                    |
| FORWARDING\_TO\_NODE\_FAILED | The hub was unable to forward to the node. Out of memory errors/node stability issues or network problems                                                                       |
| CREATIONFAILED               | The node failed to create the browser. This can typically happen when there are environmental/configuration problems on the node. Try using the node directly to track problem. |
| PROXY\_REREGISTRATION        | The session has been discarded because the node has re-registered on the grid (in mid-test)                                                                                     |

```
	[[DesiredCapabilities]] capability = DesiredCapabilities.internetExplorer();
	capability.setVersion("8");
	capability.setPlatform(Platform.XP);
	WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
```

The request for a new session with specified DesiredCapability is sent to the Grid Hub, which will look through all of the registered nodes to see if any of them match the specification given by the test. If no node matches the specification, a CapabilityNotPresentOnTheGridException will be returned.

It is a common misconception that the PLATFORM determines the ability to choose the Operating System on which the new session will be created. In this situation, platform and operating system are not the same, thus specifying the platform to “Windows 2003 Server” will not allow you to choose between a Windows XP, Vista, and 2003 server. This misconception can be born from platforms such as Mac OSX and Linux, where the name of the platform matches the name of the Operating System.

In case of Selenium Grid, platform refers to the underlying interactions between the Driver Atoms and the web browser. Mac OSX and Linux based Operating Systems (Centos, Ubuntu, Debian, etc..) have a relatively stable communication with the web browsers such as Firefox and Chrome. Thus the platform names are simple to understand, as seen in the example bellow:

```
   capability.setPlatform(Platform.MAC);   //Set platform to OSX
   capability.setPlatform(Platform.LINUX); // Set platform to Linux based systems
```

The prior to release of Vista, Windows based Operating Systems only had one platform, shown here:

```
	capability.setPlatform(Platform.WINDOWS); //Set platform to Windows
```

However, with the introduction of UAC in Windows Vista, there were major changes done to the underlying interactions between WebDriver and Internet Explorer. To work around the UAC constrains a new platform was added to nodes with Windows based Operating systems:

```
	capability.setPlatform(Platform.VISTA); //Set platform to VISTA
```

With the release of Windows 8, another major overhaul happened in how the WebDriver communicates with Internet Explorer, thus a new platform was added for Windows 8 based nodes:

```
	capability.setPlatform(Platform.WIN8); //Set platform to Windows 8
```

Similar story happened with introduction of Windows 8.1, in this example the platform is set to Windows 8.1:

```
	capability.setPlatform(Platform.WIN8_1); //Set platform to Windows 8.1
```

```
  	capability.setPlatform(Platform.VISTA); //Will return a node with Windows Vista or 2008 Server or Windows 7 Operating System.
  	capability.setPlatform(Platform.XP);   //Will return a node with Windows XP or 2003 Server or Windows 2000 Professional Operating System.   
  	capability.setPlatform(Platform.WINDOWS); //Will return a node with ANY Windows Operating System
```

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/interactions/print_page/
----

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L14-L17)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L12-L19)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L12-L14)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L23-L26)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L22-L29)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L18-L26)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L32-L35)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L32-L38)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L24-L27)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#41-L48)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L51-L57)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L30-L35)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L53-L57)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L61-L68)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L42-L45)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L63-L66)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L41-L48)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L49-L51)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L72-L75)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L71-L78)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L55-L57)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java#L27-L31)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.Pdf;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.PrintsPage;
import dev.selenium.BaseTest;

public class PrintsPageTest extends BaseTest{

    @BeforeEach
    public void setup() {
        ChromeOptions options = getDefaultChromeOptions();
        options.setCapability("webSocketUrl", true);
        driver = new ChromeDriver(options);
    }

    @Test
    public void PrintWithPrintsPageTest() 
    {
        driver.get("https://www.selenium.dev/");
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }

    @Test
    public void PrintWithBrowsingContextTest() 
    {
        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);
        Assertions.assertTrue(printPage.length() > 0);
    }
}
```

**BrowsingContext()**

```java
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        PrintOptions printOptions = new PrintOptions();
        String printPage = browsingContext.print(printOptions);
        Assertions.assertTrue(printPage.length() > 0);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java#L37-L41)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.Pdf;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.PrintsPage;
import dev.selenium.BaseTest;

public class PrintsPageTest extends BaseTest{

    @BeforeEach
    public void setup() {
        ChromeOptions options = getDefaultChromeOptions();
        options.setCapability("webSocketUrl", true);
        driver = new ChromeDriver(options);
    }

    @Test
    public void PrintWithPrintsPageTest() 
    {
        driver.get("https://www.selenium.dev/");
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }

    @Test
    public void PrintWithBrowsingContextTest() 
    {
        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);
        Assertions.assertTrue(printPage.length() > 0);
    }
}
```

```cs
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L81-L88)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

**print\_page()**

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    pdf = driver.print_page(print_options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_prints_page.py#L12-L14)

##### /examples/python/tests/interactions/test\_prints\_page.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_prints_page(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    pdf = driver.print_page(print_options)
    assert len(pdf) > 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/bidi/network/
----

# WebDriver BiDi Network Features

These features are related to networking, and are made available via a “network” namespace.

The implementation of these features is being tracked here: [#13993](https://github.com/SeleniumHQ/selenium/issues/13993)

Remember that to use WebDriver BiDi, you must enable it in Options. For more details, see [Enabling BiDi](https://www.selenium.dev/zh-cn/documentation/webdriver/bidi/)

```rb
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds an auth handler', skip: 'Do not execute BiDi test' do
    driver.network.add_authentication_handler('test', 'test')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/network_spec.rb#L7-L11)

##### /examples/ruby/spec/bidi/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network', exclusive: {bidi: true, reason: 'only executed when bidi is enabled'},
                          only: {browser: %i[chrome edge firefox]} do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds an auth handler', skip: 'Do not execute BiDi test' do
    driver.network.add_authentication_handler('test', 'test')
    driver.navigate.to url_for('basicAuth')
    expect(driver.find_element(tag_name: 'h1').text).to eq('authorized')
  end
end
```

最后修改 August 18, 2025: [Fix path for codeblock (cb0bfc20fdf)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/cb0bfc20fdf56dfe6b16733e84cee540f2ffe04e)

----
url: https://www.selenium.dev/zh-cn/_print/documentation/about/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/about/).

# 关于这个文档

* 1: [版权和归属](#pg-5fbfa5313614573b96cae1567eeabb51)
* 2: [为 Selenium 文档做贡献](#pg-c876976cf75230412179ca26d6de8110)
* 3: [Style guide for Selenium documentation](#pg-b7337a7fcc25ba4adaf8a0aba18abd48)

这些文档，就像代码本身一样，100% 由 Selenium 社区中的志愿者维护。 许多人自成立以来一直在使用它，但更多人只是在短时间内使用它，并且已经花时间帮助改善新用户的入门体验。

如果文档有问题，我们想知道！ 沟通问题的最佳方式是访问 [https://github.com/seleniumhq/seleniumhq.github.io/issues](//github.com/seleniumhq/seleniumhq.github.io/issues) 并搜索问题是否已经提交。 如果没有，请随意打开一个！

社区的许多成员经常光顾 [Libera.chat](https://libera.chat/) 的 *#selenium* Libera 频道。 请随时来访并提出问题，如果您得到了您认为在这些文档中可能有用的帮助，请务必添加您的贡献！ 我们可以更新这些文档，但当我们从普通提交者之外获得贡献时，对每个人来说都容易得多。

# 1 - 版权和归属

| 软件                                  | 版本       | 许可                                                          |
| ----------------------------------- | -------- | ----------------------------------------------------------- |
| [Hugo](/zh-cn/)                     | v0.110.0 | [Apache 2.0](//gohugo.io/about/license/)                    |
| [Docsy](//github.com/google/docsy/) | —        | [Apache 2.0](//github.com/google/docsy/blob/master/LICENSE) |

## 许可

源自Selenium项目的所有代码和文档均基于Apache2.0的许可, 由 [Software Freedom Conservancy](/zh-cn/) 作为版权所有者.

为方便起见, 此处包含许可证, 您也可以在此查看 [Apache 基金会站点](//apache.org/licenses/LICENSE-2.0.html):

```markdown
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
```

# 2 - 为 Selenium 文档做贡献

有关改进Selenium文档和代码示例的信息

Selenium是一个大型软件项目, 其网站和文档是了解事情如何工作以及学习有效利用其潜力的关键.

该项目包含Selenium的网站和文档. 这是一项持续的工作(不针对任何特定版本), 用于提供有效使用Selenium、 如何参与以及如何为Selenium做出贡献的更新信息.

对网站和文档的贡献遵循以下部分中有关贡献的描述.

***

```
    {{< tab header="Ruby" >}}
    {{< gh-codeblock path="/examples/ruby/spec/browsers/chrome_spec.rb#L8-L9" >}}
    {{< /tab >}}
```

```shell
% git clone git@github.com:seleniumhq/seleniumhq.github.io.git
% cd seleniumhq.github.io
```

#### 依赖: Hugo

我们使用 [Hugo](https://gohugo.io/) 和 [Docsy theme](https://www.docsy.dev/) 用于构建和渲染本网站. 你需要Hugo“extended”扩展的Sass/SCSS版本用于这个网站. 我们推荐使用Hugo 0.148.2 .

请参考来自Docsy的说明 [安装Hugo](https://www.docsy.dev/docs/getting-started/#install-hugo) .

### 步骤 2: 分支

创建一个功能分支并开始工作:

```shell
% git checkout -b my-feature-branch
```

我们实践基于HEAD的开发模式, 这意味着所有更改都直接应用在trunk之上.

### 步骤 3: 做出改变

本仓库包含站点和文档. 在开始进行更改之前, 请初始化子模块并安装所需的依赖项 (请参阅下面的命令). 要对网站进行更改, 请使用 `website_and_docs` 目录. 要查看更改的实时预览, 请在站点的根目录上运行 `hugo server` .

```shell
% git submodule update --init --recursive
% cd website_and_docs
% hugo server
```

请参阅 [样式指南](https://www.selenium.dev/zh-cn/documentation/about/style/) , 以了解更多关于我们约定的信息

### 步骤 4: 提交

首先确保git知道您的姓名和电子邮件地址:

```shell
% git config --global user.name 'Santa Claus'
% git config --global user.email 'santa@example.com'
```

**编写良好的提交信息很重要.** 提交信息应描述更改的内容, 原因以及已解决的参考问题(如果有). 撰写时应遵循以下规则:

1. 第一行应少于或等于50个字符, 并包含对该更改的简短说明.
2. 保持第二行空白.
3. 在所有72列处换行.
4. 包括 `Fixes #N`, 其中 *N* 是提交修复的问题编号(如果有).

一个好的提交信息可能看起来像这样:

```text
explain commit normatively in one line

Body of commit message is a few lines of text, explaining things
in more detail, possibly giving some background about the issue
being fixed, etc.

The body of the commit message can be several paragraphs, and
please do proper word-wrap and keep columns shorter than about
72 characters or so. That way `git log` will show things
nicely even when it is indented.

Fixes #141
```

第一行必须有意义, 因为这是人们在运行 `git shortlog` 或 `git log --oneline` 时看到的内容.

### 步骤 5: Rebase

使用 `git rebase` (并非 `git merge`) 同步实时的工作.

```shell
% git fetch origin
% git rebase origin/trunk
```

### 步骤 6: 测试

永远记住要[运行本地服务](https://gohugo.io/getting-started/usage/#livereload), 这样做可以确保您的更改没有破坏任何事情.

### 步骤 7: Push

```shell
% git push origin my-feature-branch
```

访问 <https://github.com/yourusername/seleniumhq.github.io.git> 并点击 *Pull Request* 以及填写表格. **请明确您已经签署了CLA** (详见步骤 7).

Pull requests通常会在几天内进行审核. 如果有评论要解决, 请在新提交(最好是[修正](http://git-scm.com/docs/git-commit))中应用您的更改, 然后推push到同一分支.

### 步骤 8: 集成

代码审查完成后, 提交者将获取您的PR并将其集成到项目的trunk分支中. 因为我们希望在trunk分支上保持线性历史记录, 所以我们通常会squash并rebase您的分支历史记录.

## 沟通

有关如何与项目贡献者和整个社区进行沟通的所有详细信息, 请访问以下网址 <https://selenium.dev/support>

# 3 - Style guide for Selenium documentation

Conventions for contributions to the Selenium documentation and code examples

Read our [contributing documentation](https://www.selenium.dev/zh-cn/documentation/about/contributing/) for complete instructions on how to add content to this documentation.

## Alerts

Alerts have been added to direct potential contributors to where specific content is missing.

```html
{{< alert-content />}}
```

or

```html
{{< alert-content >}}
Additional information about what specific content is needed
{{< /alert-content >}}
```

```java
WebDriver driver = new ChromeDriver();
```

```python
driver = webdriver.Chrome()
```

```csharp
var driver = new ChromeDriver();
```

```ruby
driver = Selenium::WebDriver.for :chrome
```

```javascript
let driver = await new Builder().forBrowser('chrome').build();
```

```kotlin
val driver = ChromeDriver()
```

To generate the above tabs, this is what you need to write. Note that the `tabpane` includes `langEqualsHeader=true`. This auto-formats the code in each tab to match the header name, and ensures that all tabs on the page with a language are set to the same thing.

```
{{< tabpane langEqualsHeader=true >}}
  {{< tab header="Java" >}}
    WebDriver driver = new ChromeDriver();
  {{< /tab >}}
  {{< tab header="Python" >}}
    driver = webdriver.Chrome()
  {{< /tab >}}
  {{< tab header="CSharp" >}}
    var driver = new ChromeDriver();
  {{< /tab >}}
  {{< tab header="Ruby" >}}
    driver = Selenium::WebDriver.for :chrome
  {{< /tab >}}
  {{< tab header="JavaScript" >}}
    let driver = await new Builder().forBrowser('chrome').build();
  {{< /tab >}}
  {{< tab header="Kotlin" >}}
    val driver = ChromeDriver()
  {{< /tab >}}
{{< /tabpane >}}
```

#### Reference GitHub Examples

To ensure that all code is kept up to date, our goal is to write the code in the repo where it can be executed when Selenium versions are updated to ensure that everything is correct.

All code examples to be in our [example directories](https://github.com/SeleniumHQ/seleniumhq.github.io/tree/dev/examples).

This code can be automatically displayed in the documentation using the `gh-codeblock` shortcode. The shortcode automatically generates its own html, so we do not want it to auto-format with the language header. If all tabs are using this shortcode, set `text=true` in the `tabpane` and remove `langEqualsHeader=true`. If only some tabs are using this shortcode, keep `langEqualsHeader=true` in the `tabpane` and add `text=true` to the `tab`. Note that the `gh-codeblock` line can not be indented at all.

One great thing about using `gh-codeblock` is that it adds a link to the full example. This means you don’t have to include any additional context code, just the line(s) that are needed, and the user can navigate to the repo to see how to use it.

A basic comparison of code looks like:

```
{{< tabpane text=true >}}
{{< tab header="Java" >}}
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-L27" >}}
{{< /tab >}}
{{< tab header="Python" >}}
{{< gh-codeblock path="/examples/python/tests/getting_started/first_script.py#L18-L19" >}}
{{< /tab >}}
{{< tab header="CSharp" >}}
{{< gh-codeblock path="/examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-L26" >}}
{{< /tab >}}
{{< tab header="Ruby" >}}
{{< gh-codeblock path="/examples/ruby/spec/getting_started/first_script.rb#L17-L18" >}}
{{< /tab >}}
{{< tab header="JavaScript" >}}
{{< gh-codeblock path="/examples/javascript/test/getting_started/firstScript.spec.js#L22-L23" >}}
{{< /tab >}}
{{< tab header="Kotlin" >}}
{{< gh-codeblock path="/examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-L32" >}}
{{< /tab >}}
{{< /tabpane >}}
```

```java
        WebElement message = driver.findElement(By.id("message"));
        message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-L27)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
message = driver.find_element(by=By.ID, value="message")
text = message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L18-L19)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-L26)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
message = driver.find_element(id: 'message')
message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L17-L18)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L22-L23)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val message = driver.findElement(By.id("message"))
        val value = message.getText()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-L32)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

### Using Markdown in a Tab

If you want your example to include something other than code (default) or html (from `gh-codeblock`), you need to first set `text=true`, then change the Hugo syntax for the `tab`to use `%` instead of `<` and `>` with curly braces:

```
{{< tabpane text=true >}}
{{% tab header="Java" %}}
1. Start the driver
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12" >}}
2. Navigate to a page
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14" >}}
3. Quit the driver
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29" >}}
{{% /tab %}}
< ... >
{{< /tabpane >}}
```

This produces:

*

1. Start the driver

   ```java
           WebDriver driver = new ChromeDriver();
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

2. Navigate to a page

   ```java
           driver.get("https://www.selenium.dev/selenium/web/web-form.html");
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

3. Quit the driver

   ```java
           driver.quit();
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

----
url: https://www.selenium.dev/documentation/legacy/selenium_2/emulation/
----

# Backing Selenium with WebDriver

The Java and .NET versions of Selenium 2 provided implementations of the original Selenium API

(Previously located: <https://github.com/SeleniumHQ/selenium/wiki/Selenium-Emulation>)

## Backing Selenium with WebDriver

The Java and .NET versions of WebDriver provide implementations of the existing Selenium API. In Java, it is used like so:

```
// You may use any WebDriver implementation. Firefox is used here as an example
WebDriver driver = new FirefoxDriver();

// A "base url", used by selenium to resolve relative URLs
String baseUrl = "http://www.google.com";

// Create the Selenium implementation
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);

// Perform actions with selenium
selenium.open("http://www.google.com");
selenium.type("name=q", "cheese");
selenium.click("name=btnG");

// And get the underlying WebDriver implementation back. This will refer to the
// same WebDriver instance as the "driver" variable above.
WebDriver driverInstance = ((WebDriverBackedSelenium) selenium).getUnderlyingWebDriver();
```

```
driver = RemoteWebDriver(desired_capabilities = DesiredCapabilities.FIREFOX)
selenium = DefaultSelenium('localhost', '4444', '*webdriver', 'http://www.google.com')
selenium.start(driver = driver)
```

Provided you keep a reference to the original WebDriver and Selenium objects you created, you can use even the two APIs interchangeably. The magic is the “`*webdriver`” browser name passed to the Selenium instance, and that you pass the WebDriver instance when calling `start()`.

In languages where DefaultSelenium doesn’t have `start(driver)`, you can connect the WebDriver and Selenium objects together yourself, by supplying the WebDriver session ID to the Selenium object.

For example, in C#:

```

RemoteWebDriver driver = new RemoteWebDriver(DesiredCapabilities.Firefox());
string sessionId = (string) driver.Capabilities.GetCapability("webdriver.remote.sessionid");
DefaultSelenium selenium = new DefaultSelenium("localhost", 4444, "*webdriver", "http://www.google.com");
selenium.Start("webdriver.remote.sessionid=" + sessionId);
```

## Backing WebDriver with Selenium

WebDriver doesn’t support as many browsers as Selenium does, so in order to provide that support while still using the webdriver API, you can make use of the `SeleneseCommandExecutor` It is done like this:

```
Capabilities capabilities = new DesiredCapabilities()
capabilities.setBrowserName("safari");
CommandExecutor executor = new SeleneseCommandExecutor("http:localhost:4444/", "http://www.google.com/", capabilities);
WebDriver driver = new RemoteWebDriver(executor, capabilities);
```

There are currently some major limitations with this approach, notably that `findElements` doesn’t work as expected. Also, because we’re using Selenium Core for the heavy lifting of driving the browser, you are limited by the Javascript sandbox.

----
url: https://www.selenium.dev/zh-cn/documentation/ie_driver_server/
----

# IE驱动服务器

Internet Explorer驱动是一种实现WebDriver规范的单机服务器.

| 开关                   | 释义                                                                      |
| -------------------- | ----------------------------------------------------------------------- |
| –port=`<端口号>`        | 指定IE驱动程序的HTTP服务器将在其上侦听来自语言绑定的命令的端口. 默认值为5555.                           |
| –host=`<主机IP地址>`     | 指定主机适配器的IP地址, IE驱动程序的HTTP服务器将在其上侦听来自语言绑定的命令. 默认值为127.0.0.1.             |
| –log-level=`<日志级别>`  | 指定日志消息的输出级别. 有效值包括 FATAL, ERROR, WARN, INFO, DEBUG, 以及 TRACE. 默认为FATAL. |
| –log-file=`<日志文件>`   | 指定日志文件的完整路径和文件名. 默认为标准输出.                                               |
| –extract-path=`<路径>` | 指定用于提取服务器使用的支持文件的目录的完整路径. 如果未指定, 则默认为临时目录.                              |
| –silent              | 在服务器启动时抑制诊断输出.                                                          |

## 重要的系统属性

以下系统属性用于 `InternetExplorerDriver` (在Java代码中使用 `System.getProperty()` 读取并使用`System.setProperty()` 进行设置, 或者 在命令行标识 “`-DpropertyName=value`”) :

| **属性**                            | **含义**                                                                  |
| --------------------------------- | ----------------------------------------------------------------------- |
| `webdriver.ie.driver`             | IE驱动程序二进制文件的位置.                                                         |
| `webdriver.ie.driver.host`        | 指定IE驱动程序将在其上侦听的主机适配器的IP地址.                                              |
| `webdriver.ie.driver.loglevel`    | 指定日志消息的输出级别. 有效值包括 FATAL, ERROR, WARN, INFO, DEBUG, 以及 TRACE. 默认为FATAL. |
| `webdriver.ie.driver.logfile`     | 指定日志文件的完整路径和文件名.                                                        |
| `webdriver.ie.driver.silent`      | 在IE驱动程序启动时抑制诊断输出.                                                       |
| `webdriver.ie.driver.extractpath` | 指定用于提取服务器使用的支持文件的目录的完整路径. 如果未指定, 则默认为临时目录.                              |


***

##### [Internet Explorer Driver Internals](/zh-cn/documentation/ie_driver_server/internals/)

More detailed information on the IE Driver.

最后修改 January 23, 2022: [Updating IE info links in all docs\[deploy site\] (a5c7b8a0d9e)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/a5c7b8a0d9e1a6087da8f68bea1ce8f972b7dd92)

----
url: https://www.selenium.dev/documentation/webdriver/elements/
----

# Web elements

Identifying and working with element objects in the DOM.

The majority of most people’s Selenium code involves working with web elements.

***

##### [Locator strategies](/documentation/webdriver/elements/locators/)

Ways to identify one or more specific elements in the DOM.

##### [Finding web elements](/documentation/webdriver/elements/finders/)

Locating the elements based on the provided locator values.

##### [Interacting with web elements](/documentation/webdriver/elements/interactions/)

A high-level instruction set for manipulating form controls.

##### [Information about web elements](/documentation/webdriver/elements/information/)

What you can learn about an element.

##### [File Upload](/documentation/webdriver/elements/file_upload/)

Last modified December 13, 2021: [organize element documentation (#876) \[deploy site\] (759fdeec9d3)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/759fdeec9d32221e669ea5dd1fcac9d726686b0c)

----
url: https://www.selenium.dev/documentation/legacy/developers/roadmap/
----

# Snapshot of Roadmaps for Selenium Releases

The list of plans and things to accomplish before a release

## Preparation for Selenium 2

Date unknown This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/RoadMap/eef12bca5fdc865449ad2d1735ee08e40ba0bd2b)

The following issues need to be resolved before the final release:

| **Issue**                                                    | **Summary**                                             | **HtmlUnitDriver Progress** | **FirefoxDriver Progress** | **InternetExplorerDriver Progress** | **ChromeDriver Progress** |
| ------------------------------------------------------------ | ------------------------------------------------------- | --------------------------- | -------------------------- | ----------------------------------- | ------------------------- |
| [27](http://code.google.com/p/webdriver/issues/detail?id=27) | Handle alerts in Javascript-enabled browsers            | n/a                         | Started                    | Started                             | Not Started               |
| [32](http://code.google.com/p/webdriver/issues/detail?id=32) | User guide                                              | Started                     |                            |                                     |                           |
| [34](http://code.google.com/p/webdriver/issues/detail?id=34) | Support HTTP Basic and Digest Authentication            | Not Started                 |                            |                                     |                           |
| [35](http://code.google.com/p/webdriver/issues/detail?id=35) | [Selenium](http://www.openqa.org/selenium-rc) emulation | Done for Java and C#        |                            |                                     |                           |
| [36](http://code.google.com/p/webdriver/issues/detail?id=36) | Support for drag and drop behaviour                     | n/a                         | Done                       | Done                                | Started                   |
| none                                                         | Example tests                                           | Not Started                 |                            |                                     |                           |

A final release will be made once these are implemented in Firefox, IE and at least one webkit-based browser.

### The Future

The following are also planned:

* **JsonWireProtocol** — The formalisation of the current RemoteWebDriver wire protocol in [JSON](http://www.json.org/).

## Preparation for Selenium 3

As of Mar 16, 2015 This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/Shipping-Selenium-3)

### User Visible Changes

* Migrate all drivers to use the status strings rather than status codes in responses
* Update client bindings to also cope with that
* Write a new runner for the html-suite tests
* Segment the build to remove RC

### Clean up

* Using WebDriver after quit() should be an IllegalStateException
* Actions to have a single end point
* Capabilities to be the same as the spec
* Multiple calls to WebDriver.quit() should still be safe.
* Clean up WebDriver constructors, pulling heavy initialization logic into a Builder class
* Migrate to Netty or webbit server
* Delete unnecessary cruft
* Land a cleaner end point for the rc emulation

## Preparation for Selenium 4

This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/RoadMap) As of April 12, 2017

* Finish the [W3C WebDriver Spec](https://w3c.github.io/webdriver/webdriver-spec.html)
* Implement the local end requirements for the spec in selenium
* Implement protocol conversion in the standalone server
* Ship 4.0
*

Last modified January 11, 2022: [combine legacy roadmap documentation into one (884dae2ea0d)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/884dae2ea0d31928e343a789bc353350fac9c70e)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/bidi/w3c/log/
----

# BiDirectional API (W3C compliant)

```java
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L33-L39)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/logInspector.spec.js#L23-37)

##### /examples/javascript/test/bidirectional/logInspector.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const LogInspector = require('selenium-webdriver/bidi/logInspector');
const {Builder} = require("selenium-webdriver");


describe('Log Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test listen to console log', async function () {
    let logEntry = null
    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)

    await inspector.close()
  })

  it('test listen to javascript error log', async function () {
    let logEntry = null
    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')

    await inspector.close()
  })

  it('test retrieve stack trace for a log', async function () {
    let logEntry = null
    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()

    const stackTrace = logEntry.stackTrace
    assert.notEqual(stackTrace, null)
    assert.equal(stackTrace.callFrames.length, 3)

    await inspector.close()
  })

  it('test listen to logs with multiple consumers', async function () {
    let logEntry1 = null
    let logEntry2 = null
    const inspector = await LogInspector(driver)
    await inspector.onJavascriptException(function (log) {
      logEntry1 = log
    })
    await inspector.onJavascriptException(function (log) {
      logEntry2 = log
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    await driver.findElement({id: 'jsException'}).click()

    assert.equal(logEntry1.text, 'Error: Not working')
    assert.equal(logEntry1.type, 'javascript')
    assert.equal(logEntry1.level, 'error')

    assert.equal(logEntry2.text, 'Error: Not working')
    assert.equal(logEntry2.type, 'javascript')
    assert.equal(logEntry2.level, 'error')

    await inspector.close()
  })
})
```

```java
            logInspector.onJavaScriptException(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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L73-L78)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/logInspector.spec.js#L44-54)

##### /examples/javascript/test/bidirectional/logInspector.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const LogInspector = require('selenium-webdriver/bidi/logInspector');
const {Builder} = require("selenium-webdriver");


describe('Log Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test listen to console log', async function () {
    let logEntry = null
    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)

    await inspector.close()
  })

  it('test listen to javascript error log', async function () {
    let logEntry = null
    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')

    await inspector.close()
  })

  it('test retrieve stack trace for a log', async function () {
    let logEntry = null
    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()

    const stackTrace = logEntry.stackTrace
    assert.notEqual(stackTrace, null)
    assert.equal(stackTrace.callFrames.length, 3)

    await inspector.close()
  })

  it('test listen to logs with multiple consumers', async function () {
    let logEntry1 = null
    let logEntry2 = null
    const inspector = await LogInspector(driver)
    await inspector.onJavascriptException(function (log) {
      logEntry1 = log
    })
    await inspector.onJavascriptException(function (log) {
      logEntry2 = log
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    await driver.findElement({id: 'jsException'}).click()

    assert.equal(logEntry1.text, 'Error: Not working')
    assert.equal(logEntry1.type, 'javascript')
    assert.equal(logEntry1.level, 'error')

    assert.equal(logEntry2.text, 'Error: Not working')
    assert.equal(logEntry2.type, 'javascript')
    assert.equal(logEntry2.level, 'error')

    await inspector.close()
  })
})
```

```java
            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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L55-L60)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

Última modificação December 16, 2024: [\[java\] Remove a wrong code example and update code lines (#2104) (6b3cccc0e32)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/6b3cccc0e32b97a2a88350983e4b7c73836e0733)

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/testing_types/
----

# 测试类型

### 验收测试

进行这种类型的测试以确定功能或系统是否满足客户的期望和要求. 这种测试通常涉及客户的合作或反馈, 是一种验证活动, 可以用于回答以下问题：

> 我们是否在制造 ***正确的*** 产品?

对于Web应用程序, 可以通过模拟用户期望的行为 直接使用Selenium来完成此测试的自动化. 可以通过记录/回放, 或通过本文档中介绍的各种支持的语言来完成此类模拟. 注意：有些人可能还会提到, 验收测试是 ***功能测试*** 的子类型.

### 功能测试

进行这种类型的测试是为了确定功能或系统是否正常运行而没有问题. 它会在不同级别检查系统, 以确保涵盖所有方案并且系统能够执行预期的 *工作* . 这是一个验证活动, 它回答了以下问题：

> 我们是否在 ***正确地*** 制造产品？

> For example, ***Testing that the site can handle numerous orders/users at once.***

#### 压力测试

进行压力测试, 以验证应用程序在压力 (或高于最大支持负载) 下的运行状况.

> For example, ***Testing that your ecommerce site can handle Black Friday***

> For example, ***Testing that your new search bar doesn’t break the other buttons on the menu***

最后修改 March 9, 2025: [Added more examples to testing type descriptions (#1970)\[deploy site\] (9f7a22b43fc)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/9f7a22b43fcd2d4158aa007d622c9a6d7bf4ca6b)

----
url: https://www.selenium.dev/ja/documentation/legacy/selenium_2/remote_server/
----

# リモートWebDriverサーバー

サーバーは、テストするブラウザーがインストールされたマシンで常に実行されます。 サーバーは、コマンドラインから、またはコード設定を通じて使用できます。

## コマンドラインからサーバーを起動する

一旦、`selenium-server-standalone-{VERSION}.jar`をダウンロードしたら、テストしたいブラウザーのあるコンピューターに配置します。 次に、jarを含むディレクトリから、次のコマンドを実行します。

```shell
java -jar selenium-server-standalone-{VERSION}.jar
```

## サーバーを実行するにあたって考慮すること

呼び出し元は、`Selenium#stop()`または`WebDriver#quit`を呼び出して、各セッションを適切に終了すべきです。

selenium-serverは、進行中の各セッションのメモリ内ログを保持します。 これらのログは、`Selenium#stop()`または`WebDriver#quit`が呼び出されるとクリアされます。 これらのセッションの終了を忘れると、サーバーでメモリリークが発生する可能性があります。 非常に長時間実行されるセッションを維持する場合は、時々停止または終了する必要があります（または-Xmx jvmオプションでメモリを増やします）。

## タイムアウト (version 2.21以降)

サーバーには2つの異なるタイムアウトがあり、次のように設定できます。

```shell
java -jar selenium-server-standalone-{VERSION}.jar -timeout=20 -browserTimeout=60
```

```java
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.security.SslSocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;

import javax.servlet.Servlet;
import java.io.File;

import org.openqa.selenium.remote.server.DriverServlet;

public class AppServer {
  private Server server = new Server();

  public AppServer() throws Exception {
    WebAppContext context = new WebAppContext();
    context.setContextPath("");
    context.setWar(new File("."));
    server.addHandler(context);

    context.addServlet(DriverServlet.class, "/wd/*");

    SelectChannelConnector connector = new SelectChannelConnector();
    connector.setPort(3001);
    server.addConnector(connector);

    server.start();
  }
}
```

----
url: https://www.selenium.dev/ja/documentation/grid/architecture/
----

# Grid アーキテクチャ

|            | イベントバス | ディストリビューター | ノード | ルーター | セッションマップ | 新規セッションキュー |
| ---------- | ------ | ---------- | --- | ---- | -------- | ---------- |
| イベントバス     | X      |            |     |      |          |            |
| ディストリビューター | ✅      | X          | ✅   |      |          | ✅          |
| ノード        | ✅      |            | X   |      |          |            |
| ルーター       |        |            | ✅   | X    | ✅        |            |
| セッションマップ   |        |            |     |      | X        |            |
| 新規セッションキュー | ✅      |            |     |      |          | X          |

| 名前                 | 型       | 概要                                                                                                                |
| ------------------ | ------- | ----------------------------------------------------------------------------------------------------------------- |
| availability       | string  | `up`, `draining`, `down` のいずれかの文字列です。重要なのは `draining` で、これはノードに新しいセッションを送らないことを示し、最後のセッションが終了するとノードは終了、または再起動します。 |
| externalUrl        | string  | Grid 内の他のコンポーネントが接続するための URI。                                                                                     |
| lastSessionCreated | integer | このノードで最後にセッションが作成された時間のエポックタイムスタンプです。ディストリビューターは、他の条件がすべて同じであれば、最も長くアイドルであったノードに新しいセッションを送信しようとします。               |
| maxSessionCount    | integer | セッション数は利用可能なスロット数をカウントすることで推測できますが、この値はノードが「満杯」とみなされるまでに、ノード上で同時に実行されるセッションの最大数を決定するために使用されます。                    |
| nodeId             | string  | ノード ID を識別する UUID です。                                                                                             |
| osInfo             | object  | `arch`, `name`, `version` フィールドを持つオブジェクトです。Grid UI と GraphQL クエリーで利用されます。                                         |
| slots              | array   | Slot オブジェクト(以下を参照)の配列。                                                                                            |
| version            | string  | ノードのバージョン(Selenium では、これは Selenium のバージョンと同じです)。                                                                  |

すべてのフィールドの値を設定することが推奨されます。

### Slot オブジェクト

Slot オブジェクトは 1 ノードでの 1 スロットを表します。 1 スロットにつき 1 セッションを実行することができます。 1 つのノードが同時に実行できる数よりも多くのスロットを持つことができます。 例えばあるノードが 10 セッションまで同時に実行でき、 それらのセッションは Chrome, Edge, Firefox のどの組み合わせでも良い時、 ノードは ‘max session count’ を 10 として、 10 の Chrome スロット、10 の Edge スロット、10 の Firefox スロットを持ちます。

| 名前          | 型      | 概要                                                                                                                                 |
| ----------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| id          | string | スロット ID。                                                                                                                           |
| lastStarted | string | スロットが最後にセッションを開始した時間。ISO-8601 フォーマット。                                                                                              |
| stereotype  | object | このスロットがマッチする最小限の[capabilities](https://w3c.github.io/webdriver/#dfn-merging-capabilities) のセット。 最小の例: `{"browserName": "firefox"}` |
| session     | object | Session オブジェクト(以下を参照)。                                                                                                             |

### Session オブジェクト

スロットで実行中のセッションを表します。

| 名前           | 型      | 概要                                                                                                                                               |
| ------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| capabilities | object | セッションが持つ実際の capabilities。 The actual capabilities provided by the session. [新規セッション](https://w3c.github.io/webdriver/#new-session)コマンドの戻り値と同じです。 |
| startTime    | string | セッションが開始した時間。ISO-8601 フォーマット。                                                                                                                    |
| stereotype   | object | このスロットがマッチする最小限の[capabilities](https://w3c.github.io/webdriver/#dfn-merging-capabilities) のセット。 最小の例: `{"browserName": "firefox"}`               |
| uri          | string | ノードがセッションに接続するための URI。                                                                                                                           |

----
url: https://www.selenium.dev/zh-cn/_print/documentation/webdriver/elements/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/webdriver/elements/).

# 网络元素

在DOM中识别和使用元素对象.

* 1: [查询网络元素](#pg-63202971179128b89518703d2383a15b)
* 2: [Web元素交互](#pg-1b19fbce1869b2e4d9b4ff5f03c074b4)
* 3: [定位策略](#pg-01199522e2d2ea9360d11a43bff79c51)
* 4: [关于网络元素的信息](#pg-ad956e592b6d0efc90f34a1a18c0c8f3)
* 5: [文件上传](#pg-ba14c44cac094411e1b241c56878e0d6)

大多数人的Selenium代码都涉及使用web元素.

# 1 - 查询网络元素

根据提供的定位值定位元素.

使用 Selenium 最基本的特点之一是获取可用于操作的元素引用。 Selenium 提供了许多内置的 [定位策略](https://www.selenium.dev/zh-cn/documentation/webdriver/elements/locators/)，用于唯一标识元素。 在更复杂的场景中，可以用多种方式使用这些定位器。为了本篇文档的目的， 我们来考虑下面的 HTML 片段：

```html
<ol id="vegetables">
 <li class="potatoes">…
 <li class="onions">…
 <li class="tomatoes"><span>Tomato is a Vegetable</span>…
</ol>
<ul id="fruits">
  <li class="bananas">…
  <li class="apples">…
  <li class="tomatoes"><span>Tomato is a Fruit</span>…
</ul>
```

```java
WebElement vegetable = driver.findElement(By.className("tomatoes"));
  
```

```python
vegetable = driver.find_element(By.CLASS_NAME, "tomatoes")
  
```

```csharp
var vegetable = driver.FindElement(By.ClassName("tomatoes"));
  
```

```rb
      driver.find_element(class: 'tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L10)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const vegetable = await driver.findElement(By.className('tomatoes'));
  
```

```kotlin
val vegetable: WebElement = driver.findElement(By.className("tomatoes"))
  
```

```java
WebElement fruits = driver.findElement(By.id("fruits"));
WebElement fruit = fruits.findElement(By.className("tomatoes"));
  
```

```python
fruits = driver.find_element(By.ID, "fruits")
fruit = fruits.find_element(By.CLASS_NAME,"tomatoes")
  
```

```csharp
IWebElement fruits = driver.FindElement(By.Id("fruits"));
IWebElement fruit = fruits.FindElement(By.ClassName("tomatoes"));
  
```

```rb
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L14-L15)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const fruits = await driver.findElement(By.id('fruits'));
const fruit = fruits.findElement(By.className('tomatoes'));
  
```

```kotlin
val fruits = driver.findElement(By.id("fruits"))
val fruit = fruits.findElement(By.className("tomatoes"))
  
```

```java
WebElement shadowHost = driver.findElement(By.cssSelector("#shadow_host"));
SearchContext shadowRoot = shadowHost.getShadowRoot();
WebElement shadowContent = shadowRoot.findElement(By.cssSelector("#shadow_content"));
```

```python
shadow_host = driver.find_element(By.CSS_SELECTOR, '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(By.CSS_SELECTOR, '#shadow_content')
```

```csharp
var shadowHost = _driver.FindElement(By.CssSelector("#shadow_host"));
var shadowRoot = shadowHost.GetShadowRoot();
var shadowContent = shadowRoot.FindElement(By.CssSelector("#shadow_content"));
```

```ruby
shadow_host = @driver.find_element(css: '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(css: '#shadow_content')
```

```java
WebElement fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"));
  
```

```python
fruit = driver.find_element(By.CSS_SELECTOR,"#fruits .tomatoes")
  
```

```csharp
var fruit = driver.FindElement(By.CssSelector("#fruits .tomatoes"));
  
```

```rb
      driver.find_element(css: '#fruits .tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L19)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const fruit = await driver.findElement(By.css('#fruits .tomatoes'));
  
```

```kotlin
val fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"))
  
```

```java
List<WebElement> plants = driver.findElements(By.tagName("li"));
  
```

```python
plants = driver.find_elements(By.TAG_NAME, "li")
  
```

```csharp
IReadOnlyList<IWebElement> plants = driver.FindElements(By.TagName("li"));
  
```

```rb
      driver.find_elements(tag_name: 'li')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L23)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const plants = await driver.findElements(By.tagName('li'));
  
```

```kotlin
val plants: List<WebElement> = driver.findElements(By.tagName("li"))
  
```

```java
List<WebElement> elements = driver.findElements(By.tagName("li"));

for (WebElement element : elements) {
    System.out.println("Paragraph text:" + element.getText());
}
  
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Firefox()

    # Navigate to Url
driver.get("https://www.example.com")

    # Get all the elements available with tag name 'p'
elements = driver.find_elements(By.TAG_NAME, 'p')

for e in elements:
    print(e.text)
  
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using System.Collections.Generic;

namespace FindElementsExample {
 class FindElementsExample {
  public static void Main(string[] args) {
   IWebDriver driver = new FirefoxDriver();
   try {
    // Navigate to Url
    driver.Navigate().GoToUrl("https://example.com");

    // Get all the elements available with tag name 'p'
    IList < IWebElement > elements = driver.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }

   } finally {
    driver.Quit();
   }
  }
 }
}
  
```

```rb
      elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L27-L28)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
   
   require 'spec_helper'
   
   RSpec.describe 'Element Finders' do
     let(:driver) { start_session }
   
     context 'without executing finders', skip: 'these are just examples, not actual tests' do
       it 'finds the first matching element' do
         driver.find_element(class: 'tomatoes')
       end
   
       it 'uses a subset of the dom to find an element' do
         fruits = driver.find_element(id: 'fruits')
         fruits.find_element(class: 'tomatoes')
       end
   
       it 'uses an optimized locator' do
         driver.find_element(css: '#fruits .tomatoes')
       end
   
       it 'finds all matching elements' do
         driver.find_elements(tag_name: 'li')
       end
   
       it 'gets an element from a collection' do
         elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'finds element from element' do
         element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'find active element' do
         driver.find_element(css: '[name="q"]').send_keys('webElement')
         driver.switch_to.active_element.attribute('title')
       end
     end
   end
   
```

```javascript
const {Builder, By} = require('selenium-webdriver');
(async function example() {
    let driver = await new Builder().forBrowser('firefox').build();
    try {
        // Navigate to Url
        await driver.get('https://www.example.com');

        // Get all the elements available with tag 'p'
        let elements = await driver.findElements(By.css('p'));
        for(let e of elements) {
            console.log(await e.getText());
        }
    }
    finally {
        await driver.quit();
    }
})();
  
```

```kotlin
import org.openqa.selenium.By
import org.openqa.selenium.firefox.FirefoxDriver

fun main() {
    val driver = FirefoxDriver()
    try {
        driver.get("https://example.com")
        // Get all the elements available with tag name 'p'
        val elements = driver.findElements(By.tagName("p"))
        for (element in elements) {
            println("Paragraph text:" + element.text)
        }
    } finally {
        driver.quit()
    }
}
  
```

```java
  import org.openqa.selenium.By;
  import org.openqa.selenium.WebDriver;
  import org.openqa.selenium.WebElement;
  import org.openqa.selenium.chrome.ChromeDriver;
  import java.util.List;

  public class findElementsFromElement {
      public static void main(String[] args) {
          WebDriver driver = new ChromeDriver();
          try {
              driver.get("https://example.com");

              // Get element with tag name 'div'
              WebElement element = driver.findElement(By.tagName("div"));

              // Get all the elements available with tag name 'p'
              List<WebElement> elements = element.findElements(By.tagName("p"));
              for (WebElement e : elements) {
                  System.out.println(e.getText());
              }
          } finally {
              driver.quit();
          }
      }
  }
  
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://www.example.com")
##get elements from parent element using TAG_NAME

    # Get element with tag name 'div'
element = driver.find_element(By.TAG_NAME, 'div')

    # Get all the elements available with tag name 'p'
elements = element.find_elements(By.TAG_NAME, 'p')
for e in elements:
    print(e.text)

##get elements from parent element using XPATH
##NOTE: in order to utilize XPATH from current element, you must add "." to beginning of path

    # Get first element of tag 'ul'
element = driver.find_element(By.XPATH, '//ul')

    # get children of tag 'ul' with tag 'li'
elements  = element.find_elements(By.XPATH, './/li')
for e in elements:
    print(e.text)
  
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace FindElementsFromElement {
 class FindElementsFromElement {
  public static void Main(string[] args) {
   IWebDriver driver = new ChromeDriver();
   try {
    driver.Navigate().GoToUrl("https://example.com");

    // Get element with tag name 'div'
    IWebElement element = driver.FindElement(By.TagName("div"));

    // Get all the elements available with tag name 'p'
    IList < IWebElement > elements = element.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }
   } finally {
    driver.Quit();
   }
  }
 }
}
  
```

```rb
      element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L32-L34)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
   
   require 'spec_helper'
   
   RSpec.describe 'Element Finders' do
     let(:driver) { start_session }
   
     context 'without executing finders', skip: 'these are just examples, not actual tests' do
       it 'finds the first matching element' do
         driver.find_element(class: 'tomatoes')
       end
   
       it 'uses a subset of the dom to find an element' do
         fruits = driver.find_element(id: 'fruits')
         fruits.find_element(class: 'tomatoes')
       end
   
       it 'uses an optimized locator' do
         driver.find_element(css: '#fruits .tomatoes')
       end
   
       it 'finds all matching elements' do
         driver.find_elements(tag_name: 'li')
       end
   
       it 'gets an element from a collection' do
         elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'finds element from element' do
         element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'find active element' do
         driver.find_element(css: '[name="q"]').send_keys('webElement')
         driver.switch_to.active_element.attribute('title')
       end
     end
   end
   
```

```javascript
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = new Builder()
          .forBrowser('chrome')
          .build();

      await driver.get('https://www.example.com');

      // Get element with tag name 'div'
      let element = driver.findElement(By.css("div"));

      // Get all the elements available with tag name 'p'
      let elements = await element.findElements(By.css("p"));
      for(let e of elements) {
          console.log(await e.getText());
      }
  })();
  
```

```kotlin
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://example.com")

          // Get element with tag name 'div'
          val element = driver.findElement(By.tagName("div"))

          // Get all the elements available with tag name 'p'
          val elements = element.findElements(By.tagName("p"))
          for (e in elements) {
              println(e.text)
          }
      } finally {
          driver.quit()
      }
  }
  
```

```java
  import org.openqa.selenium.*;
  import org.openqa.selenium.chrome.ChromeDriver;

  public class activeElementTest {
    public static void main(String[] args) {
      WebDriver driver = new ChromeDriver();
      try {
        driver.get("http://www.google.com");
        driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement");

        // Get attribute of current active element
        String attr = driver.switchTo().activeElement().getAttribute("title");
        System.out.println(attr);
      } finally {
        driver.quit();
      }
    }
  }
  
```

```python
  from selenium import webdriver
  from selenium.webdriver.common.by import By

  driver = webdriver.Chrome()
  driver.get("https://www.google.com")
  driver.find_element(By.CSS_SELECTOR, '[name="q"]').send_keys("webElement")

    # Get attribute of current active element
  attr = driver.switch_to.active_element.get_attribute("title")
  print(attr)
  
```

```csharp
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;

    namespace ActiveElement {
     class ActiveElement {
      public static void Main(string[] args) {
       IWebDriver driver = new ChromeDriver();
       try {
        // Navigate to Url
        driver.Navigate().GoToUrl("https://www.google.com");
        driver.FindElement(By.CssSelector("[name='q']")).SendKeys("webElement");

        // Get attribute of current active element
        string attr = driver.SwitchTo().ActiveElement().GetAttribute("title");
        System.Console.WriteLine(attr);
       } finally {
        driver.Quit();
       }
      }
     }
    }
  
```

```rb
      driver.find_element(css: '[name="q"]').send_keys('webElement')
        driver.switch_to.active_element.attribute('title')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L38-L39)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
  
  require 'spec_helper'
  
  RSpec.describe 'Element Finders' do
    let(:driver) { start_session }
  
    context 'without executing finders', skip: 'these are just examples, not actual tests' do
      it 'finds the first matching element' do
        driver.find_element(class: 'tomatoes')
      end
  
      it 'uses a subset of the dom to find an element' do
        fruits = driver.find_element(id: 'fruits')
        fruits.find_element(class: 'tomatoes')
      end
  
      it 'uses an optimized locator' do
        driver.find_element(css: '#fruits .tomatoes')
      end
  
      it 'finds all matching elements' do
        driver.find_elements(tag_name: 'li')
      end
  
      it 'gets an element from a collection' do
        elements = driver.find_elements(:tag_name, 'p')
        elements.each { |e| puts e.text }
      end
  
      it 'finds element from element' do
        element = driver.find_element(:tag_name, 'div')
        elements = element.find_elements(:tag_name, 'p')
        elements.each { |e| puts e.text }
      end
  
      it 'find active element' do
        driver.find_element(css: '[name="q"]').send_keys('webElement')
        driver.switch_to.active_element.attribute('title')
      end
    end
  end
  
```

```javascript
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = await new Builder().forBrowser('chrome').build();
      await driver.get('https://www.google.com');
      await  driver.findElement(By.css('[name="q"]')).sendKeys("webElement");

      // Get attribute of current active element
      let attr = await driver.switchTo().activeElement().getAttribute("title");
      console.log(`${attr}`)
  })();
  
```

```kotlin
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://www.google.com")
          driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement")

          // Get attribute of current active element
          val attr = driver.switchTo().activeElement().getAttribute("title")
          print(attr)
      } finally {
          driver.quit()
      }
  }
  
```

# 2 - Web元素交互

```java
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L18-L22)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L12-L17)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L17-L21)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'color_input').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L11)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
    await submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L20)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
  const assert = require("assert");
  
  (async function firstTest() {
    let driver;
    
    try {
      driver = await new Builder().forBrowser(Browser.CHROME).build();
      await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
    
      let title = await driver.getTitle();
      assert.equal("Web form", title);
    
      await driver.manage().setTimeouts({implicit: 500});
    
      let textBox = await driver.findElement(By.name('my-text'));
      let submitButton = await driver.findElement(By.css('button'));
    
      await textBox.sendKeys('Selenium');
      await submitButton.click();
    
      let message = await driver.findElement(By.id('message'));
      let value = await message.getText();
      assert.equal("Received!", value);
    } catch (e) {
      console.log(e)
    } finally {
      await driver.quit();
    }
  }())
  
```

```kotlin
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    // Click the element
    driver.findElement(By.name("color_input")).click();
  
  
```

```java
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L27-L32)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L22-L27)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L27-L33)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L16)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
      let inputField = await driver.findElement(By.name('no_type'));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/interactions.spec.js#L21)

##### /examples/javascript/test/elements/interactions.spec.js

```js

  const {By, Browser, Builder} = require('selenium-webdriver');
  const assert = require("node:assert");
  
  
  describe('Element Interactions', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('should Clear input and send keys into input field', async function () {
  
      try {
        await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
        let inputField = await driver.findElement(By.name('no_type'));
        await inputField.clear();
        await inputField.sendKeys('Selenium');
        const text = await inputField.getAttribute('value');
        assert.strictEqual(text, "Selenium");
      } catch (e) {
        console.log(e)
      }
    });
  });
```

```kotlin
  
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

	//Clear field to empty it from any previous data
	driver.findElement(By.name("email_input")).clear()
	
    // Enter text 
    driver.findElement(By.name("email_input")).sendKeys("admin@localhost.dev")
  
  
```

```java
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L38-L40)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    email_input.clear()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L34)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L40-L43)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'email_input').clear
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L15)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
      await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/interactions.spec.js#L20)

##### /examples/javascript/test/elements/interactions.spec.js

```js

  const {By, Browser, Builder} = require('selenium-webdriver');
  const assert = require("node:assert");
  
  
  describe('Element Interactions', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('should Clear input and send keys into input field', async function () {
  
      try {
        await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
        let inputField = await driver.findElement(By.name('no_type'));
        await inputField.clear();
        await inputField.sendKeys('Selenium');
        const text = await inputField.getAttribute('value');
        assert.strictEqual(text, "Selenium");
      } catch (e) {
        console.log(e)
      }
    });
  });
```

```kotlin
  
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

	//Clear field to empty it from any previous data
	driver.findElement(By.name("email_input")).clear()
	
  
  
```

## 提交

在Selenium 4中, 不再通过单独的端点以及脚本执行的方法来实现. 因此, 建议不要使用此方法, 而是单击相应的表单提交按钮.

# 3 - 定位策略

在DOM中标识一个或多个特定元素的方法.

定位器是在页面上标识元素的一种方法。它是传送给 [查找元素](https://www.selenium.dev/zh-cn/documentation/webdriver/elements/finders/) 方法的参数。

查看 [鼓励测试练习](https://www.selenium.dev/zh-cn/documentation/test_practices/encouraged/) 寻找 [定位器](https://www.selenium.dev/zh-cn/documentation/test_practices/encouraged/locators/)的小技巧， 包含在查找方法中，不同时间，不同原因下，单独声明的定位器的使用方法。

### 元素选择策略

在 WebDriver 中有 8 种不同的内置元素定位策略：

| 定位器 Locator       | 描述                                                 |
| ----------------- | -------------------------------------------------- |
| class name        | 定位class属性与搜索值匹配的元素（不允许使用复合类名）                      |
| css selector      | 定位 CSS 选择器匹配的元素                                    |
| id                | 定位 id 属性与搜索值匹配的元素                                  |
| name              | 定位 name 属性与搜索值匹配的元素                                |
| link text         | 定位link text可视文本与搜索值完全匹配的锚元素                        |
| partial link text | 定位link text可视文本部分与搜索值部分匹配的锚点元素。如果匹配多个元素，则只选择第一个元素。 |
| tag name          | 定位标签名称与搜索值匹配的元素                                    |
| xpath             | 定位与 XPath 表达式匹配的元素                                 |

## Creating Locators

To work on a web element using Selenium, we need to first locate it on the web page. Selenium provides us above mentioned ways, using which we can locate element on the page. To understand and create locator we will use the following HTML snippet.

```html
<html>
<body>
<style>
.information {
  background-color: white;
  color: black;
  padding: 10px;
}
</style>
<h2>Contact Selenium</h2>

<form>
  <input type="radio" name="gender" value="m" />Male &nbsp;
  <input type="radio" name="gender" value="f" />Female <br>
  <br>
  <label for="fname">First name:</label><br>
  <input class="information" type="text" id="fname" name="fname" value="Jane"><br><br>
  <label for="lname">Last name:</label><br>
  <input class="information" type="text" id="lname" name="lname" value="Doe"><br><br>
  <label for="newsletter">Newsletter:</label>
  <input type="checkbox" name="newsletter" value="1" /><br><br>
  <input type="submit" value="Submit">
</form> 

<p>To know more about Selenium, visit the official page 
<a href ="www.selenium.dev">Selenium Official Page</a> 
</p>

</body>
</html>
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L31" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L7-L9)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.ClassName("information"));
  
```

```rb
    driver.find_element(class: 'information')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L7)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.className('information'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.className("information"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L38" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L17-L19)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.CssSelector("#fname"));
  
```

```rb
    driver.find_element(css: '#fname')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L11)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.css('#fname'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.css("#fname"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L45" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L27-L29)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.Id("lname"));
  
```

```rb
    driver.find_element(id: 'lname')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L15)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.id('lname'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.id("lname"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L52" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L37-L39)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.Name("newsletter"));
  
```

```rb
    driver.find_element(name: 'newsletter')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L19)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.name('newsletter'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.name("newsletter"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L59" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L47-L49)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.LinkText("Selenium Official Page"));
  
```

```rb
    driver.find_element(link_text: 'Selenium Official Page')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L23)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.linkText('Selenium Official Page'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.linkText("Selenium Official Page"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L66" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L57-L59)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.PartialLinkText("Official Page"));
  
```

```rb
    driver.find_element(partial_link_text: 'Official Page')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L27)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.partialLinkText('Official Page'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.partialLinkText("Official Page"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L73" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L67-L69)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.TagName("a"));
  
```

```rb
    driver.find_element(tag_name: 'a')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L31)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.tagName('a'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.tagName("a"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L80" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L77-L79)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.Xpath("//input[@value='f']"));
  
```

```rb
    driver.find_element(xpath: "//input[@value='f']")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L35)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.xpath('//input[@value='f']'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.xpath('//input[@value='f']'))
  
```

```java
    import org.openqa.selenium.By;
    WebDriver driver = new ChromeDriver();
	driver.findElement(By.className("information"));
  
```

```python
    from selenium.webdriver.common.by import By
    driver = webdriver.Chrome()
	driver.find_element(By.CLASS_NAME, "information")
  
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.ClassName("information"));
  
```

```rb
    driver.find_element(class: 'information')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L7)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.className('information'));
  
```

```kotlin
    import org.openqa.selenium.By
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.className("information"))
  
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java#L37-L38)

##### /examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java

```java
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java#L22-L23)

##### /examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java

```java
```

```java
By emailLocator = RelativeLocator.with(By.tagName("input")).above(By.id("password"));
```

```python
email_locator = locate_with(By.TAG_NAME, "input").above({By.ID: "password"})
```

```csharp
var emailLocator = RelativeBy.WithLocator(By.TagName("input")).Above(By.Id("password"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L40)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let emailLocator = locateWith(By.tagName('input')).above(By.id('password'));
```

```kotlin
val emailLocator = RelativeLocator.with(By.tagName("input")).above(By.id("password"))
```

```java
By passwordLocator = RelativeLocator.with(By.tagName("input")).below(By.id("email"));
```

```python
password_locator = locate_with(By.TAG_NAME, "input").below({By.ID: "email"})
```

```csharp
var passwordLocator = RelativeBy.WithLocator(By.TagName("input")).Below(By.Id("email"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L44)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let passwordLocator = locateWith(By.tagName('input')).below(By.id('email'));
```

```kotlin
val passwordLocator = RelativeLocator.with(By.tagName("input")).below(By.id("email"))
```

```java
By cancelLocator = RelativeLocator.with(By.tagName("button")).toLeftOf(By.id("submit"));
```

```python
cancel_locator = locate_with(By.TAG_NAME, "button").to_left_of({By.ID: "submit"})
```

```csharp
var cancelLocator = RelativeBy.WithLocator(By.tagName("button")).LeftOf(By.Id("submit"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L48)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let cancelLocator = locateWith(By.tagName('button')).toLeftOf(By.id('submit'));
```

```kotlin
val cancelLocator = RelativeLocator.with(By.tagName("button")).toLeftOf(By.id("submit"))
```

```java
By submitLocator = RelativeLocator.with(By.tagName("button")).toRightOf(By.id("cancel"));
```

```python
submit_locator = locate_with(By.TAG_NAME, "button").to_right_of({By.ID: "cancel"})
```

```csharp
var submitLocator = RelativeBy.WithLocator(By.tagName("button")).RightOf(By.Id("cancel"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L52)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let submitLocator = locateWith(By.tagName('button')).toRightOf(By.id('cancel'));
```

```kotlin
val submitLocator = RelativeLocator.with(By.tagName("button")).toRightOf(By.id("cancel"))
```

```java
By emailLocator = RelativeLocator.with(By.tagName("input")).near(By.id("lbl-email"));
```

```python
email_locator = locate_with(By.TAG_NAME, "input").near({By.ID: "lbl-email"})
```

```csharp
var emailLocator = RelativeBy.WithLocator(By.tagName("input")).Near(By.Id("lbl-email"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L56)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let emailLocator = locateWith(By.tagName('input')).near(By.id('lbl-email'));
```

```kotlin
val emailLocator = RelativeLocator.with(By.tagName("input")).near(By.id("lbl-email"));
```

```java
By submitLocator = RelativeLocator.with(By.tagName("button")).below(By.id("email")).toRightOf(By.id("cancel"));
```

```python
submit_locator = locate_with(By.TAG_NAME, "button").below({By.ID: "email"}).to_right_of({By.ID: "cancel"})
```

```csharp
var submitLocator = RelativeBy.WithLocator(By.tagName("button")).Below(By.Id("email")).RightOf(By.Id("cancel"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L60)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let submitLocator = locateWith(By.tagName('button')).below(By.id('email')).toRightOf(By.id('cancel'));
```

```kotlin
val submitLocator = RelativeLocator.with(By.tagName("button")).below(By.id("email")).toRightOf(By.id("cancel"))
```

# 4 - 关于网络元素的信息

```java
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L27-L29)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L12-L15)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L18-L22)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    displayed_value = driver.find_element(name: 'email_input').displayed?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L12)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L16-L17)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//returns true if element is displayed else returns false
val flag = driver.findElement(By.name("email_input")).isDisplayed()
```

```java
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L32-L34)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L19)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L25-L27)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    enabled_value = driver.find_element(name: 'email_input').enabled?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L17)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L23-L24)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//returns true if element is enabled else returns false
val attr = driver.findElement(By.name("button_input")).isEnabled()
```

```java
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L37-L39)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L23)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
  from selenium.webdriver.common.by import By
  
  import pytest
  
  
  def test_informarion():
      # Initialize WebDriver
      driver = webdriver.Chrome()
      driver.implicitly_wait(0.5)
  
      driver.get("https://www.selenium.dev/selenium/web/inputs.html")
  
      # isDisplayed
      is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
      assert is_email_visible == True
  
      # isEnabled
      is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
      assert is_enabled_button == True
  
      # isSelected
      is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
      assert is_selected_check == True
  
      # TagName
      tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
      assert tag_name_inp == "input"
  
      # GetRect
      rect = driver.find_element(By.NAME, "range_input").rect
      assert rect["x"] == 10
  
      # CSS Value
      css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
          "font-size"
      )
      assert css_value == "13.3333px"
  
      # GetText
      text = driver.find_element(By.TAG_NAME, "h1").text
      assert text == "Testing Inputs"
  
      # FetchAttributes
      email_txt = driver.find_element(By.NAME, "email_input")
      value_info = email_txt.get_attribute("value")
      assert value_info == "admin@localhost"
  
```

```cs
            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L30-L32)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    selected_value = driver.find_element(name: 'email_input').selected?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L22)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L30-L31)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//returns true if element is checked else returns false
val attr =  driver.findElement(By.name("checkbox_input")).isSelected()
```

```java
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L42-L44)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L27)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L35-L37)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    tag_name = driver.find_element(name: 'email_input').tag_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L27)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L37-L38)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//returns TagName of the element 
val attr =  driver.findElement(By.name("email_input")).getTagName()
```

```java
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L47-L50)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    rect = driver.find_element(By.NAME, "range_input").rect
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L31)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L40-L43)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    size = driver.find_element(name: 'email_input').size
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L32)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    let object = await driver.findElement(By.name('range_input')).getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L45)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

// Returns height, width, x and y coordinates referenced element
val res = driver.findElement(By.name("range_input")).rect

// Rectangle class provides getX,getY, getWidth, getHeight methods
println(res.getX())
```

```java
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L52-L54)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L35-L37)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L49-L50)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L38)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L76-L78)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to Url
driver.get("https://www.selenium.dev/selenium/web/colorPage.html")

// Retrieves the computed style property 'color' of linktext
val cssValue = driver.findElement(By.id("namedColor")).getCssValue("background-color")
```

```java
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L58-L60)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    text = driver.find_element(By.TAG_NAME, "h1").text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L41)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L53-L55)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    text = driver.find_element(xpath: '//h1').text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L43)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L84-L86)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to URL
driver.get("https://www.selenium.dev/selenium/web/linked_image.html")

// retrieves the text of the element
val text = driver.findElement(By.id("justanotherlink")).getText()
```

```java
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L64-L68)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L44-L46)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L58-L62)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L48)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L55-L59)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to URL
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//fetch the value property associated with the textbox
val attr = driver.findElement(By.name("email_input")).getAttribute("value")
```

# 5 - 文件上传

```java
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/FileUploadTest.java#L17-L19)

##### /examples/java/src/test/java/dev/selenium/elements/FileUploadTest.java

```java
package dev.selenium.elements;

import dev.selenium.BaseChromeTest;
import java.io.File;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

public class FileUploadTest extends BaseChromeTest {

  @Test
  public void fileUploadTest() {
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }
}
```

```py
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_file_upload.py#L12-L14)

##### /examples/python/tests/elements/test\_file\_upload.py

```py
import os

from selenium import webdriver
from selenium.webdriver.common.by import By


def test_uploads(driver):
    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"
```

```cs
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/FileUploadTest.cs#L21-L23)

##### /examples/dotnet/SeleniumDocs/Elements/FileUploadTest.cs

```cs
using System;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;

namespace SeleniumDocs.Elements
{
    [TestClass]
    public class FileUploadTest : BaseChromeTest
    {
        [TestMethod]
        public void Uploads()
        {
            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }
    }
}
```

```rb
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/file_upload_spec.rb#L12-L14)

##### /examples/ruby/spec/elements/file\_upload\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'File Upload' do
  let(:driver) { start_session }

  it 'uploads' do
    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    file_name = driver.find_element(id: 'uploaded-files')
    expect(file_name.text).to eq 'selenium-snapshot.png'
  end
end
```

```js
    await driver.get('https://the-internet.herokuapp.com/upload');
    // Upload snapshot
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/fileUpload.spec.js#L24-L25)

##### /examples/javascript/test/elements/fileUpload.spec.js

```js

const {Browser, By, until, Builder} = require("selenium-webdriver");
const path = require("path");
const assert = require('node:assert');


describe('File Upload Test', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async() => await driver.quit());

  it('Should be able to upload a file successfully', async function() {
    const image = path.resolve('./test/resources/selenium-snapshot.png')

    await driver.manage().setTimeouts({implicit: 5000});

    // Navigate to URL
    await driver.get('https://the-internet.herokuapp.com/upload');
    // Upload snapshot
    await driver.findElement(By.id("file-upload")).sendKeys(image);
    await driver.findElement(By.id("file-submit")).submit();

    const revealed = await driver.findElement(By.id('uploaded-files'))
    await driver.wait(until.elementIsVisible(revealed), 2000);
    const data = await driver.findElement(By.css('h3'));

    assert.equal(await data.getText(), `File Uploaded!`);
  });
});
```

----
url: https://www.selenium.dev/documentation/grid/configuration/
----

# Configuration of Components

Here you can see how each Grid component can be configured individually based on common configuration values and component-specific configuration values.

***

##### [Configuration help](/documentation/grid/configuration/help/)

Get information about all the available options to configure Grid.

##### [CLI options in the Selenium Grid](/documentation/grid/configuration/cli_options/)

All Grid components configuration CLI options in detail.

##### [TOML configuration options](/documentation/grid/configuration/toml_options/)

Grid configuration examples using Toml files.

----
url: https://www.selenium.dev/documentation/ide/
----

# Selenium IDE

The Selenium IDE is a browser extension that records and plays back a user’s actions.

Selenium’s Integrated Development Environment ([Selenium IDE](//selenium.dev/selenium-ide)) is an easy-to-use browser extension that records a user’s actions in the browser using existing Selenium commands, with parameters defined by the context of each element. It provides an excellent way to learn Selenium syntax. It’s available for Google Chrome, Mozilla Firefox, and Microsoft Edge.

For more information, visit the complete [Selenium IDE Documentation](https://www.selenium.dev/selenium-ide/docs/en/introduction/getting-started)

Last modified December 7, 2021: [add IDE page to top level (#844) \[deploy site\] (b634eec49a0)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/b634eec49a0da0462e79a2bac3e5d6440a5c7c1d)

----
url: https://www.selenium.dev/documentation/grid/advanced_features/external_datastore/
----

# External datastore

```sql
CREATE TABLE IF NOT EXISTS sessions_map(
    session_ids varchar(256),
    session_caps text,
    session_uri varchar(256),
    session_stereotype text,
    session_start varchar(256)
 );
```

* In the same directory as the `init.sql`, create a file named `docker-compose.yml` with its contents as below:

```yaml
version: '3.8'
services:
  db:
    image: postgres:9.6-bullseye
    restart: always
    environment:
      - POSTGRES_USER=seluser
      - POSTGRES_PASSWORD=seluser
      - POSTGRES_DB=selenium_sessions
    ports:
      - "5432:5432"
    volumes:
    - ./init.sql:/docker-entrypoint-initdb.d/init.sql
```

We can now start our database container by running:

```bash
docker-compose up -d
```

*Our database name is `selenium_sessions` with its username and password set to `seluser`*

If you are working with an already running PostGreSQL DB instance, then you just need to create a database named `selenium_sessions` and the table `sessions_map` using the above mentioned SQL statement.

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
implementation = "org.openqa.selenium.grid.sessionmap.jdbc.JdbcBackedSessionMap"
jdbc-url = "jdbc:postgresql://localhost:5432/selenium_sessions"
jdbc-user = "seluser"
jdbc-password = "seluser"
```

*Note:* If you plan to use an existing PostGreSQL DB instance, then replace `localhost:5432` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed Grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Sessions Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

```yaml
version: '3.8'
services:
  redis:
    image: redis:bullseye
    restart: always
    ports:
      - "6379:6379"
```

We can now start our Redis container by running:

```bash
docker-compose up -d
```

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
scheme = "redis"
implementation = "org.openqa.selenium.grid.sessionmap.redis.RedisBackedSessionMap"
hostname = "localhost"
port = 6379
```

*Note:* If you plan to use an existing Redis Cache instance, then replace `localhost` and `6379` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Session Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

* At this point the current directory should contain the following files:

  * `docker-compose.yml`
  * `sessions.toml`
  * `distributed.sh`

* You can now spawn the Grid by running `distributed.sh` shell script and quickly run a test. You will notice that the Grid now stores session information into the Redis instance. You can perhaps make use of a Redis GUI such as [TablePlus](https://tableplus.com/) to see them (Make sure that you have setup a debug point in your test, because the values will get deleted as soon as the test runs to completion).

In the line which spawns a `SessionMap` on a machine:

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

* The variable names from the above script have been replaced with their actual values for clarity.
* Remember to substitute `localhost` with the actual hostname of the machine where your `Event-Bus` is running.
* The arguments being passed to `coursier` are basically the GAV (Group Artifact Version) Maven co-ordinates of:
  * [selenium-session-map-redis](https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-session-map-redis) which is needed to help us store sessions information in Redis Cache.
* `sessions.toml` is the configuration file that we created earlier.

Last modified November 15, 2022: [Docs for External Sessions Data store (#1225) (60943504fb8)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/60943504fb8c6a2e992afa291b77199d629f7ed3)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/troubleshooting/errors/
----

# 理解常见的异常

***

##### [Unable to Locate Driver Error](/zh-cn/documentation/webdriver/troubleshooting/errors/driver_location/)

Troubleshooting missing path to driver executable.

最后修改 May 12, 2026: [docs: add Selenium Wait Generator to NoSuchElementException solutions (#2627) (a25fe46dcbf)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/a25fe46dcbfe2b07ccb95ec80923b9d94eadd12b)

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/encouraged/consider_using_a_fluent_api/
----

# 考虑使用Fluent API

Martin Fowler创造了术语 [“Fluent API”](//www.martinfowler.com/bliki/FluentInterface.html). Selenium已经在其 `FluentWait` 类中实现了类似的东西, 这是对标准 `Wait` 类的替代. 您可以在页面对象中启用Fluent API设计模式, 然后使用如下代码段查询Google搜索页面:

```java
driver.get( "http://www.google.com/webhp?hl=en&amp;tab=ww" );
GoogleSearchPage gsp = new GoogleSearchPage(driver);
gsp.setSearchString().clickSearchButton();
```

Google页面对象类具有这种流畅行为后可能看起来像这样:

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

public class GoogleSearchPage extends BasePage {
    public GoogleSearchPage(WebDriver driver) {
        super(driver);
        // Generally do not assert within pages or components.
        // Effectively throws an exception if the lambda condition is not met.
        new WebDriverWait(driver, Duration.ofSeconds(3)).until(d -> d.findElement(By.id("logo")));
    }

    public GoogleSearchPage setSearchString(String sstr) {
        driver.findElement(By.id("gbqfq")).sendKeys(sstr);
        return this;
    }

    public void clickSearchButton() {
        driver.findElement(By.id("gbqfb")).click();
    }
}
```

最后修改 May 17, 2023: [Consider Using a Fluent API - Fix usage (#1378) (332da70d909)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/332da70d90970623288d2e98fbcff098b7812995)

----
url: https://www.selenium.dev/ja/documentation/webdriver/support_features/listeners/
----

----
url: https://www.selenium.dev/documentation/webdriver/browsers/safari/
----

# Safari specific functionality

These are capabilities and features specific to Apple Safari browsers.

Unlike Chromium and Firefox drivers, the safaridriver is installed with the Operating System. To enable automation on Safari, run the following command from the terminal:

```shell
safaridriver --enable
```

```java
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#24-L25)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

```py
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L9-L10)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

```cs
            var options = new SafariOptions();
            driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/SafariTest.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/Browsers/SafariTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Safari;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("OSX")]
    public class SafariTest
    {
        private SafariDriver driver;

        [TestCleanup]
        public void QuitDriver()
        {
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new SafariOptions();
            driver = new SafariDriver(options);
        }
    }
}
```

```rb
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L8-L9)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

```js
    let driver = new Builder()
      .forBrowser(Browser.SAFARI)
      .setSafariOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/safariSpecificCap.spec.js#L8-L11)

##### /examples/javascript/test/browser/safariSpecificCap.spec.js

```js
const safari = require('selenium-webdriver/safari');
const {Browser, Builder} = require("selenium-webdriver");
const options = new safari.Options();
const process  =  require('node:process');

describe('Should be able to Test Command line arguments', function () {
  (process.platform === 'darwin' ? it : it.skip)('safari caps', async function () {
    let driver = new Builder()
      .forBrowser(Browser.SAFARI)
      .setSafariOptions(options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
  val options = SafariOptions()
  val driver = SafariDriver(options)
```

```java
                .withLogging(true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `SafariDriverService.SAFARI_DRIVER_LOGGING`\
Property value: `"true"` or `"false"`

[Selenium v4.26](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.26.0)

```py
    service = webdriver.SafariService(enable_logging=True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L17)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L20)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

```java
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#L39-L40)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

```py
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L25-L30)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L38-L39)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

----
url: https://www.selenium.dev/documentation/test_practices/design_strategies/
----

# Design patterns and development strategies

```java
package com.example.webdriver;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class EditIssue {

  private final WebDriver driver;

  public EditIssue(WebDriver driver) {
    this.driver = driver;
  }

  public void setTitle(String title) {
    WebElement field = driver.findElement(By.id("issue_title")));
    clearAndType(field, title);
  }

  public void setBody(String body) {
    WebElement field = driver.findElement(By.id("issue_body"));
    clearAndType(field, body);
  }

  public void setHowToReproduce(String howToReproduce) {
    WebElement field = driver.findElement(By.id("issue_form_repro-command"));
    clearAndType(field, howToReproduce);
  }

  public void setLogOutput(String logOutput) {
    WebElement field = driver.findElement(By.id("issue_form_logs"));
    clearAndType(field, logOutput);
  }

  public void setOperatingSystem(String operatingSystem) {
    WebElement field = driver.findElement(By.id("issue_form_operating-system"));
    clearAndType(field, operatingSystem);
  }

  public void setSeleniumVersion(String seleniumVersion) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-version"));
    clearAndType(field, logOutput);
  }

  public void setBrowserVersion(String browserVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-versions"));
    clearAndType(field, browserVersion);
  }

  public void setDriverVersion(String driverVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-driver-versions"));
    clearAndType(field, driverVersion);
  }

  public void setUsingGrid(String usingGrid) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-grid-version"));
    clearAndType(field, usingGrid);
  }

  public IssueList submit() {
    driver.findElement(By.cssSelector("button[type='submit']")).click();
    return new IssueList(driver);
  }

  private void clearAndType(WebElement field, String text) {
    field.clear();
    field.sendKeys(text);
  }
}
```

In order to turn this into a LoadableComponent, all we need to do is to set that as the base type:

```java
public class EditIssue extends LoadableComponent<EditIssue> {
  // rest of class ignored for now
}
```

This signature looks a little unusual, but all it means is that this class represents a LoadableComponent that loads the EditIssue page.

By extending this base class, we need to implement two new methods:

```java
  @Override
  protected void load() {
    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();
    assertTrue("Not on the issue entry page: " + url, url.endsWith("/new"));
  }
```

The `load` method is used to navigate to the page, whilst the `isLoaded` method is used to determine whether we are on the right page. Although the method looks like it should return a boolean, instead it performs a series of assertions using JUnit’s Assert class. There can be as few or as many assertions as you like. By using these assertions it’s possible to give users of the class clear information that can be used to debug tests.

With a little rework, our PageObject looks like:

```java
package com.example.webdriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

import static junit.framework.Assert.assertTrue;

public class EditIssue extends LoadableComponent<EditIssue> {

  private final WebDriver driver;
  
  // By default the PageFactory will locate elements with the same name or id
  // as the field. Since the issue_title element has an id attribute of "issue_title"
  // we don't need any additional annotations.
  private WebElement issue_title;
  
  // But we'd prefer a different name in our code than "issue_body", so we use the
  // FindBy annotation to tell the PageFactory how to locate the element.
  @FindBy(id = "issue_body") private WebElement body;
  
  public EditIssue(WebDriver driver) {
    this.driver = driver;
    
    // This call sets the WebElement fields.
    PageFactory.initElements(driver, this);
  }

  @Override
  protected void load() {
    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();
    assertTrue("Not on the issue entry page: " + url, url.endsWith("/new"));
  }

  public void setHowToReproduce(String howToReproduce) {
    WebElement field = driver.findElement(By.id("issue_form_repro-command"));
    clearAndType(field, howToReproduce);
  }

  public void setLogOutput(String logOutput) {
    WebElement field = driver.findElement(By.id("issue_form_logs"));
    clearAndType(field, logOutput);
  }

  public void setOperatingSystem(String operatingSystem) {
    WebElement field = driver.findElement(By.id("issue_form_operating-system"));
    clearAndType(field, operatingSystem);
  }

  public void setSeleniumVersion(String seleniumVersion) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-version"));
    clearAndType(field, logOutput);
  }

  public void setBrowserVersion(String browserVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-versions"));
    clearAndType(field, browserVersion);
  }

  public void setDriverVersion(String driverVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-driver-versions"));
    clearAndType(field, driverVersion);
  }

  public void setUsingGrid(String usingGrid) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-grid-version"));
    clearAndType(field, usingGrid);
  }

  public IssueList submit() {
    driver.findElement(By.cssSelector("button[type='submit']")).click();
    return new IssueList(driver);
  }

  private void clearAndType(WebElement field, String text) {
    field.clear();
    field.sendKeys(text);
  }
}
```

That doesn’t seem to have bought us much, right? One thing it has done is encapsulate the information about how to navigate to the page into the page itself, meaning that this information’s not scattered through the code base. It also means that we can do this in our tests:

```java
EditIssue page = new EditIssue(driver).get();
```

This call will cause the driver to navigate to the page if that’s necessary.

### Nested Components

LoadableComponents start to become more useful when they are used in conjunction with other LoadableComponents. Using our example, we could view the “edit issue” page as a component within a project’s website (after all, we access it via a tab on that site). You also need to be logged in to file an issue. We could model this as a tree of nested components:

```
 + ProjectPage
 +---+ SecuredPage
     +---+ EditIssue
```

What would this look like in code? For a start, each logical component would have its own class. The “load” method in each of them would “get” the parent. The end result, in addition to the EditIssue class above is:

ProjectPage.java:

```java
package com.example.webdriver;

import org.openqa.selenium.WebDriver;

import static org.junit.Assert.assertTrue;

public class ProjectPage extends LoadableComponent<ProjectPage> {

  private final WebDriver driver;
  private final String projectName;

  public ProjectPage(WebDriver driver, String projectName) {
    this.driver = driver;
    this.projectName = projectName;
  }

  @Override
  protected void load() {
    driver.get("http://" + projectName + ".googlecode.com/");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();

    assertTrue(url.contains(projectName));
  }
}
```

and SecuredPage.java:

```java
package com.example.webdriver;

import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import static org.junit.Assert.fail;

public class SecuredPage extends LoadableComponent<SecuredPage> {

  private final WebDriver driver;
  private final LoadableComponent<?> parent;
  private final String username;
  private final String password;

  public SecuredPage(WebDriver driver, LoadableComponent<?> parent, String username, String password) {
    this.driver = driver;
    this.parent = parent;
    this.username = username;
    this.password = password;
  }

  @Override
  protected void load() {
    parent.get();

    String originalUrl = driver.getCurrentUrl();

    // Sign in
    driver.get("https://www.google.com/accounts/ServiceLogin?service=code");
    driver.findElement(By.name("Email")).sendKeys(username);
    WebElement passwordField = driver.findElement(By.name("Passwd"));
    passwordField.sendKeys(password);
    passwordField.submit();

    // Now return to the original URL
    driver.get(originalUrl);
  }

  @Override
  protected void isLoaded() throws Error {
    // If you're signed in, you have the option of picking a different login.
    // Let's check for the presence of that.

    try {
      WebElement div = driver.findElement(By.id("multilogin-dropdown"));
    } catch (NoSuchElementException e) {
      fail("Cannot locate user name link");
    }
  }
}
```

The “load” method in EditIssue now looks like:

```java
  @Override
  protected void load() {
    securedPage.get();

    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }
```

This shows that the components are all “nested” within each other. A call to `get()` in EditIssue will cause all its dependencies to load too. The example usage:

```java
public class FooTest {
  private EditIssue editIssue;

  @Before
  public void prepareComponents() {
    WebDriver driver = new FirefoxDriver();

    ProjectPage project = new ProjectPage(driver, "selenium");
    SecuredPage securedPage = new SecuredPage(driver, project, "example", "top secret");
    editIssue = new EditIssue(driver, securedPage);
  }

  @Test
  public void demonstrateNestedLoadableComponents() {
    editIssue.get();

    editIssue.title.sendKeys('Title');
    editIssue.body.sendKeys('What Happened');
    editIssue.setHowToReproduce('How to Reproduce');
    editIssue.setLogOutput('Log Output');
    editIssue.setOperatingSystem('Operating System');
    editIssue.setSeleniumVersion('Selenium Version');
    editIssue.setBrowserVersion('Browser Version');
    editIssue.setDriverVersion('Driver Version');
    editIssue.setUsingGrid('I Am Using Grid');
  }

}
```

If you’re using a library such as [Guiceberry](https://github.com/zorzella/guiceberry) in your tests, the preamble of setting up the PageObjects can be omitted leading to nice, clear, readable tests.

## Bot Pattern

(previously located: <https://github.com/SeleniumHQ/selenium/wiki/Bot-Style-Tests>)

Although PageObjects are a useful way of reducing duplication in your tests, it’s not always a pattern that teams feel comfortable following. An alternative approach is to follow a more “command-like” style of testing.

A “bot” is an action-oriented abstraction over the raw Selenium APIs. This means that if you find that commands aren’t doing the Right Thing for your app, it’s easy to change them. As an example:

```java
public class ActionBot {
  private final WebDriver driver;

  public ActionBot(WebDriver driver) {
    this.driver = driver;
  }

  public void click(By locator) {
    driver.findElement(locator).click();
  }

  public void submit(By locator) {
    driver.findElement(locator).submit();
  }

  /** 
   * Type something into an input field. WebDriver doesn't normally clear these
   * before typing, so this method does that first. It also sends a return key
   * to move the focus out of the element.
   */
  public void type(By locator, String text) { 
    WebElement element = driver.findElement(locator);
    element.clear();
    element.sendKeys(text + "\n");
  }
}
```

```py
import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L6-L26)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L28-L65)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L67-L80)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L82-L172)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L174-L240)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

Last modified May 6, 2025: [\[docs\]: fix build issues \[deploy site\] (7615cca5ebc)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/7615cca5ebc3a7681e9ec9e6cdb4b1ddd681ef00)

----
url: https://www.selenium.dev/documentation/webdriver/troubleshooting/
----

# Troubleshooting Assistance

How to solve WebDriver problems.

It is not always obvious the root cause of errors in Selenium.

1. The most common Selenium-related error is a result of poor synchronization. Read about [Waiting Strategies](https://www.selenium.dev/documentation/webdriver/waits/). If you aren’t sure if it is a synchronization strategy you can try *temporarily* hard coding a large sleep where you see the issue, and you’ll know if adding an explicit wait can help.

2. Note that many errors that get reported to the project are actually caused by issues in the underlying drivers that Selenium sends the commands to. You can rule out a driver problem by executing the command in multiple [browsers](https://www.selenium.dev/documentation/webdriver/browsers/).

3. If you have questions about how to do things, check out the [Support options](/support/) for ways get assistance.

4. If you think you’ve found a problem with Selenium code, go ahead and file a [Bug Report](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=I-defect%2Cneeds-triaging\&template=bug-report.yml\&title=%5B%F0%9F%90%9B+Bug%5D%3A+) on GitHub.

***

##### [Understanding Common Errors](/documentation/webdriver/troubleshooting/errors/)

How to solve various problems in your Selenium code.

##### [Logging Selenium commands](/documentation/webdriver/troubleshooting/logging/)

Getting information about Selenium execution.

##### [Upgrade to Selenium 4](/documentation/webdriver/troubleshooting/upgrade_to_selenium_4/)

Are you still using Selenium 3? This guide will help you upgrade to the latest release!

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/actions_api/pen/
----

# 触控笔操作

```java
        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/PenTest.java#L26-L33)

##### /examples/java/src/test/java/dev/selenium/actions\_api/PenTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PenTest extends BaseChromeTest {
    @Test
    public void usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();

        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    @Test
    public void setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();
        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("-72", moveBy.get("tiltX"));
        Assertions.assertEquals("9", moveBy.get("tiltY"));
        Assertions.assertEquals("86", moveBy.get("twist"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    private Map<String, String> getPropertyInfo(WebElement element) {
        String text = element.getText();
        text = text.substring(text.indexOf(' ') + 1);

        return Arrays.stream(text.split(", "))
                .map(s -> s.split(": "))
                .collect(Collectors.toMap(
                        a -> a[0],
                        a -> a[1]
                ));
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_pen.py#L12-L20)

##### /examples/python/tests/actions\_api/test\_pen.py

```py
import math

from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.interaction import POINTER_PEN
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.by import By


def test_use_pen(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def test_set_pointer_event_properties(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert move_by["tiltX"] == "-72"
    assert move_by["tiltY"] == "9"
    assert move_by["twist"] == "86"
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def properties(element):
    kv = element.text.split(' ', 1)[1].split(', ')
    return {x[0]:x[1] for x in list(map(lambda item: item.split(': '), kv))}
```

```cs
            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs#L19-L28)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class PenTest : BaseChromeTest
    {
        [TestMethod]
        public void UsePen()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        [TestMethod]
        public void SetPointerEventProperties()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual((-72).ToString(), moveBy["tiltX"]);
            Assert.AreEqual((9).ToString(), moveBy["tiltY"]);
            Assert.AreEqual((86).ToString(), moveBy["twist"]);
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        private Dictionary<string, string> getProperties(IWebElement element)
        {
            var str = element.Text;
            str = str[(str.Split()[0].Length + 1)..];
            IEnumerable<string[]> keyValue = str.Split(", ").Select(part => part.Split(":"));
            return keyValue.ToDictionary(split => split[0].Trim(), split => split[1].Trim());
        }

        private bool VerifyEquivalent(decimal expected, string actual)
        {
            var absolute = Math.Abs(expected - decimal.Parse(actual));
            if (absolute <= 1)
            {
                return true;
            }

            throw new Exception("Expected: " + expected + "; but received: " + actual);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/pen_spec.rb#L11-L17)

##### /examples/ruby/spec/actions\_api/pen\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Pen' do
  let(:driver) { start_session }

  it 'uses a pen' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  it 'sets pointer event attributes' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s,
                               'tiltX' => -72.to_s,
                               'tiltY' => 9.to_s,
                               'twist' => 86.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  def properties(element)
    element.text.sub(/.*?\s/, '').split(',').to_h { |item| item.lstrip.split(/\s*:\s*/) }
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/PenTest.kt#L23-L30)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/PenTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import kotlin.collections.Map
import java.time.Duration

class PenTest : BaseTest() {
  
    @Test
    fun usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
    }

    @Test
    fun setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY")) 
	    
        Assertions.assertEquals("-72", moveBy.get("tiltX"))
        Assertions.assertEquals("9", moveBy.get("tiltY"))
        Assertions.assertEquals("86", moveBy.get("twist"))
    }
    
    fun getPropertyInfo(element: WebElement): Map<String, String> {
        var text = element.getText()  
        text = text.substring(text.indexOf(" ")+1)
        return text.split(", ")
        .map { it.split(": ") }
        .map { it.first() to it.last() }
        .toMap() 
    }
}
```

```java
        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/PenTest.java#L67-L81)

##### /examples/java/src/test/java/dev/selenium/actions\_api/PenTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PenTest extends BaseChromeTest {
    @Test
    public void usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();

        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    @Test
    public void setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();
        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("-72", moveBy.get("tiltX"));
        Assertions.assertEquals("9", moveBy.get("tiltY"));
        Assertions.assertEquals("86", moveBy.get("twist"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    private Map<String, String> getPropertyInfo(WebElement element) {
        String text = element.getText();
        text = text.substring(text.indexOf(' ') + 1);

        return Arrays.stream(text.split(", "))
                .map(s -> s.split(": "))
                .collect(Collectors.toMap(
                        a -> a[0],
                        a -> a[1]
                ));
    }
}
```

```py
    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_pen.py#L53-L61)

##### /examples/python/tests/actions\_api/test\_pen.py

```py
import math

from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.interaction import POINTER_PEN
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.by import By


def test_use_pen(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def test_set_pointer_event_properties(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert move_by["tiltX"] == "-72"
    assert move_by["tiltY"] == "9"
    assert move_by["twist"] == "86"
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def properties(element):
    kv = element.text.split(' ', 1)[1].split(', ')
    return {x[0]:x[1] for x in list(map(lambda item: item.split(': '), kv))}
```

```cs
            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs#L64-L77)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class PenTest : BaseChromeTest
    {
        [TestMethod]
        public void UsePen()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        [TestMethod]
        public void SetPointerEventProperties()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual((-72).ToString(), moveBy["tiltX"]);
            Assert.AreEqual((9).ToString(), moveBy["tiltY"]);
            Assert.AreEqual((86).ToString(), moveBy["twist"]);
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        private Dictionary<string, string> getProperties(IWebElement element)
        {
            var str = element.Text;
            str = str[(str.Split()[0].Length + 1)..];
            IEnumerable<string[]> keyValue = str.Split(", ").Select(part => part.Split(":"));
            return keyValue.ToDictionary(split => split[0].Trim(), split => split[1].Trim());
        }

        private bool VerifyEquivalent(decimal expected, string actual)
        {
            var absolute = Math.Abs(expected - decimal.Parse(actual));
            if (absolute <= 1)
            {
                return true;
            }

            throw new Exception("Expected: " + expected + "; but received: " + actual);
        }
    }
}
```

```rb
    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/pen_spec.rb#L50-L56)

##### /examples/ruby/spec/actions\_api/pen\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Pen' do
  let(:driver) { start_session }

  it 'uses a pen' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  it 'sets pointer event attributes' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s,
                               'tiltX' => -72.to_s,
                               'tiltY' => 9.to_s,
                               'twist' => 86.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  def properties(element)
    element.text.sub(/.*?\s/, '').split(',').to_h { |item| item.lstrip.split(/\s*:\s*/) }
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/PenTest.kt#L64-L78)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/PenTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import kotlin.collections.Map
import java.time.Duration

class PenTest : BaseTest() {
  
    @Test
    fun usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
    }

    @Test
    fun setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY")) 
	    
        Assertions.assertEquals("-72", moveBy.get("tiltX"))
        Assertions.assertEquals("9", moveBy.get("tiltY"))
        Assertions.assertEquals("86", moveBy.get("twist"))
    }
    
    fun getPropertyInfo(element: WebElement): Map<String, String> {
        var text = element.getText()  
        text = text.substring(text.indexOf(" ")+1)
        return text.split(", ")
        .map { it.split(": ") }
        .map { it.first() to it.last() }
        .toMap() 
    }
}
```

----
url: https://www.selenium.dev/_print/documentation/webdriver/bidi/cdp/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/webdriver/bidi/cdp/).

# Chrome DevTools Protocol

Examples of working with Chrome DevTools Protocol in Selenium. CDP support is temporary until WebDriver BiDi has been implemented.

* 1: [Chrome DevTools Logging Features](#pg-23743e5a31d1a4e0ed6c0cff25393816)
* 2: [Chrome DevTools Network Features](#pg-88fd9485a3cbc3873b6527c6fb20d35b)
* 3: [Chrome DevTools Script Features](#pg-e8c55a02bb74b8b2b1a36a5a0a22e463)

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/CdpTest.java#L22-L27)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/CdpTest.java

```java
package dev.selenium.bidi.cdp;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chromium.HasCdp;

import java.util.HashMap;
import java.util.Map;

public class CdpTest extends BaseTest {
  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
  }

  @Test
  public void setCookie() {
    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);

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }
}
```

```py
    cookie = {'name': 'cheese',
              'value': 'gouda',
              'domain': 'www.selenium.dev',
              'secure': True}

    driver.execute_cdp_cmd('Network.setCookie', cookie)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_cdp.py#L2-L7)

##### /examples/python/tests/bidi/cdp/test\_cdp.py

```py
def test_set_cookie(driver):
    cookie = {'name': 'cheese',
              'value': 'gouda',
              'domain': 'www.selenium.dev',
              'secure': True}

    driver.execute_cdp_cmd('Network.setCookie', cookie)

    driver.get('https://www.selenium.dev')
    cheese = driver.get_cookie(cookie['name'])

    assert cheese['value'] == 'gouda'
```

```cs
            var cookie = new Dictionary<string, object>
            {
                { "name", "cheese" },
                { "value", "gouda" },
                { "domain", "www.selenium.dev" },
                { "secure", true }
            };
            ((ChromeDriver)driver).ExecuteCdpCommand("Network.setCookie", cookie);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/CDPTest.cs#L14-L21)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/CDPTest.cs

```cs
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class CDPTest : BaseChromeTest
    {
        [TestMethod]
        public void SetCookie()
        {
            var cookie = new Dictionary<string, object>
            {
                { "name", "cheese" },
                { "value", "gouda" },
                { "domain", "www.selenium.dev" },
                { "secure", true }
            };
            ((ChromeDriver)driver).ExecuteCdpCommand("Network.setCookie", cookie);
            
            driver.Url = "https://www.selenium.dev";
            Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);

        }
    }
}
```

```rb
    driver.execute_cdp('Network.setCookie',
                       name: 'cheese',
                       value: 'gouda',
                       domain: 'www.selenium.dev',
                       secure: true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/cdp_spec.rb#L9-L13)

##### /examples/ruby/spec/bidi/cdp/cdp\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'sets cookie' do
    driver.execute_cdp('Network.setCookie',
                       name: 'cheese',
                       value: 'gouda',
                       domain: 'www.selenium.dev',
                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end
end
```

# 1 - Chrome DevTools Logging Features

```java
    ((HasLogEvents) driver).onLogEvent(consoleEvent(e -> messages.add(e.getMessages().get(0))));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/LoggingTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/LoggingTest.java

```java
package dev.selenium.bidi.cdp;

import static org.openqa.selenium.devtools.events.CdpEventTypes.consoleEvent;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.CopyOnWriteArrayList;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.HasLogEvents;
import org.openqa.selenium.support.ui.WebDriverWait;

public class LoggingTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void consoleLogs() {
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    CopyOnWriteArrayList<String> messages = new CopyOnWriteArrayList<>();

    ((HasLogEvents) driver).onLogEvent(consoleEvent(e -> messages.add(e.getMessages().get(0))));

    driver.findElement(By.id("consoleLog")).click();
    driver.findElement(By.id("consoleError")).click();

    wait.until(_d -> messages.size() > 1);
    Assertions.assertTrue(messages.contains("Hello, world!"));
    Assertions.assertTrue(messages.contains("I am console error"));
  }
}
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_logs.py#L11-12)

##### /examples/python/tests/bidi/cdp/test\_logs.py

```py
import pytest
from selenium.webdriver.common.bidi.console import Console
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log


@pytest.mark.trio
async def test_console_log(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
            driver.find_element(by=By.ID, value='consoleLog').click()

        assert messages["message"] == "Hello, world!"


@pytest.mark.trio
async def test_js_error(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
            driver.find_element(by=By.ID, value='jsException').click()

        assert "Error: Not working" in messages.exception_details.exception.description
```

```cs
            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs#L19-L25)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class LoggingTest : BaseChromeTest
    {
        [TestMethod]
        public async Task ConsoleLogs()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("consoleLog")).Click();
            driver.FindElement(By.Id("consoleError")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => messages.Count > 1);
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Hello, world!"));
            Assert.IsTrue(messages.Contains("I am console error"));
        }
        
        [TestMethod]
        public async Task JsErrors()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("jsException")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !messages.IsNullOrEmpty());
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Uncaught"));
        }
    }
}
```

```rb
    driver.on_log_event(:console) { |log| logs << log.args.first }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/logging_spec.rb#L12)

##### /examples/ruby/spec/bidi/cdp/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'listens for console logs' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    logs = []
    driver.on_log_event(:console) { |log| logs << log.args.first }

    driver.find_element(id: 'consoleLog').click
    driver.find_element(id: 'consoleError').click

    Selenium::WebDriver::Wait.new.until { logs.size > 1 }
    expect(logs).to include 'Hello, world!'
    expect(logs).to include 'I am console error'
  end

  it 'listens for js exception' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    exceptions = []
    driver.on_log_event(:exception) { |exception| exceptions << exception }

    driver.find_element(id: 'jsException').click

    Selenium::WebDriver::Wait.new.until { exceptions.any? }
    expect(exceptions.first&.description).to include 'Error: Not working'
  end
end
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_logs.py#L22-L23)

##### /examples/python/tests/bidi/cdp/test\_logs.py

```py
import pytest
from selenium.webdriver.common.bidi.console import Console
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log


@pytest.mark.trio
async def test_console_log(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
            driver.find_element(by=By.ID, value='consoleLog').click()

        assert messages["message"] == "Hello, world!"


@pytest.mark.trio
async def test_js_error(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
            driver.find_element(by=By.ID, value='jsException').click()

        assert "Error: Not working" in messages.exception_details.exception.description
```

```cs
            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs#L41-L47)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class LoggingTest : BaseChromeTest
    {
        [TestMethod]
        public async Task ConsoleLogs()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("consoleLog")).Click();
            driver.FindElement(By.Id("consoleError")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => messages.Count > 1);
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Hello, world!"));
            Assert.IsTrue(messages.Contains("I am console error"));
        }
        
        [TestMethod]
        public async Task JsErrors()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("jsException")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !messages.IsNullOrEmpty());
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Uncaught"));
        }
    }
}
```

```rb
    driver.on_log_event(:exception) { |exception| exceptions << exception }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/logging_spec.rb#L26)

##### /examples/ruby/spec/bidi/cdp/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'listens for console logs' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    logs = []
    driver.on_log_event(:console) { |log| logs << log.args.first }

    driver.find_element(id: 'consoleLog').click
    driver.find_element(id: 'consoleError').click

    Selenium::WebDriver::Wait.new.until { logs.size > 1 }
    expect(logs).to include 'Hello, world!'
    expect(logs).to include 'I am console error'
  end

  it 'listens for js exception' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    exceptions = []
    driver.on_log_event(:exception) { |exception| exceptions << exception }

    driver.find_element(id: 'jsException').click

    Selenium::WebDriver::Wait.new.until { exceptions.any? }
    expect(exceptions.first&.description).to include 'Error: Not working'
  end
end
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Add Example](/documentation/about/contributing/#creating-examples)

# 2 - Chrome DevTools Network Features

```java
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L41-L43)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
        credentials = base64.b64encode("admin:admin".encode()).decode()
        auth = {'authorization': 'Basic ' + credentials}
        await connection.session.execute(connection.devtools.network.set_extra_http_headers(Headers(auth)))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L13-15)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L25-L32)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L9-L11)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      HttpResponse res = next.execute(req);
                      contentType.add(res.getHeader("Content-Type"));
                      return res;
                    })) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L56-L65)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L46-L51)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L20-L24)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    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!"))))) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L75-L85)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L62-L73)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L31-L35)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L97-L110)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L85-L97)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    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
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L42-L46)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L125-L126)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    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())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L26-L28)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L114-L118)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L56-L57)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    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()));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L142-L157)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L37-L44)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L136-L143)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L68-L71)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    devTools.send(
            Browser.setDownloadBehavior(
                    Browser.SetDownloadBehaviorBehavior.ALLOWANDNAME,
                    Optional.empty(),
                    Optional.of(""),
                    Optional.of(true)));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L171-L176)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    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
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L82-L88)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Add Example](/documentation/about/contributing/#creating-examples)

# 3 - Chrome DevTools Script Features

```java
    ScriptKey key = ((JavascriptExecutor) driver).pin("return arguments;");
    List<Object> arguments =
        (List<Object>) ((JavascriptExecutor) driver).executeScript(key, 1, true, element);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/ScriptTest.java#L32-L34)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/ScriptTest.java

```java
package dev.selenium.bidi.cdp;

import static org.openqa.selenium.devtools.events.CdpEventTypes.domMutation;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.HasLogEvents;
import org.openqa.selenium.support.ui.WebDriverWait;

public class ScriptTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void pinScript() {
    driver.get("https://www.selenium.dev/selenium/web/xhtmlTest.html");
    WebElement element = driver.findElement(By.id("id1"));

    ScriptKey key = ((JavascriptExecutor) driver).pin("return arguments;");
    List<Object> arguments =
        (List<Object>) ((JavascriptExecutor) driver).executeScript(key, 1, true, element);

    Assertions.assertEquals(List.of(1L, true, element), arguments);
  }

  @Test
  public void mutatedElements() {
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    CopyOnWriteArrayList<WebElement> mutations = new CopyOnWriteArrayList<>();

    ((HasLogEvents) driver).onLogEvent(domMutation(e -> mutations.add(e.getElement())));

    driver.findElement(By.id("reveal")).click();

    wait.until(_d -> !mutations.isEmpty());
    Assertions.assertEquals(mutations.get(0), driver.findElement(By.id("revealed")));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs#L21-L22)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs

```cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class ScriptTest : BaseChromeTest
    {
        [TestMethod]
        public async Task PinScript()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/xhtmlTest.html";
            var element = driver.FindElement(By.Id("id1"));

            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);

            var expected = new List<object>
            {
                1L,
                true,
                element
            };
            CollectionAssert.AreEqual(expected, (ICollection)arguments);
        }

        [TestMethod]
        public async Task MutatedElements()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            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();

            driver.FindElement(By.Id("reveal")).Click();
            
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !mutations.IsNullOrEmpty());
            await monitor.DisableDomMutationMonitoring();
            monitor.StopEventMonitoring();

            var revealed = driver.FindElement(By.Id("revealed")); 
            Assert.AreEqual(revealed, mutations[0]);
        }
    }
}
```

```rb
    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/script_spec.rb#L12-L13)

##### /examples/ruby/spec/bidi/cdp/script\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Script' do
  let(:driver) { start_session }

  it 'pins script' do
    driver.get('https://www.selenium.dev/selenium/web/xhtmlTest.html')
    element = driver.find_element(id: 'id1')

    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)

    expect(arguments).to eq([1, true, element])
  end

  it 'gets mutated elements' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'

    mutations = []
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }

    driver.find_element(id: 'reveal').click
    Selenium::WebDriver::Wait.new(timeout: 30).until { mutations.any? }

    expect(mutations).to include(driver.find_element(id: 'revealed'))
  end
end
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).mutation_events() as event:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_script.py#L10-L11)

##### /examples/python/tests/bidi/cdp/test\_script.py

```py
import pytest
import trio
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

@pytest.mark.trio
async def test_mutation(driver):
    async with driver.bidi_connection() as session:
        async with Log(driver, session).mutation_events() as event:
            await trio.to_thread.run_sync(lambda: driver.get('https://www.selenium.dev/selenium/web/dynamic.html'))
            await trio.to_thread.run_sync(lambda: WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "reveal"))))
            await trio.to_thread.run_sync(lambda: driver.find_element(By.ID, "reveal").click())

    assert event["element"] == driver.find_element(By.ID, "revealed")
```

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs#L39-L46)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs

```cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class ScriptTest : BaseChromeTest
    {
        [TestMethod]
        public async Task PinScript()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/xhtmlTest.html";
            var element = driver.FindElement(By.Id("id1"));

            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);

            var expected = new List<object>
            {
                1L,
                true,
                element
            };
            CollectionAssert.AreEqual(expected, (ICollection)arguments);
        }

        [TestMethod]
        public async Task MutatedElements()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            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();

            driver.FindElement(By.Id("reveal")).Click();
            
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !mutations.IsNullOrEmpty());
            await monitor.DisableDomMutationMonitoring();
            monitor.StopEventMonitoring();

            var revealed = driver.FindElement(By.Id("revealed")); 
            Assert.AreEqual(revealed, mutations[0]);
        }
    }
}
```

```rb
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/script_spec.rb#L22)

##### /examples/ruby/spec/bidi/cdp/script\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Script' do
  let(:driver) { start_session }

  it 'pins script' do
    driver.get('https://www.selenium.dev/selenium/web/xhtmlTest.html')
    element = driver.find_element(id: 'id1')

    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)

    expect(arguments).to eq([1, true, element])
  end

  it 'gets mutated elements' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'

    mutations = []
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }

    driver.find_element(id: 'reveal').click
    Selenium::WebDriver::Wait.new(timeout: 30).until { mutations.any? }

    expect(mutations).to include(driver.find_element(id: 'revealed'))
  end
end
```

----
url: https://www.selenium.dev/_print/documentation/webdriver/actions_api/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/webdriver/actions_api/).

# Actions API

A low-level interface for providing virtualized device input actions to the web browser.

* 1: [Keyboard actions](#pg-dd4d117a7dc045f660abe2500d849bfb)
* 2: [Mouse actions](#pg-b1f1561a91b017781f500f999dcd71de)
* 3: [Pen actions](#pg-511b2a7b9d3ea338fd6e6ab4fb140c4a)
* 4: [Scroll wheel actions](#pg-ad88d2376acee3525960ef3a11697a64)

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/ActionsTest.java#L21-L28)

##### /examples/java/src/test/java/dev/selenium/actions\_api/ActionsTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;

public class ActionsTest extends BaseChromeTest {
    @Test
    public void pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        long start = System.currentTimeMillis();

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();

        long duration = System.currentTimeMillis() - start;
        Assertions.assertTrue(duration > 2000);
        Assertions.assertTrue(duration < 3000);
    }

    @Test
    public void releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        Actions actions = new Actions(driver);
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        ((RemoteWebDriver) driver).resetInputState();

        actions.sendKeys("a").perform();
        Assertions.assertEquals("A", String.valueOf(clickable.getAttribute("value").charAt(0)));
        Assertions.assertEquals("a", String.valueOf(clickable.getAttribute("value").charAt(1)));
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_actions.py#L13-L20)

##### /examples/python/tests/actions\_api/test\_actions.py

```py
from time import time

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.by import By


def test_pauses(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    start = time()

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()

    duration = time() - start
    assert duration > 2
    assert duration < 3


def test_releases_all(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .click_and_hold(clickable)\
        .key_down(Keys.SHIFT)\
        .key_down("a")\
        .perform()

    ActionBuilder(driver).clear_actions()

    ActionChains(driver).key_down('a').perform()

    assert clickable.get_attribute('value')[0] == "A"
    assert clickable.get_attribute('value')[1] == "a"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs#L18-L25)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class ActionsTest : BaseChromeTest
    {
        [TestMethod]
        public void Pause()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            DateTime start = DateTime.Now;

            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();

            TimeSpan duration = DateTime.Now - start;
            Assert.IsTrue(duration > TimeSpan.FromSeconds(2));
            Assert.IsTrue(duration < TimeSpan.FromSeconds(3));
        }

        [TestMethod]
        public void ReleaseAll()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            var actions = new Actions(driver);
            actions.ClickAndHold(clickable)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            ((WebDriver)driver).ResetInputState();

            actions.SendKeys("a").Perform();
            var value = clickable.GetAttribute("value");
            Assert.AreEqual("A", value[..1]);
            Assert.AreEqual("a", value.Substring(1, 1));
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/actions_spec.rb#L12-L19)

##### /examples/ruby/spec/actions\_api/actions\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Actions' do
  let(:driver) { start_session }

  it 'pauses' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
    start = Time.now

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform

    duration = Time.now - start
    expect(duration).to be > 2
    expect(duration).to be < 3
  end

  it 'releases all' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    action = driver.action
                   .click_and_hold(clickable)
                   .key_down(:shift)
                   .key_down('a')
    action.perform

    driver.action.release_actions

    action.key_down('a').perform
    expect(clickable.attribute('value')[0]).to eq 'A'
    expect(clickable.attribute('value')[-1]).to eq 'a'
  end
end
```

```js
    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/actionsTest.spec.js#L18-L25)

##### /examples/javascript/test/actionsApi/actionsTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Pause and Release All Actions', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('Pause', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const start = Date.now()

    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()

    const end = Date.now() - start
    assert.ok(end > 2000)
    assert.ok(end < 4000)
  })

  it('Clear', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const clickable = driver.findElement(By.id('clickable'))
    await driver.actions()
      .click(clickable)
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    await driver.actions().clear()
    await driver.actions().sendKeys('a').perform()

    const value = await clickable.getAttribute('value')
    assert.deepStrictEqual('A', value.substring(0, 1))
    assert.deepStrictEqual('a', value.substring(1, 2))
  })
})
```

```kt
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/ActionsTest.kt#L22-L29)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/ActionsTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration

class ActionsTest : BaseTest() {

    @Test
    fun pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val start = System.currentTimeMillis()

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 

        val duration = System.currentTimeMillis() - start
        Assertions.assertTrue(duration > 2000)
        Assertions.assertTrue(duration < 4000)
    }

    @Test
    fun releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        val actions = Actions(driver)
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        (driver as RemoteWebDriver).resetInputState()

        actions.sendKeys("a").perform()
        Assertions.assertEquals("A", clickable.getAttribute("value")!!.get(0).toString())
        Assertions.assertEquals("a", clickable.getAttribute("value")!!.get(1).toString())
    }
}
```

```java
        ((RemoteWebDriver) driver).resetInputState();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/ActionsTest.java#L46)

##### /examples/java/src/test/java/dev/selenium/actions\_api/ActionsTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;

public class ActionsTest extends BaseChromeTest {
    @Test
    public void pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        long start = System.currentTimeMillis();

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();

        long duration = System.currentTimeMillis() - start;
        Assertions.assertTrue(duration > 2000);
        Assertions.assertTrue(duration < 3000);
    }

    @Test
    public void releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        Actions actions = new Actions(driver);
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        ((RemoteWebDriver) driver).resetInputState();

        actions.sendKeys("a").perform();
        Assertions.assertEquals("A", String.valueOf(clickable.getAttribute("value").charAt(0)));
        Assertions.assertEquals("a", String.valueOf(clickable.getAttribute("value").charAt(1)));
    }
}
```

```py
    ActionBuilder(driver).clear_actions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_actions.py#L37)

##### /examples/python/tests/actions\_api/test\_actions.py

```py
from time import time

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.by import By


def test_pauses(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    start = time()

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()

    duration = time() - start
    assert duration > 2
    assert duration < 3


def test_releases_all(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .click_and_hold(clickable)\
        .key_down(Keys.SHIFT)\
        .key_down("a")\
        .perform()

    ActionBuilder(driver).clear_actions()

    ActionChains(driver).key_down('a').perform()

    assert clickable.get_attribute('value')[0] == "A"
    assert clickable.get_attribute('value')[1] == "a"
```

```cs
            ((WebDriver)driver).ResetInputState();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs#L44)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class ActionsTest : BaseChromeTest
    {
        [TestMethod]
        public void Pause()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            DateTime start = DateTime.Now;

            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();

            TimeSpan duration = DateTime.Now - start;
            Assert.IsTrue(duration > TimeSpan.FromSeconds(2));
            Assert.IsTrue(duration < TimeSpan.FromSeconds(3));
        }

        [TestMethod]
        public void ReleaseAll()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            var actions = new Actions(driver);
            actions.ClickAndHold(clickable)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            ((WebDriver)driver).ResetInputState();

            actions.SendKeys("a").Perform();
            var value = clickable.GetAttribute("value");
            Assert.AreEqual("A", value[..1]);
            Assert.AreEqual("a", value.Substring(1, 1));
        }
    }
}
```

```rb
    driver.action.release_actions
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/actions_spec.rb#L36)

##### /examples/ruby/spec/actions\_api/actions\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Actions' do
  let(:driver) { start_session }

  it 'pauses' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
    start = Time.now

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform

    duration = Time.now - start
    expect(duration).to be > 2
    expect(duration).to be < 3
  end

  it 'releases all' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    action = driver.action
                   .click_and_hold(clickable)
                   .key_down(:shift)
                   .key_down('a')
    action.perform

    driver.action.release_actions

    action.key_down('a').perform
    expect(clickable.attribute('value')[0]).to eq 'A'
    expect(clickable.attribute('value')[-1]).to eq 'a'
  end
end
```

```js
    await driver.actions().clear()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/actionsTest.spec.js#L42)

##### /examples/javascript/test/actionsApi/actionsTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Pause and Release All Actions', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('Pause', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const start = Date.now()

    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()

    const end = Date.now() - start
    assert.ok(end > 2000)
    assert.ok(end < 4000)
  })

  it('Clear', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const clickable = driver.findElement(By.id('clickable'))
    await driver.actions()
      .click(clickable)
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    await driver.actions().clear()
    await driver.actions().sendKeys('a').perform()

    const value = await clickable.getAttribute('value')
    assert.deepStrictEqual('A', value.substring(0, 1))
    assert.deepStrictEqual('a', value.substring(1, 2))
  })
})
```

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/ActionsTest.kt#L47)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/ActionsTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration

class ActionsTest : BaseTest() {

    @Test
    fun pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val start = System.currentTimeMillis()

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 

        val duration = System.currentTimeMillis() - start
        Assertions.assertTrue(duration > 2000)
        Assertions.assertTrue(duration < 4000)
    }

    @Test
    fun releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        val actions = Actions(driver)
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        (driver as RemoteWebDriver).resetInputState()

        actions.sendKeys("a").perform()
        Assertions.assertEquals("A", clickable.getAttribute("value")!!.get(0).toString())
        Assertions.assertEquals("a", clickable.getAttribute("value")!!.get(1).toString())
    }
}
```

# 1 - Keyboard actions

```java
        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L17-L20)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L10-L13)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L13-L16)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L17-L20)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L19-L22)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L30-L35)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L21-L26)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L30-L35)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L25-L30)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L32-L37)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L32-L37)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .sendKeys("abc")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L45-L47)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L34-L36)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs

            new Actions(driver)
                .SendKeys("abc")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L45-L47)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .send_keys('abc')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L39-L41)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .sendKeys('abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L48-L50)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .sendKeys("abc")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L47-L49)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L59-L62)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L45-L48)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L58-L61)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L51-L54)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L59-L63)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L60-L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L70-L84)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L56-L67)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L72-L82)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L64-L74)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L73-L85)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L74-L86)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L22-L25)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L14-L17)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L11-L14)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    let clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.move({origin: clickable}).press().perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/clickAndHold.spec.js#L14-L16)

##### /examples/javascript/test/actionsApi/mouse/clickAndHold.spec.js

```js
const {By, Builder} = require('selenium-webdriver');

describe('Click and hold', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and mouseDown on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    let clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.move({origin: clickable}).press().perform();
  });
});
```

```kt
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L23-L26)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L34-L37)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L26-L29)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L30-L33)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L22-L25)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    let click = driver.findElement(By.id("click"));
    const actions = driver.actions({async: true});
    await actions.move({origin: click}).click().perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/clickAndRelease.spec.js#L14-L16)

##### /examples/javascript/test/actionsApi/mouse/clickAndRelease.spec.js

```js
const {By,Builder} = require('selenium-webdriver');

describe('Click and release', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    let click = driver.findElement(By.id("click"));
    const actions = driver.actions({async: true});
    await actions.move({origin: click}).click().perform();
  });
});
```

```kt
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L35-L38)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L46-L49)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L37-L40)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L43-L46)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L34-L37)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.contextClick(clickable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/rightClick.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/rightClick.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Right click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and right click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.contextClick(clickable).perform();

    await driver.sleep(500);
    const clicked = await driver.findElement(By.id('click-status')).getText();
    assert.deepStrictEqual(clicked, `context-clicked`)
  });
});
```

```kt
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L47-L50)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L60-L66)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L51-L54)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L59-L63)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L47-L50)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js#L19-L20)

##### /examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js

```js
const {By, Button, Browser, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Should be able to perform BACK click and FORWARD click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Back click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)

    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)
  });

  it('Forward click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();
    await driver.navigate().back();

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)

    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L61-L67)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L78-L84)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L65-L68)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L77-L81)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L61-L64)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js#L32-L33)

##### /examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js

```js
const {By, Button, Browser, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Should be able to perform BACK click and FORWARD click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Back click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)

    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)
  });

  it('Forward click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();
    await driver.navigate().back();

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)

    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L79-L85)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L93-L96)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L76-L79)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L91-L94)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L73-L76)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.doubleClick(clickable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/doubleClick.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/doubleClick.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Double click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Double-click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.doubleClick(clickable).perform();

    await driver.sleep(500);
    const status = await driver.findElement(By.id('click-status')).getText();
    assert.deepStrictEqual(status, `double-clicked`)
  });
});
```

```kt
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L94-L97)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L105-L108)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L87-L90)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L104-L107)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L84-L87)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const hoverable = driver.findElement(By.id("hover"));
    const actions = driver.actions({async: true});
    await actions.move({origin: hoverable}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveToElement.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/moveToElement.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Move to element', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move into an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const hoverable = driver.findElement(By.id("hover"));
    const actions = driver.actions({async: true});
    await actions.move({origin: hoverable}).perform();

    const status = await driver.findElement(By.id('move-status')).getText();
    assert.deepStrictEqual(status, `hovered`)
  });
});
```

```kt
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L106-L109)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L118-L121)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L98-L101)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L132-L135)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L97-L100)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L119-L122)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L131-L136)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L110-L112)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L146-L150)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      driver.action
            .move_to_location(8, 12)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L114-L116)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L27-L28)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L132-L137)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L153-L155)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L126-L128)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L167-L169)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      driver.action
            .move_by(13, 15)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L128-L130)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L40)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L154-L156)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L166-L170)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L139-L143)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L181-L185)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L141-L145)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js#L27-L30)

##### /examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Drag and Drop', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('By Offset', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });

  it('Onto Element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });
});
```

```kt
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L167-L171)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L179-L184)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L151-L156)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L195-L200)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L153-L158)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js#L15-L19)

##### /examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Drag and Drop', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('By Offset', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });

  it('Onto Element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });
});
```

```kt
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L180-L185)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/PenTest.java#L26-L33)

##### /examples/java/src/test/java/dev/selenium/actions\_api/PenTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PenTest extends BaseChromeTest {
    @Test
    public void usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();

        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    @Test
    public void setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();
        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("-72", moveBy.get("tiltX"));
        Assertions.assertEquals("9", moveBy.get("tiltY"));
        Assertions.assertEquals("86", moveBy.get("twist"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    private Map<String, String> getPropertyInfo(WebElement element) {
        String text = element.getText();
        text = text.substring(text.indexOf(' ') + 1);

        return Arrays.stream(text.split(", "))
                .map(s -> s.split(": "))
                .collect(Collectors.toMap(
                        a -> a[0],
                        a -> a[1]
                ));
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_pen.py#L12-L20)

##### /examples/python/tests/actions\_api/test\_pen.py

```py
import math

from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.interaction import POINTER_PEN
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.by import By


def test_use_pen(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def test_set_pointer_event_properties(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert move_by["tiltX"] == "-72"
    assert move_by["tiltY"] == "9"
    assert move_by["twist"] == "86"
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def properties(element):
    kv = element.text.split(' ', 1)[1].split(', ')
    return {x[0]:x[1] for x in list(map(lambda item: item.split(': '), kv))}
```

```cs
            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs#L19-L28)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class PenTest : BaseChromeTest
    {
        [TestMethod]
        public void UsePen()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        [TestMethod]
        public void SetPointerEventProperties()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual((-72).ToString(), moveBy["tiltX"]);
            Assert.AreEqual((9).ToString(), moveBy["tiltY"]);
            Assert.AreEqual((86).ToString(), moveBy["twist"]);
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        private Dictionary<string, string> getProperties(IWebElement element)
        {
            var str = element.Text;
            str = str[(str.Split()[0].Length + 1)..];
            IEnumerable<string[]> keyValue = str.Split(", ").Select(part => part.Split(":"));
            return keyValue.ToDictionary(split => split[0].Trim(), split => split[1].Trim());
        }

        private bool VerifyEquivalent(decimal expected, string actual)
        {
            var absolute = Math.Abs(expected - decimal.Parse(actual));
            if (absolute <= 1)
            {
                return true;
            }

            throw new Exception("Expected: " + expected + "; but received: " + actual);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/pen_spec.rb#L11-L17)

##### /examples/ruby/spec/actions\_api/pen\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Pen' do
  let(:driver) { start_session }

  it 'uses a pen' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  it 'sets pointer event attributes' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s,
                               'tiltX' => -72.to_s,
                               'tiltY' => 9.to_s,
                               'twist' => 86.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  def properties(element)
    element.text.sub(/.*?\s/, '').split(',').to_h { |item| item.lstrip.split(/\s*:\s*/) }
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/PenTest.kt#L23-L30)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/PenTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import kotlin.collections.Map
import java.time.Duration

class PenTest : BaseTest() {
  
    @Test
    fun usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
    }

    @Test
    fun setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY")) 
	    
        Assertions.assertEquals("-72", moveBy.get("tiltX"))
        Assertions.assertEquals("9", moveBy.get("tiltY"))
        Assertions.assertEquals("86", moveBy.get("twist"))
    }
    
    fun getPropertyInfo(element: WebElement): Map<String, String> {
        var text = element.getText()  
        text = text.substring(text.indexOf(" ")+1)
        return text.split(", ")
        .map { it.split(": ") }
        .map { it.first() to it.last() }
        .toMap() 
    }
}
```

```java
        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/PenTest.java#L67-L81)

##### /examples/java/src/test/java/dev/selenium/actions\_api/PenTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PenTest extends BaseChromeTest {
    @Test
    public void usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();

        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    @Test
    public void setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();
        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("-72", moveBy.get("tiltX"));
        Assertions.assertEquals("9", moveBy.get("tiltY"));
        Assertions.assertEquals("86", moveBy.get("twist"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    private Map<String, String> getPropertyInfo(WebElement element) {
        String text = element.getText();
        text = text.substring(text.indexOf(' ') + 1);

        return Arrays.stream(text.split(", "))
                .map(s -> s.split(": "))
                .collect(Collectors.toMap(
                        a -> a[0],
                        a -> a[1]
                ));
    }
}
```

```py
    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_pen.py#L53-L61)

##### /examples/python/tests/actions\_api/test\_pen.py

```py
import math

from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.interaction import POINTER_PEN
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.by import By


def test_use_pen(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def test_set_pointer_event_properties(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert move_by["tiltX"] == "-72"
    assert move_by["tiltY"] == "9"
    assert move_by["twist"] == "86"
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def properties(element):
    kv = element.text.split(' ', 1)[1].split(', ')
    return {x[0]:x[1] for x in list(map(lambda item: item.split(': '), kv))}
```

```cs
            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs#L64-L77)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class PenTest : BaseChromeTest
    {
        [TestMethod]
        public void UsePen()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        [TestMethod]
        public void SetPointerEventProperties()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual((-72).ToString(), moveBy["tiltX"]);
            Assert.AreEqual((9).ToString(), moveBy["tiltY"]);
            Assert.AreEqual((86).ToString(), moveBy["twist"]);
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        private Dictionary<string, string> getProperties(IWebElement element)
        {
            var str = element.Text;
            str = str[(str.Split()[0].Length + 1)..];
            IEnumerable<string[]> keyValue = str.Split(", ").Select(part => part.Split(":"));
            return keyValue.ToDictionary(split => split[0].Trim(), split => split[1].Trim());
        }

        private bool VerifyEquivalent(decimal expected, string actual)
        {
            var absolute = Math.Abs(expected - decimal.Parse(actual));
            if (absolute <= 1)
            {
                return true;
            }

            throw new Exception("Expected: " + expected + "; but received: " + actual);
        }
    }
}
```

```rb
    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/pen_spec.rb#L50-L56)

##### /examples/ruby/spec/actions\_api/pen\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Pen' do
  let(:driver) { start_session }

  it 'uses a pen' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  it 'sets pointer event attributes' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s,
                               'tiltX' => -72.to_s,
                               'tiltY' => 9.to_s,
                               'twist' => 86.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  def properties(element)
    element.text.sub(/.*?\s/, '').split(',').to_h { |item| item.lstrip.split(/\s*:\s*/) }
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/PenTest.kt#L64-L78)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/PenTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import kotlin.collections.Map
import java.time.Duration

class PenTest : BaseTest() {
  
    @Test
    fun usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
    }

    @Test
    fun setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY")) 
	    
        Assertions.assertEquals("-72", moveBy.get("tiltX"))
        Assertions.assertEquals("9", moveBy.get("tiltY"))
        Assertions.assertEquals("86", moveBy.get("twist"))
    }
    
    fun getPropertyInfo(element: WebElement): Map<String, String> {
        var text = element.getText()  
        text = text.substring(text.indexOf(" ")+1)
        return text.split(", ")
        .map { it.split(": ") }
        .map { it.first() to it.last() }
        .toMap() 
    }
}
```

```java
        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L17-L20)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L11-L14)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L11-L14)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L16-L19)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L18-L21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L29-L33)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L22-L26)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L31-L35)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L22-L26)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L26-L31)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L30-L34)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L42-L46)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L35-L39)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L46-L53)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L34-L38)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L40-L44)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L43-L47)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L57-L61)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L50-L54)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L66-L75)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L48-L52)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L57-L61)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L59-L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L73-L76)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L66-L70)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L89-L97)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L63-L66)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L75-L77)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L75-L78)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

----
url: https://www.selenium.dev/_print/documentation/legacy/selenium_3/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/legacy/selenium_3/).

# Selenium 3

Selenium 3 was the implementation of WebDriver without the Selenium RC Code. It has since been replaced with Selenium 4, which implements the W3C WebDriver specification.

* 1: [Grid 3](#pg-6b86dc079f63c200ff9d293cde398616)
* 2: [Setting up your own Grid 3](#pg-51d2482692e825414d0ffd833835614e)
* 3: [Components of Grid 3](#pg-88001777a96888486f97550f11bcb985)

# 1 - Grid 3

Selenium Grid 3 supported WebDriver without Selenium RC code. Grid 3 was completely rewritten for the new Grid 4.

You can read our documentation for more information about [Grid 4](https://www.selenium.dev/documentation/grid/)

*Selenium Grid* is a smart proxy server that allows Selenium tests to route commands to remote web browser instances. Its aim is to provide an easy way to run tests in parallel on multiple machines.

With Selenium Grid, one server acts as the hub that routes JSON formatted test commands to one or more registered Grid nodes. Tests contact the hub to obtain access to remote browser instances. The hub has a list of registered servers that it provides access to, and allows control of these instances.

Selenium Grid allows us to run tests in parallel on multiple machines, and to manage different browser versions and browser configurations centrally (instead of in each individual test).

Selenium Grid is not a silver bullet. It solves a subset of common delegation and distribution problems, but will for example not manage your infrastructure, and might not suit your specific needs.

# 2 - Setting up your own Grid 3

```shell
java -jar selenium-server-standalone.jar -role hub
```

The Hub will listen to port 4444 by default. You can view the status of the hub by opening a browser window and navigating to <http://localhost:4444/grid/console>.

To change the default port, you can add the optional `-port` flag with an integer representing the port to listen to when you run the command. Also, all of the other options you see in the JSON config file (seen below) are possible command-line flags.

You certainly can get by with only the simple command shown above, but if you need more advanced configuration, you can also specify a JSON format config file, for convenience, to configure the hub when you start it. You can do it like so:

```shell
java -jar selenium-server-standalone.jar -role hub -hubConfig hubConfig.json -debug
```

Below you will see an example of a `hubConfig.json` file. We will go into more detail on how to provide node configuration files in step 2.

```json
{
  "_comment" : "Configuration for Hub - hubConfig.json",
  "host": ip,
  "maxSession": 5,
  "port": 4444,
  "cleanupCycle": 5000,
  "timeout": 300000,
  "newSessionWaitTimeout": -1,
  "servlets": [],
  "prioritizer": null,
  "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
  "throwOnCapabilityNotPresent": true,
  "nodePolling": 180000,
  "platform": "WINDOWS"}
```

### Step 2: Start the Nodes

Regardless of whether you want to run a grid with new WebDriver functionality, or a grid with Selenium 1 RC functionality, or both at the same time, you use the same `selenium-server-standalone.jar` file to start the nodes:

```shell
java -jar selenium-server-standalone.jar -role node -hub http://localhost:4444
```

```shell
java -Dwebdriver.chrome.driver=chromedriver.exe -jar selenium-server-standalone.jar -role node -nodeConfig node1Config.json
```

And here is an example of a `nodeConfig.json` file:

```json
{
  "capabilities": [
    {
      "browserName": "firefox",
      "acceptSslCerts": true,
      "javascriptEnabled": true,
      "takesScreenshot": false,
      "firefox_profile": "",
      "browser-version": "27",
      "platform": "WINDOWS",
      "maxInstances": 5,
      "firefox_binary": "",
      "cleanSession": true
    },
    {
      "browserName": "chrome",
      "maxInstances": 5,
      "platform": "WINDOWS",
      "webdriver.chrome.driver": "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"
    },
    {
      "browserName": "internet explorer",
      "maxInstances": 1,
      "platform": "WINDOWS",
      "webdriver.ie.driver": "C:/Program Files (x86)/Internet Explorer/iexplore.exe"
    }
  ],
  "configuration": {
    "_comment" : "Configuration for Node",
    "cleanUpCycle": 2000,
    "timeout": 30000,
    "proxy": "org.openqa.grid.selenium.proxy.WebDriverRemoteProxy",
    "port": 5555,
    "host": ip,
    "register": true,
    "hubPort": 4444,
    "maxSession": 5
  }
}
```

```shell
java -jar selenium-server-standalone.jar -role hub -log log.txt
```

Use your favorite text editor to open log file (log.txt in the example above) to find “ERROR” logs if you get issues.

### Using `-debug` argument

Also you can use `-debug` argument to print debug logs to console. Start Selenium Grid Hub or Node with `-debug` argument. Please see the below example:

```shell
java -jar selenium-server-standalone.jar -role hub -debug
```

# 3 - Components of Grid 3

----
url: https://www.selenium.dev/documentation/test_practices/discouraged/gmail_email_and_facebook_logins/
----

# Gmail, email and Facebook logins

For multiple reasons, logging into sites like Gmail and Facebook using WebDriver is not recommended. Aside from being against the usage terms for these sites (where you risk having the account shut down), it is slow and unreliable.

The ideal practice is to use the APIs that email providers offer, or in the case of Facebook the developer tools service which exposes an API for creating test accounts, friends and so forth. Although using an API might seem like a bit of extra hard work, you will be paid back in speed, reliability, and stability. The API is also unlikely to change, whereas webpages and HTML locators change often and require you to update your test framework.

Logging in to third party sites using WebDriver at any point of your test increases the risk of your test failing because it makes your test longer. A general rule of thumb is that longer tests are more fragile and unreliable.

WebDriver implementations that are [W3C conformant](//w3c.github.io/webdriver/webdriver-spec.html) also annotate the `navigator` object with a `WebDriver` property so that Denial of Service attacks can be mitigated.

----
url: https://www.selenium.dev/ja/documentation/grid/advanced_features/graphql_support/
----

# GraphQLクエリのサポート

```shell
{
    session(id: "<session-id>") : {
        id,
        capabilities,
        startTime,
        uri,
        nodeId,
        nodeUri,
        sessionDurationMillis
        slot : {
            id,
            stereotype,
            lastStarted
        }
    }
    grid: {
        uri,
        totalSlots,
        nodeCount,
        maxSession,
        sessionCount,
        version,
        sessionQueueSize
    }
    sessionsInfo: {
        sessionQueueRequests,
        sessions: [
            {
                id,
                capabilities,
                startTime,
                uri,
                nodeId,
                nodeUri,
                sessionDurationMillis
                slot : {
                    id,
                    stereotype,
                    lastStarted
                }
            }
        ]
    }
    nodesInfo: {
        nodes : [
            {
                id,
                uri,
                status,
                maxSession,
                slotCount,
                sessions: [
                    {
                        id,
                        capabilities,
                        startTime,
                        uri,
                        nodeId,
                        nodeUri,
                        sessionDurationMillis
                        slot : {
                            id,
                            stereotype,
                            lastStarted
                        }
                    }
                ],
                sessionCount,
                stereotypes,
                version,
                osInfo: {
                    arch,
                    name,
                    version
                }
            }
        ]
    }
}
```

## GraphQLで照会する

GraphQLをクエリする最良の方法は、 `curl` リクエストを使用することです。 GraphQLを使用すると、必要なデータのみをフェッチできます。それ以上でもそれ以下でもありません。

GraphQLクエリの例のいくつかを以下に示します。 必要に応じて独自のクエリを作成できます。

### グリッド内の `maxSession`と` sessionCount`の数を照会する

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ grid { maxSession, sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

通常、ローカルマシンでは、 `<LINK_TO_GRAPHQL_ENDPOINT>` は `http://localhost:4444/graphql` になります。

### セッション、ノード、グリッドのすべての詳細を照会する

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { uri, maxSession, sessionCount }, nodesInfo { nodes { id, uri, status, sessions { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } }, slotCount, sessionCount }} }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### グリッドで現在のセッション数を取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### グリッドで最大セッション数を取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { maxSession } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### グリッド内のすべてのノードのすべてのセッションの詳細を取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, capabilities, startTime, uri, nodeId, nodeId, sessionDurationMillis } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### グリッド内の各ノードのすべてのセッションのスロット情報を取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, slot { id, stereotype, lastStarted } } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 特定のセッションのセッション情報を取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ session (id: \"<session-id>\") { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } } } "}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### グリッド内の各ノードのcapabilityを照会する

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { stereotypes } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### グリッド内の各ノードのステータスを照会する

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { status } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 各ノードとグリッドのURIを照会する

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { uri } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 新しいセッションキューで現在のリクエストを取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessionQueueRequests } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 新しいセッションキューのサイズを取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionQueueSize } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

最終更新 January 24, 2022: [Properly parse quotes for GraphQl query's session id (#941) \[deploy site\] (548fa83a491)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/548fa83a491330341485e5667d5053743f8e313c)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/getting_started/using_selenium/
----

# Organizando e executando o código Selenium

Escalonamento da execução do Selenium com um IDE e uma biblioteca do Test Runner

Se quiser executar mais do que um punhado de scripts pontuais, precisa de ser capaz de organizar e trabalhar com seu código. Esta página deve dar a você ideias de como fazer coisas produtivas com seu código Selenium.

## Usos comuns

A maioria das pessoas usa o Selenium para executar testes automatizados para aplicações web, mas o Selenium suporta qualquer caso de uso de automação de navegador.

### Tarefas Repetitivas

Talvez seja necessário fazer login em um site e baixar algo ou enviar um formulário. Você pode criar um script Selenium para ser executado com um serviço em horários pré-definidos.

### Web Scrapping

Está a tentar recolher dados de um site que não tem uma API? O Selenium permitirá que você faça isso, mas certifique-se de estar familiarizado com os termos de serviço do site termos de serviço do site, pois alguns sites não permitem isso e outros até bloqueiam o Selenium.

### Testes

Executar o Selenium para testes requer fazer asserções sobre as ações tomadas pelo Selenium. Então uma boa biblioteca de asserções é necessária. Características adicionais para prover estrutura para testes requerem o uso de [Executador de teste](/pt-br/documentation/webdriver/getting_started/using_selenium/#executador-de-teste).

## IDEs

Independentemente de como você usa o código do Selenium, não será muito eficaz escrevendo ou executando-o sem um bom ambiente de desenvolvimento integrado. Aqui estão algumas opções comuns…

* [Eclipse](https://www.eclipse.org/)
* [IntelliJ IDEA](https://www.jetbrains.com/idea/)
* [PyCharm](https://www.jetbrains.com/pycharm/)
* [RubyMine](https://www.jetbrains.com/ruby/)
* [Rider](https://www.jetbrains.com/rider/)
* [WebStorm](https://www.jetbrains.com/webstorm/)
* [VS Code](https://code.visualstudio.com/)

## Executador de teste

Mesmo que não esteja a usar o Selenium para testes, se tiver casos de uso avançado, pode fazer sentido usar um executor de testes para organizar melhor seu código. Ser capaz de usar hooks antes/depois e executar coisas em grupos ou em paralelo pode ser muito útil.

### Escolhendo

Há muitos executores de teste diferentes disponíveis.

Todos os exemplos de código nesta documentação podem ser encontrados em (ou estão sendo movidos para) nossos diretórios que usam test runners e são executados a cada lançamento para garantir que todo o código esteja correto e atualizado. Aqui está uma lista de executores de teste com links. O primeiro item é o que é usado por este repositório e o que que será usado para todos os exemplos nesta página.

*
*
*
*
*
*

- [JUnit](https://junit.org/junit5/) - Uma estrutura de teste amplamente utilizada para testes Selenium baseados em Java.
- [TestNG](https://testng.org/) - Oferece recursos extras, como execução de testes paralelos e testes parametrizados.

* [pytest](https://pytest.org/) -Uma escolha preferida por muitos, graças à sua simplicidade e aos seus poderosos plugins.
* [unittest](https://docs.python.org/3/library/unittest.html) - A estrutura de testes da biblioteca padrão do Python.

- [NUnit](https://nunit.org/) - Um popular framework de teste unitário para .NET.
- [MS Test](https://docs.microsoft.com/en-us/visualstudio/test/getting-started-with-unit-testing?view=vs-2019) - O Framework de testes unitários da Microsoft.

* [RSpec](https://rspec.info/) - A biblioteca de testes mais utilizada para executar testes Selenium em Ruby.
* [Minitest](https://github.com/seattlerb/minitest) - Um framework de testes leve que vem com a biblioteca padrão do Ruby.

- [Jest](https://jestjs.io/) - Principalmente conhecido como um framework de teste para React, também pode ser utilizado para testes Selenium.
- [Mocha](https://mochajs.org/) - A biblioteca JS mais comum para executar testes Selenium.

* [Kotest](https://kotest.io/) - Uma estrutura de testes flexível e abrangente, projetada especificamente para Kotlin.
* [JUnit5](https://junit.org/junit5/) - A estrutura de testes padrão do Java, totalmente compatível com Kotlin.

### Instalando

Isto é muito semelhante ao que foi requerido em [Install a Selenium Library](https://www.selenium.dev/pt-br/documentation/webdriver/getting_started/install_library/). Este código está apenas a mostrar exemplos do que está a ser usado no nosso projeto de Exemplos de Documentação.

Para usá-lo em um projeto, adicione-o ao arquivo `requirements.txt`:

in the project’s `csproj` especifique a dependência como `PackageReference` em `ItemGroup`:

Add to project’s gemfile

In your project’s `package.json`, adicionar requisito às `dependências`:

### Afirmar

*
*
*
*
*
*

```java
		String title = driver.getTitle();
		assertEquals("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L30-L31)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java
package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

```py
    title = driver.title
    assert title == "Web form"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L8-L9)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

```cs
            var title = driver.Title;
            Assert.AreEqual("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs#L19-L20)

##### /examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted
{
    [TestClass]
    public class UsingSeleniumTest
    {

        [TestMethod]
        public void EightComponents()
        {
            IWebDriver driver = new ChromeDriver();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

            var title = driver.Title;
            Assert.AreEqual("Web form", title);

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            var textBox = driver.FindElement(By.Name("my-text"));
            var submitButton = driver.FindElement(By.TagName("button"));
            
            textBox.SendKeys("Selenium");
            submitButton.Click();
            
            var message = driver.FindElement(By.Id("message"));
            var value = message.Text;
            Assert.AreEqual("Received!", value);
            
            driver.Quit();
        }
    }
}
```

```rb
    title = @driver.title
    expect(title).to eq('Web form')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb#L14-L15)

##### /examples/ruby/spec/getting\_started/using\_selenium\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

```js
    let title = await driver.getTitle();
    assert.equal("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L14-L15)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

```kt
        val title = driver.title
        assertEquals("Web form", title)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L20-21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

### Configuarar e Desconfigurar

```java
	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L19-L22)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java
package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

### Tear Down

```java
	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L45-L48)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java
package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

### Set Up

```py
def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L25-L28)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

### Tear Down

```py
def teardown(driver):
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L30-31)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

### Set Up

```rb
  before do
    @driver = Selenium::WebDriver.for :chrome
  end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb#L7-L9)

##### /examples/ruby/spec/getting\_started/using\_selenium\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

### Tear Down

```rb
  config.after { @driver&.quit }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/spec_helper.rb#L30)

##### /examples/ruby/spec/spec\_helper.rb

```rb
# frozen_string_literal: true

require 'selenium-webdriver'
require 'selenium/webdriver/support/guards'

RSpec.configure do |config|
  # Enable flags like --only-failures and --next-failure
  config.example_status_persistence_file_path = '.rspec_status'

  # Disable RSpec exposing methods globally on `Module` and `main`
  config.disable_monkey_patching!
  Dir.mktmpdir('tmp')
  config.example_status_persistence_file_path = 'tmp/examples.txt'

  config.expect_with :rspec do |c|
    c.syntax = :expect
  end

  config.before do |example|
    bug_tracker = 'https://github.com/SeleniumHQ/seleniumhq.github.io/issues'
    guards = Selenium::WebDriver::Support::Guards.new(example,
                                                      bug_tracker: bug_tracker)
    guards.add_condition(:platform, Selenium::WebDriver::Platform.os)
    guards.add_condition(:ci, Selenium::WebDriver::Platform.ci)

    results = guards.disposition
    send(*results) if results
  end

  config.after { @driver&.quit }

  def start_session
    options = Selenium::WebDriver::Chrome::Options.new
    options.add_argument('disable-search-engine-choice-screen')
    options.add_argument('--no-sandbox')
    @driver = Selenium::WebDriver.for(:chrome, options: options)
  end

  def start_bidi_session
    options = Selenium::WebDriver::Chrome::Options.new(web_socket_url: true)
    @driver = Selenium::WebDriver.for :chrome, options: options
  end

  def start_firefox
    options = Selenium::WebDriver::Options.firefox(timeouts: {implicit: 1500})
    @driver = Selenium::WebDriver.for :firefox, options: options
  end
end
```

\### Set Up

```js
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L7-L9)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

\### Tear Down

```js
  after(async () => await driver.quit());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L30)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

### Executando

```shell
mvn clean test
```

### Gradle

```shell
gradle clean test
```

````md
```
````

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/README.md#L35)

##### /examples/python/README.md

````md
# Running tests from Selenium Python examples

#### 1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

#### 2. Navigate to `python` directory

```
cd seleniumhq.github.io/examples/python
```

#### 3. Create a virtual environment

- On Windows:

```
py -m venv venv
venv\Scripts\activate
```

- On Linux/Mac:

```
python3 -m venv venv
source venv/bin/activate
```

#### 4. Install dependencies:

```
pip install -r requirements.txt
```

> for help, see: https://packaging.python.org/en/latest/tutorials/installing-packages

#### 5. Run tests

- Run all tests with the default Python interpreter:

```
pytest
```

- Run all tests with every installed/supported Python interpreter:

```
tox
```

> Please have some patience - If you are doing it for the first time, it will take a little while to download the browser drivers

- Run a specific example:

```
pytest path/to/test_script.py
```

> Make sure to replace `path/to/test_script.py` with the path and name of the example you want to run
````

```md
dotnet test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/README.md#L44)

##### /examples/dotnet/README.md

````md

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

## Navigate to the .NET directory
### Change into the .NET examples directory:

```bash
cd seleniumhq.github.io/examples/dotnet/SeleniumDocs
```

## Running the Tests
### Restore dependencies
Install necessary dependencies using the .NET CLI:

```bash
dotnet restore
```

### Run all tests
To run all available tests:

```bash
dotnet test
```

### Run a Specific Test Method
To run a specific test method using its fully qualified name:

```bash
dotnet test --filter "FullyQualifiedName=Namespace.ClassName.MethodName"
```
For example:
```bash
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

You can also filter by test name only (if it's unique):
```bash
dotnet test --filter "Name=EightComponents"
```
````

```md
bundle exec rspec
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/README.md#L26)

##### /examples/ruby/README.md

````md
# Running all tests from Selenium ruby example

Follow these steps to run all test example from selenium ruby

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `ruby` directory

```
cd seleniumhq.github.io/examples/ruby
```

3. Install dependencies using bundler

```
bundler install
```

4. Run all tests

```
bundle exec rspec
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a ruby script

Use this command to run a ruby script and follow the first script example

```
ruby example_script.rb
```
````

### Mocha

```shell
mocha runningTests.spec.js
```

### npx

```shell
npx mocha runningTests.spec.js
```

[Add Example](/documentation/about/contributing/#creating-examples)

### Examplos

In [First script](https://www.selenium.dev/pt-br/documentation/webdriver/getting_started/first_script/), we saw each of the components of a Selenium script. Here’s an example of that code using a test runner:

*
*
*
*
*
*

```java

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java)

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py)

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted
{
    [TestClass]
    public class UsingSeleniumTest
    {

        [TestMethod]
        public void EightComponents()
        {
            IWebDriver driver = new ChromeDriver();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

            var title = driver.Title;
            Assert.AreEqual("Web form", title);

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            var textBox = driver.FindElement(By.Name("my-text"));
            var submitButton = driver.FindElement(By.TagName("button"));
            
            textBox.SendKeys("Selenium");
            submitButton.Click();
            
            var message = driver.FindElement(By.Id("message"));
            var value = message.Text;
            Assert.AreEqual("Received!", value);
            
            driver.Quit();
        }
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs)

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb)

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js)

[Add Example](/documentation/about/contributing/#creating-examples)

## Proximos passos

Pegue no que aprendeu e desenvolva o seu código Selenium!

À medida que encontrar mais funcionalidades de que precisa, leia o resto da nossa [documentação do WebDriver](https://www.selenium.dev/pt-br/documentation/webdriver/).

Última modificação February 25, 2026: [Update "Using Selenium" documentation with C# example from .NET README (#2584) (e1d46ea60e4)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e1d46ea60e47ff168113cd1e609b27a142527573)

## Development Partners

[](https://www.browserstack.com/automate?utm_campaign=open-source-sponsor\&utm_campaigncode=701OW000009sQwVYAU\&utm_medium=partnered\&utm_source=seleniumorg)

[](https://saucelabs.com/resources/topic-hub/selenium?utm_source=selenium\&utm_medium=website\&utm_campaign=selenium-sponsorship-fy25)

[](https://www.testmuai.com)

## Selenium Level Sponsors

[](https://brightdata.com/?utm_source=brand\&utm_campaign=brnd-mkt_partners_selenium)

[](https://applitools.com/)

[](https://www.thordata.com/?ls=waOicIkB\&lk=selenium)

## Support the Selenium Project

Learn more or view the full list of sponsors.

[Learn more**](/sponsors)

----
url: https://www.selenium.dev/ja/documentation/test_practices/design_strategies/
----

# デザインパターンと開発戦略

```java
package com.example.webdriver;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class EditIssue {

  private final WebDriver driver;

  public EditIssue(WebDriver driver) {
    this.driver = driver;
  }

  public void setTitle(String title) {
    WebElement field = driver.findElement(By.id("issue_title")));
    clearAndType(field, title);
  }

  public void setBody(String body) {
    WebElement field = driver.findElement(By.id("issue_body"));
    clearAndType(field, body);
  }

  public void setHowToReproduce(String howToReproduce) {
    WebElement field = driver.findElement(By.id("issue_form_repro-command"));
    clearAndType(field, howToReproduce);
  }

  public void setLogOutput(String logOutput) {
    WebElement field = driver.findElement(By.id("issue_form_logs"));
    clearAndType(field, logOutput);
  }

  public void setOperatingSystem(String operatingSystem) {
    WebElement field = driver.findElement(By.id("issue_form_operating-system"));
    clearAndType(field, operatingSystem);
  }

  public void setSeleniumVersion(String seleniumVersion) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-version"));
    clearAndType(field, logOutput);
  }

  public void setBrowserVersion(String browserVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-versions"));
    clearAndType(field, browserVersion);
  }

  public void setDriverVersion(String driverVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-driver-versions"));
    clearAndType(field, driverVersion);
  }

  public void setUsingGrid(String usingGrid) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-grid-version"));
    clearAndType(field, usingGrid);
  }

  public IssueList submit() {
    driver.findElement(By.cssSelector("button[type='submit']")).click();
    return new IssueList(driver);
  }

  private void clearAndType(WebElement field, String text) {
    field.clear();
    field.sendKeys(text);
  }
}
```

これをLoadableComponentに変換するには、これを基本型として設定するだけです。

```java
public class EditIssue extends LoadableComponent<EditIssue> {
  // rest of class ignored for now
}
```

この署名は少し変わっているように見えますが、それは、このクラスがEditIssueページをロードするLoadableComponentを表すことを意味します。

このベースクラスを拡張することにより、2つの新しいメソッドを実装する必要があります。

```java
  @Override
  protected void load() {
    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();
    assertTrue("Not on the issue entry page: " + url, url.endsWith("/new"));
  }
```

`load` メソッドはページに移動するために使用され、　`isLoaded` メソッドは正しいページにいるかどうかを判断するために使用されます。 このメソッドはブール値を返す必要があるように見えますが、代わりにJUnitのAssertクラスを使用して一連のアサーションを実行します。 アサーションは好きなだけ少なくても多くてもかまいません。 これらのアサーションを使用することで、クラスのユーザーにテストのデバッグに使用できる明確な情報を提供することができます。

少し手直しすると、PageObjectは次のようになります。

```java
package com.example.webdriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

import static junit.framework.Assert.assertTrue;

public class EditIssue extends LoadableComponent<EditIssue> {

  private final WebDriver driver;
  
  // By default the PageFactory will locate elements with the same name or id
  // as the field. Since the issue_title element has an id attribute of "issue_title"
  // we don't need any additional annotations.
  private WebElement issue_title;
  
  // But we'd prefer a different name in our code than "issue_body", so we use the
  // FindBy annotation to tell the PageFactory how to locate the element.
  @FindBy(id = "issue_body") private WebElement body;
  
  public EditIssue(WebDriver driver) {
    this.driver = driver;
    
    // This call sets the WebElement fields.
    PageFactory.initElements(driver, this);
  }

  @Override
  protected void load() {
    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();
    assertTrue("Not on the issue entry page: " + url, url.endsWith("/new"));
  }

  public void setHowToReproduce(String howToReproduce) {
    WebElement field = driver.findElement(By.id("issue_form_repro-command"));
    clearAndType(field, howToReproduce);
  }

  public void setLogOutput(String logOutput) {
    WebElement field = driver.findElement(By.id("issue_form_logs"));
    clearAndType(field, logOutput);
  }

  public void setOperatingSystem(String operatingSystem) {
    WebElement field = driver.findElement(By.id("issue_form_operating-system"));
    clearAndType(field, operatingSystem);
  }

  public void setSeleniumVersion(String seleniumVersion) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-version"));
    clearAndType(field, logOutput);
  }

  public void setBrowserVersion(String browserVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-versions"));
    clearAndType(field, browserVersion);
  }

  public void setDriverVersion(String driverVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-driver-versions"));
    clearAndType(field, driverVersion);
  }

  public void setUsingGrid(String usingGrid) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-grid-version"));
    clearAndType(field, usingGrid);
  }

  public IssueList submit() {
    driver.findElement(By.cssSelector("button[type='submit']")).click();
    return new IssueList(driver);
  }

  private void clearAndType(WebElement field, String text) {
    field.clear();
    field.sendKeys(text);
  }
}
```

それは私たちをあまり信じられなかったようですよね？ これまでに行ったことの1つは、ページに移動する方法に関する情報をページ自体にカプセル化することです。 つまり、この情報はコードベース全体に散らばっていません。 これは、テストで下記を実行できることも意味します。

```java
EditIssue page = new EditIssue(driver).get();
```

この呼び出しにより、ドライバーは必要に応じてページに移動します。

### ネストされたコンポーネント

LoadableComponentsは、他のLoadableComponentsと組み合わせて使用すると、より便利になります。 この例を使用すると、 “edit issue” ページをプロジェクトのWebサイト内のコンポーネントとして表示できます（結局のところ、そのサイトのタブからアクセスします）。 また、issue を報告するにはログインする必要があります。 これをネストされたコンポーネントのツリーとしてモデル化できます。

```
 + ProjectPage
 +---+ SecuredPage
     +---+ EditIssue
```

これはコードではどのように見えますか？ まず、各論理コンポーネントには独自のクラスがあります。 それぞれの “load” メソッドは、親クラスを “get” します。 上記のEditIssueクラスに加えて、最終結果は次のようになります。

ProjectPage.java:

```java
package com.example.webdriver;

import org.openqa.selenium.WebDriver;

import static org.junit.Assert.assertTrue;

public class ProjectPage extends LoadableComponent<ProjectPage> {

  private final WebDriver driver;
  private final String projectName;

  public ProjectPage(WebDriver driver, String projectName) {
    this.driver = driver;
    this.projectName = projectName;
  }

  @Override
  protected void load() {
    driver.get("http://" + projectName + ".googlecode.com/");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();

    assertTrue(url.contains(projectName));
  }
}
```

and SecuredPage.java:

```java
package com.example.webdriver;

import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import static org.junit.Assert.fail;

public class SecuredPage extends LoadableComponent<SecuredPage> {

  private final WebDriver driver;
  private final LoadableComponent<?> parent;
  private final String username;
  private final String password;

  public SecuredPage(WebDriver driver, LoadableComponent<?> parent, String username, String password) {
    this.driver = driver;
    this.parent = parent;
    this.username = username;
    this.password = password;
  }

  @Override
  protected void load() {
    parent.get();

    String originalUrl = driver.getCurrentUrl();

    // Sign in
    driver.get("https://www.google.com/accounts/ServiceLogin?service=code");
    driver.findElement(By.name("Email")).sendKeys(username);
    WebElement passwordField = driver.findElement(By.name("Passwd"));
    passwordField.sendKeys(password);
    passwordField.submit();

    // Now return to the original URL
    driver.get(originalUrl);
  }

  @Override
  protected void isLoaded() throws Error {
    // If you're signed in, you have the option of picking a different login.
    // Let's check for the presence of that.

    try {
      WebElement div = driver.findElement(By.id("multilogin-dropdown"));
    } catch (NoSuchElementException e) {
      fail("Cannot locate user name link");
    }
  }
}
```

EditIssueの “load” メソッドは次のようになります。

```java
  @Override
  protected void load() {
    securedPage.get();

    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }
```

これは、コンポーネントがすべて相互に “ネストされている” ことを示しています。 EditIssueで `get()` を呼び出すと、そのすべての依存関係も読み込まれます。 使用例：

```java
public class FooTest {
  private EditIssue editIssue;

  @Before
  public void prepareComponents() {
    WebDriver driver = new FirefoxDriver();

    ProjectPage project = new ProjectPage(driver, "selenium");
    SecuredPage securedPage = new SecuredPage(driver, project, "example", "top secret");
    editIssue = new EditIssue(driver, securedPage);
  }

  @Test
  public void demonstrateNestedLoadableComponents() {
    editIssue.get();

    editIssue.title.sendKeys('Title');
    editIssue.body.sendKeys('What Happened');
    editIssue.setHowToReproduce('How to Reproduce');
    editIssue.setLogOutput('Log Output');
    editIssue.setOperatingSystem('Operating System');
    editIssue.setSeleniumVersion('Selenium Version');
    editIssue.setBrowserVersion('Browser Version');
    editIssue.setDriverVersion('Driver Version');
    editIssue.setUsingGrid('I Am Using Grid');
  }
}
```

テストで [Guiceberry](https://github.com/zorzella/guiceberry) などのライブラリを使用している場合は、PageObjectsの設定の前文を省略して、わかりやすく読みやすいテストを作成できます。

## ボットパターン

(以前の場所: <https://github.com/SeleniumHQ/selenium/wiki/Bot-Style-Tests>)

PageObjectsは、テストでの重複を減らすための便利な方法ですが、チームが快適にフォローできるパターンであるとは限りません。 別のアプローチは、より “コマンドのような” スタイルのテストに従うことです。

“ボット” は、生のSeleniumAPIに対するアクション指向の抽象化です。 つまり、コマンドがアプリに対して正しいことをしていないことがわかった場合、コマンドを簡単に変更できます。 例として：

```java
public class ActionBot {
  private final WebDriver driver;

  public ActionBot(WebDriver driver) {
    this.driver = driver;
  }

  public void click(By locator) {
    driver.findElement(locator).click();
  }

  public void submit(By locator) {
    driver.findElement(locator).submit();
  }

  /** 
   * Type something into an input field. WebDriver doesn't normally clear these
   * before typing, so this method does that first. It also sends a return key
   * to move the focus out of the element.
   */
  public void type(By locator, String text) { 
    WebElement element = driver.findElement(locator);
    element.clear();
    element.sendKeys(text + "\n");
  }
}
```

```py
import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L6-L26)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L28-L65)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L67-L80)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L82-L172)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L174-L240)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

最終更新 May 6, 2025: [\[docs\]: fix build issues \[deploy site\] (7615cca5ebc)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/7615cca5ebc3a7681e9ec9e6cdb4b1ddd681ef00)

----
url: https://www.selenium.dev/ja/documentation/grid/configuration/toml_options/
----

# Toml オプション

```toml
[section1]
option1="value"

[section2]
option2=["value1","value2"]
option3=true
```

TOML ファイルで設定された Grid コンポーネントを起動するには以下のように起動できます:

```
java -jar selenium-server-<version>.jar <component> --config /path/to/file/<file-name>.toml
```

### スタンドアロン

ポート 4449 で動作し、新規セッションリクエストのタイムアウトが 500 秒のスタンドアロンサーバー。

```toml
[server]
port = 4449

[sessionqueue]
session-request-timeout = 500
```

### 特定のブラウザとセッションの上限

Firefox と Chrome のみがデフォルトで有効になっているスタンドアロンサーバー、またはノード

```toml
[node]
drivers = ["chrome", "firefox"]
max-sessions = 3
```

### ドライバーのカスタマイズと設定

Firefox Beta や Nightly のような、異なるブラウザのバージョンを持つことができるカスタマイズされた ドライバを用いた、スタンドアロン、またはノード。

```toml
[node]
detect-drivers = false
[[node.driver-configuration]]
max-sessions = 100
display-name = "Firefox Nightly"
stereotype = "{\"browserName\": \"firefox\", \"browserVersion\": \"93\", \"platformName\": \"MAC\", \"moz:firefoxOptions\": {\"binary\": \"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"
[[node.driver-configuration]]
display-name = "Chrome Beta"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"94\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta\"}}"
[[node.driver-configuration]]
display-name = "Chrome Dev"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"95\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev\"}}"
webdriver-executable = '/path/to/chromedriver/95/chromedriver'
```

### Docker を利用したスタンドアロン、またはノード

Docker コンテナでセッションを実行できるスタンドアロン、またはノードサーバー。 ドライバを検出を無効にし、最大 2 つの同時セッションを持ちます。 ステレオタイプは、Docker イメージにマッピングされる必要があり、 Docker デーモンが http/tcp で公開されている必要があります。 また、`devices`プロパティを用いて、ホスト上でアクセス可能なデバイスファイルを、コンテナで利用できるようにすることも可能です。 Docker デバイスをマッピングする詳しい方法は[docker](https://docs.docker.com/engine/reference/commandline/run/#add-host-device-to-container---device) を参照してください。

```toml
[node]
detect-drivers = false
max-sessions = 2

[docker]
configs = [
    "selenium/standalone-chrome:93.0", "{\"browserName\": \"chrome\", \"browserVersion\": \"91\"}",
    "selenium/standalone-firefox:92.0", "{\"browserName\": \"firefox\", \"browserVersion\": \"92\"}"
]
#Optionally define all device files that should be mapped to docker containers
#devices = [
#    "/dev/kvm:/dev/kvm"
#]
url = "http://localhost:2375"
video-image = "selenium/video:latest"
```

### WebDriver をサポートするサービスエンドポイントへのコマンド中継

WebDriver をサポートする外部サービスを Selenium Grid に接続すると便利です。 例えばクラウドプロバイダーや Appium サーバーなどです。 Grid はローカルに存在しないプラットフォームやバージョンなどを幅広くカバーできるようになります。

以下は Appium サーバーを Grid に接続する例です。

```toml
[node]
detect-drivers = false

[relay]
# Default Appium/Cloud server endpoint
url = "http://localhost:4723/wd/hub"
status-endpoint = "/status"
# Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status (e.g. HTTP/1.1, HTTP/2)
protocol-version = "HTTP/1.1"
# Stereotypes supported by the service. The initial number is "max-sessions", and will allocate
# that many test slots to that particular configuration
configs = [
  "5", "{\"browserName\": \"chrome\", \"platformName\": \"android\", \"appium:platformVersion\": \"11\"}"
]
```

### Basic 認証の有効化

ルーター、ハブ、スタンドアロンにユーザー名とパスワードを設定することで、 Basic 認証で Grid を保護することができます。 このユーザーとパスワードは、Grid UI を読み込む時や 新しいセッションを開始する時に必要になります。

```toml
[router]
username = "admin"
password = "myStrongPassword"
```

Java でユーザーとパスワードを使ってセッションを開始する方法の例です。

```java
ClientConfig clientConfig = ClientConfig.defaultConfig()
  .baseUrl(new URL("http://localhost:4444"))
  .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"));
HttpCommandExecutor executor = new HttpCommandExecutor(clientConfig);
RemoteWebDriver driver = new RemoteWebDriver(executor, new ChromeOptions());
```

In other languages, you can use the URL http\://admin:myStrongPassword\@localhost:4444

### 特定のノードにマッチするカスタム capabilities の設定

**重要**: カスタム capabilities は全てのノードで設定する必要があります。 また全てのセッションリクエストで常に含まれる必要があります。

```toml
[node]
detect-drivers = false

[[node.driver-configuration]]
display-name = "firefox"
stereotype = '{"browserName": "firefox", "platformName": "macOS", "browserVersion":"96", "networkname:applicationName":"node_1", "nodename:applicationName":"app_1" }'
max-sessions = 5
```

Java でノードにマッチさせる方法の例です。

```java
FirefoxOptions options = new FirefoxOptions();
options.setCapability("networkname:applicationName", "node_1");
options.setCapability("nodename:applicationName", "app_1");
options.setBrowserVersion("96");
options.setPlatformName("macOS");
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

### Enabling Managed downloads by the Node.

The Node can be instructed to manage downloads automatically. This will cause the Node to save all files that were downloaded for a particular session into a temp directory, which can later be retrieved from the node. To turn this capability on, use the below configuration:

```toml
[node]
enable-managed-downloads = true
```

Refer to the [CLI section](https://www.selenium.dev/ja/documentation/grid/configuration/cli_options/#enabling-managed-downloads-by-the-node) for a complete example.

最終更新 April 23, 2024: [\[grid\] update list CLI/TOML options (#1683) (1f27efd060f)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/1f27efd060fbacdd93b29416182faa8636bd6604)

----
url: https://www.selenium.dev/ja/documentation/overview/details/
----

# Selenium 詳細

最終更新 September 10, 2024: [Transparent png favicons (#1937)\[deploy site\] (03705be0833)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/03705be0833a1820cbaf73ab1119adf400549ac8)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/bidi/network/
----

# WebDriver BiDi Network Features

These features are related to networking, and are made available via a “network” namespace.

The implementation of these features is being tracked here: [#13993](https://github.com/SeleniumHQ/selenium/issues/13993)

Remember that to use WebDriver BiDi, you must enable it in Options. For more details, see [Enabling BiDi](https://www.selenium.dev/pt-br/documentation/webdriver/bidi/)

```rb
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds an auth handler', skip: 'Do not execute BiDi test' do
    driver.network.add_authentication_handler('test', 'test')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/network_spec.rb#L7-L11)

##### /examples/ruby/spec/bidi/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network', exclusive: {bidi: true, reason: 'only executed when bidi is enabled'},
                          only: {browser: %i[chrome edge firefox]} do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds an auth handler', skip: 'Do not execute BiDi test' do
    driver.network.add_authentication_handler('test', 'test')
    driver.navigate.to url_for('basicAuth')
    expect(driver.find_element(tag_name: 'h1').text).to eq('authorized')
  end
end
```

Última modificação August 18, 2025: [Fix path for codeblock (cb0bfc20fdf)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/cb0bfc20fdf56dfe6b16733e84cee540f2ffe04e)

----
url: https://www.selenium.dev/ja/documentation/webdriver/browsers/
----

# 対応ブラウザ

各ブラウザにはカスタム機能とユニークな特徴があります。

***

##### [Chrome固有の機能](/ja/documentation/webdriver/browsers/chrome/)

これらは、Google Chromeブラウザに特有の機能と機能です。

##### [Edge固有の機能](/ja/documentation/webdriver/browsers/edge/)

これらは、Microsoft Edgeブラウザに固有のCapabilityです。

##### [Firefox特有の機能](/ja/documentation/webdriver/browsers/firefox/)

これらは、Mozilla Firefoxブラウザに特有の機能と機能です。

##### [IE特有の機能](/ja/documentation/webdriver/browsers/internet_explorer/)

これらは、Microsoft Internet Explorerブラウザに特有の機能と機能です。

##### [Safari特有の機能](/ja/documentation/webdriver/browsers/safari/)

これらは、Apple Safariブラウザに特有の機能と機能です。

----
url: https://www.selenium.dev/ja/documentation/grid/configuration/help/
----

# 構成ヘルプ

```shell
java -jar selenium-server-<version>.jar info config
```

### セキュリティ

安全な通信とノード登録のためのグリッドサーバーの設定の詳細を取得するには、以下を実行します。

```shell
java -jar selenium-server-<version>.jar info security
```

### セッションマップの設定

デフォルトでは、グリッドはローカルセッションマップを使用してセッション情報を保存します。 グリッドは、Redis や JDBC-SQL がサポートするデータベースなどの追加のストレージオプションをサポートしています。 別のセッションストレージをセットアップするには、次のコマンドを使用してセットアップ手順を取得します。

```shell
java -jar selenium-server-<version>.jar info sessionmap
```

### OpenTelemetry と Jaeger を使用したトレースの設定

デフォルトでは、トレースは有効になっています。 トレースをエクスポートして Jaeger 経由で視覚化するには、次のコマンドを使用して手順を実行します。

```shell
java -jar selenium-server-<version>.jar info tracing
```

## SeleniumGrid コマンドを一覧表示する

```shell
java -jar selenium-server-<version>.jar --config-help
```

使用可能なすべてのコマンドとそれぞれの説明が表示されます。

## コンポーネントヘルプコマンド

Selenium ロールの後に–help config オプションを渡して、コンポーネント固有の構成情報を取得します。

### スタンドアロン

```shell
java -jar selenium-server-<version>.jar standalone --help
```

### ハブ

```shell
java -jar selenium-server-<version>.jar hub --help
```

### セッション

```shell
java -jar selenium-server-<version>.jar sessions --help
```

### 新規セッションキュー

```shell
java -jar selenium-server-<version>.jar sessionqueue --help
```

### ディストリビューター

```shell
java -jar selenium-server-<version>.jar distributor --help
```

### ルーター

```shell
java -jar selenium-server-<version>.jar router --help
```

### ノード

```shell
java -jar selenium-server-<version>.jar node --help
```

----
url: https://www.selenium.dev/pt-br/_print/documentation/about/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/about/).

# Sobre esta documentação

* 1: [Direitos autorais e atribuições](#pg-35d79a09a489d439e39bfaff74c481dd)
* 2: [Contribuindo com o Site e Documentação do Selenium](#pg-7a2a81c8f39a5fded7355f7fd6ecc6a2)
* 3: [Guia de estilo para a documentação do Selenium](#pg-e5e5ecd7854fee43970a63f8524b3559)

Essa documentação, como o próprio código, são mantidos 100% por voluntários dentro da comunidade Selenium. Muitos têm usado desde o seu início, mas muitos mais o usam há pouco tempo, e dedicaram seu tempo para ajudar a melhorar a experiência de integração para novos usuários.

Se houver algum problema com a documentação, queremos saber! A melhor maneira de comunicar um problema é visitar [https://github.com/seleniumhq/seleniumhq.github.io/issues](//github.com/seleniumhq/seleniumhq.github.io/issues) e pesquise se o problema já foi ou não arquivado. Se não, fique à vontade para abrir um!

Muitos membros da comunidade frequentam o canal Libera *#selenium* em [Libera.chat](https://libera.chat/). Sinta-se à vontade para entrar e fazer perguntas e se você receber ajuda que você acha que poderia ser útil nessa documentação, certifique-se de adicionar sua contribuição! Podemos atualizar essa documentação, mas é muito mais fácil para todos quando recebemos contribuições de fora dos committers normais.

# 1 - Direitos autorais e atribuições

| Software                            | Versão   | Licença                                                     |
| ----------------------------------- | -------- | ----------------------------------------------------------- |
| [Hugo](/pt-br/)                     | v0.110.0 | [Apache 2.0](//gohugo.io/about/license/)                    |
| [Docsy](//github.com/google/docsy/) | —        | [Apache 2.0](//github.com/google/docsy/blob/master/LICENSE) |

## Licença

Todo o código e documentação proveniente do projeto Selenium está licenciado sob a licença Apache 2.0, com a [Software Freedom Conservancy](/pt-br/) como detentor dos direitos autorais.

A licença está incluída aqui por conveniência, mas você também pode encontrá-la no [Site da Apache Foundation](//apache.org/licenses/LICENSE-2.0.html):

```markdown
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
```

# 2 - Contribuindo com o Site e Documentação do Selenium

Informações em como melhorar a documentação e exemplos de código para Selenium.

Selenium é um grande projeto de software, seu site e documentação são fundamentais para entender como as coisas funcionam e aprender maneiras eficazes de explorar seu potencial.

Este projeto contém o site e a documentação do Selenium. Isto é um esforço contínuo (não direcionado a nenhuma versão específica) para fornecer informações atualizadas sobre como usar o Selenium de forma eficaz, como se envolver e como contribuir para o Selenium.

As contribuições para o site e documentação seguem o processo descrito na seção abaixo sobre contribuições.

***

```
    {{< tab header="Ruby" >}}
    {{< gh-codeblock path="/examples/ruby/spec/browsers/chrome_spec.rb#L8-L9" >}}
    {{< /tab >}}
```

```shell
% git clone git@github.com:seleniumhq/seleniumhq.github.io.git
% cd seleniumhq.github.io
```

#### Dependências: Hugo

Usamos [Hugo](https://gohugo.io/) e [Docsy theme](https://www.docsy.dev/) para criar e gerar o website. Você vai necessitar de usar a versão “extended” Sass/SCSS do binário Hugo. Recomendamos a versão 0.148.2 .

Por favor siga as instruções do Docsy [Install Hugo](https://www.docsy.dev/docs/getting-started/#install-hugo)

### Passo 2: Branch

Crie uma branch e comece a hackear:

```shell
% git checkout -b my-feature-branch
```

Praticamos o desenvolvimento baseado em HEAD, o que significa que todas as mudanças são aplicadas diretamente no topo do `dev`.

### Passo 3: Faça mudanças

O repositório contém o website e a documentação. Antes de começar a alterar coisas, por favor veja o resto dos passos para preparar as dependências e sub-módulos (veja os comandos abaixo).

Para fazer alterações ao website, trabalha na pasta `website_and_docs`. Para ver uma previsão do aspecto do website, execute `hugo server` a partir da raíz do projecto.

```shell
% git submodule update --init --recursive
% cd website_and_docs
% hugo server
```

See [Style Guide](https://www.selenium.dev/pt-br/documentation/about/style/) for more information on our conventions for contribution

### Passo 4: Commit

Primeiro, certifique-se de que o git saiba seu nome e endereço de e-mail:

```shell
% git config --global user.name 'Santa Claus'
% git config --global user.email 'santa@example.com'
```

**Escrever boas mensagens de commit é importante.** Uma mensagem de confirmação deve descrever o que mudou, por que e conter referência de problemas corrigidos (se houver). Siga estas diretrizes ao escrever um:

1. A primeira linha deve ter cerca de 50 caracteres ou menos e conter uma breve da descrição da mudança.
2. Mantenha a segunda linha em branco.
3. Quebra todas as outras linhas em 72 colunas.
4. Incluir `Fixes # N`, onde *N* é o número do problema que o commit corrige se houver.

Uma boa mensagem de confirmação pode ter a seguinte aparência:

```text
explain commit normatively in one line

Body of commit message is a few lines of text, explaining things
in more detail, possibly giving some background about the issue
being fixed, etc.

The body of the commit message can be several paragraphs, and
please do proper word-wrap and keep columns shorter than about
72 characters or so. That way `git log` will show things
nicely even when it is indented.

Fixes #141
```

A primeira linha deve ser significativa, pois é o que as pessoas veem quando executam `git shortlog` ou` git log --oneline`.

### Passo 5: Rebase

Use `git rebase` (não `git merge`) para sincronizar seu trabalho de tempos em tempos.

```shell
% git fetch origin
% git rebase origin/trunk
```

### Passo 6: Teste

Lembre-se sempre de [executar o servidor local](https://gohugo.io/getting-started/usage/#livereload), com isso, você pode ter certeza de que suas alterações não prejudicaram nada.

### Passo 7: Push

```shell
% git push origin my-feature-branch
```

Acesse <https://github.com/yourusername/seleniumhq.github.io.git> e clique em *Pull Request* e preencha o formulário. **Por favor indique que você assinou o CLA** (consulte a Etapa 7).

Os Pull Requests geralmente são revisados em alguns dias. Se houver comentários a abordar, aplique suas alterações em novos commits (de preferência [fixups](http://git-scm.com/docs/git-commit)) e envie para a mesma branch.

### Passo 8: Integração

Quando a revisão do código for concluída, um committer integrará seu PR no branch de tronco do repositório. Porque gostamos de manter um histórico linear no `trunk`, nós normalmente iremos dar Squash & Rebase no histórico da sua branch.

## Comunicação

Todos os detalhes sobre como se comunicar com os colaboradores do projeto e a comunidade em geral podem ser encontrados em <https://selenium.dev/support>

# 3 - Guia de estilo para a documentação do Selenium

Convenções para contribuições à documentação do Selenium e exemplos de código.

Read our [contributing documentation](https://www.selenium.dev/pt-br/documentation/about/contributing/) for complete instructions on how to add content to this documentation.

## Alerts

Alerts have been added to direct potential contributors to where specific content is missing.

```html
{{< alert-content />}}
```

or

```html
{{< alert-content >}}
Additional information about what specific content is needed
{{< /alert-content >}}
```

```java
WebDriver driver = new ChromeDriver();
```

```python
driver = webdriver.Chrome()
```

```csharp
var driver = new ChromeDriver();
```

```ruby
driver = Selenium::WebDriver.for :chrome
```

```javascript
let driver = await new Builder().forBrowser('chrome').build();
```

```kotlin
val driver = ChromeDriver()
```

To generate the above tabs, this is what you need to write. Note that the `tabpane` includes `langEqualsHeader=true`. This auto-formats the code in each tab to match the header name, and ensures that all tabs on the page with a language are set to the same thing.

```
{{< tabpane langEqualsHeader=true >}}
  {{< tab header="Java" >}}
    WebDriver driver = new ChromeDriver();
  {{< /tab >}}
  {{< tab header="Python" >}}
    driver = webdriver.Chrome()
  {{< /tab >}}
  {{< tab header="CSharp" >}}
    var driver = new ChromeDriver();
  {{< /tab >}}
  {{< tab header="Ruby" >}}
    driver = Selenium::WebDriver.for :chrome
  {{< /tab >}}
  {{< tab header="JavaScript" >}}
    let driver = await new Builder().forBrowser('chrome').build();
  {{< /tab >}}
  {{< tab header="Kotlin" >}}
    val driver = ChromeDriver()
  {{< /tab >}}
{{< /tabpane >}}
```

#### Reference GitHub Examples

To ensure that all code is kept up to date, our goal is to write the code in the repo where it can be executed when Selenium versions are updated to ensure that everything is correct.

All code examples to be in our [example directories](https://github.com/SeleniumHQ/seleniumhq.github.io/tree/dev/examples).

This code can be automatically displayed in the documentation using the `gh-codeblock` shortcode. The shortcode automatically generates its own html, so we do not want it to auto-format with the language header. If all tabs are using this shortcode, set `text=true` in the `tabpane` and remove `langEqualsHeader=true`. If only some tabs are using this shortcode, keep `langEqualsHeader=true` in the `tabpane` and add `text=true` to the `tab`. Note that the `gh-codeblock` line can not be indented at all.

One great thing about using `gh-codeblock` is that it adds a link to the full example. This means you don’t have to include any additional context code, just the line(s) that are needed, and the user can navigate to the repo to see how to use it.

A basic comparison of code looks like:

```
{{< tabpane text=true >}}
{{< tab header="Java" >}}
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-L27" >}}
{{< /tab >}}
{{< tab header="Python" >}}
{{< gh-codeblock path="/examples/python/tests/getting_started/first_script.py#L18-L19" >}}
{{< /tab >}}
{{< tab header="CSharp" >}}
{{< gh-codeblock path="/examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-L26" >}}
{{< /tab >}}
{{< tab header="Ruby" >}}
{{< gh-codeblock path="/examples/ruby/spec/getting_started/first_script.rb#L17-L18" >}}
{{< /tab >}}
{{< tab header="JavaScript" >}}
{{< gh-codeblock path="/examples/javascript/test/getting_started/firstScript.spec.js#L22-L23" >}}
{{< /tab >}}
{{< tab header="Kotlin" >}}
{{< gh-codeblock path="/examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-L32" >}}
{{< /tab >}}
{{< /tabpane >}}
```

```java
        WebElement message = driver.findElement(By.id("message"));
        message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-L27)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
message = driver.find_element(by=By.ID, value="message")
text = message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L18-L19)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-L26)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
message = driver.find_element(id: 'message')
message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L17-L18)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L22-L23)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val message = driver.findElement(By.id("message"))
        val value = message.getText()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-L32)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

### Using Markdown in a Tab

If you want your example to include something other than code (default) or html (from `gh-codeblock`), you need to first set `text=true`, then change the Hugo syntax for the `tab`to use `%` instead of `<` and `>` with curly braces:

```
{{< tabpane text=true >}}
{{% tab header="Java" %}}
1. Start the driver
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12" >}}
2. Navigate to a page
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14" >}}
3. Quit the driver
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29" >}}
{{% /tab %}}
< ... >
{{< /tabpane >}}
```

This produces:

*

1. Start the driver

   ```java
           WebDriver driver = new ChromeDriver();
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

2. Navigate to a page

   ```java
           driver.get("https://www.selenium.dev/selenium/web/web-form.html");
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

3. Quit the driver

   ```java
           driver.quit();
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

----
url: https://www.selenium.dev/documentation/legacy/developers/ci_tool/
----

# Selenium's Continuous Integration Implementation

----
url: https://www.selenium.dev/documentation/test_practices/encouraged/improved_reporting/
----

# Improved reporting

Selenium is not designed to report on the status of test cases run. Taking advantage of the built-in reporting capabilities of unit test frameworks is a good start. Most unit test frameworks have reports that can generate xUnit or HTML formatted reports. xUnit reports are popular for importing results to a Continuous Integration (CI) server like Jenkins, Travis, Bamboo, etc. Here are some links for more information regarding report outputs for several languages.

[NUnit 3 Console Runner](//github.com/nunit/docs/wiki/Console-Runner)

[NUnit 3 Console Command Line](//github.com/nunit/docs/wiki/Console-Command-Line)

[xUnit getting test results in TeamCity](//xunit.net/docs/getting-test-results-in-teamcity)

[xUnit getting test results in CruiseControl.NET](//xunit.net/docs/getting-test-results-in-ccnet)

[xUnit getting test results in Azure DevOps](//xunit.net/docs/getting-test-results-in-azure-devops)

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/encouraged/mock_external_services/
----

# Simulação de serviços externos

Eliminar as dependências de serviços externos melhorará muito a velocidade e estabilidade de seus testes.

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/bidi/w3c/
----

# BiDirectional API (W3C compliant)

**Page being translated from English to Portuguese. Do you speak Portuguese? Help us to translate it by sending us pull requests!

The following list of APIs will be growing as the [WebDriver BiDirectional Protocol](https://w3c.github.io/webdriver-bidi/) 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](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=\&template=feature.md).

***

##### [Browsing Context](/pt-br/documentation/webdriver/bidi/w3c/browsing_context/)

##### [Browsing Context](/pt-br/documentation/webdriver/bidi/w3c/input/)

##### [Network](/pt-br/documentation/webdriver/bidi/w3c/network/)

##### [Script](/pt-br/documentation/webdriver/bidi/w3c/script/)

##### [BiDirectional API (W3C compliant)](/pt-br/documentation/webdriver/bidi/w3c/log/)

----
url: https://www.selenium.dev/documentation/webdriver/bidi/network/
----

# WebDriver BiDi Network Features

These features are related to networking, and are made available via a “network” namespace.

The implementation of these features is being tracked here: [#13993](https://github.com/SeleniumHQ/selenium/issues/13993)

Remember that to use WebDriver BiDi, you must enable it in Options. For more details, see [Enabling BiDi](https://www.selenium.dev/documentation/webdriver/bidi/)

```rb
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds an auth handler', skip: 'Do not execute BiDi test' do
    driver.network.add_authentication_handler('test', 'test')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/network_spec.rb#L7-L11)

##### /examples/ruby/spec/bidi/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network', exclusive: {bidi: true, reason: 'only executed when bidi is enabled'},
                          only: {browser: %i[chrome edge firefox]} do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds an auth handler', skip: 'Do not execute BiDi test' do
    driver.network.add_authentication_handler('test', 'test')
    driver.navigate.to url_for('basicAuth')
    expect(driver.find_element(tag_name: 'h1').text).to eq('authorized')
  end
end
```

Last modified August 18, 2025: [Fix path for codeblock (cb0bfc20fdf)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/cb0bfc20fdf56dfe6b16733e84cee540f2ffe04e)

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/encouraged/improved_reporting/
----

# 改善报告

Selenium并非旨在报告测试用例的运行状态. 利用单元测试框架的内置报告功能是一个好的开始. 大多数单元测试框架都有可以生成xUnit或HTML格式的报告. xUnit报表很受欢迎, 可以将其结果导入到持续集成（CI）服务器, 例如Jenkins、Travis、Bamboo等. 以下是一些链接, 可获取关于几种语言报表输出的更多信息.

[NUnit 3 Console Runner](//github.com/nunit/docs/wiki/Console-Runner)

[NUnit 3 Console Command Line](//github.com/nunit/docs/wiki/Console-Command-Line)

[xUnit getting test results in TeamCity](//xunit.net/docs/getting-test-results-in-teamcity)

[xUnit getting test results in CruiseControl.NET](//xunit.net/docs/getting-test-results-in-ccnet)

[xUnit getting test results in Azure DevOps](//xunit.net/docs/getting-test-results-in-azure-devops)

----
url: https://www.selenium.dev/documentation/test_practices/encouraged/
----

# Encouraged behaviors

Some guidelines and recommendations on testing from the Selenium project.

A note on “Best Practices”: We’ve intentionally avoided the phrase “Best Practices” in this documentation. No one approach works for all situations. We prefer the idea of “Guidelines and Recommendations”. We encourage you to read through these and thoughtfully decide what approaches will work for you in your particular environment.

Functional testing is difficult to get right for many reasons. As if application state, complexity, and dependencies do not make testing difficult enough, dealing with browsers (especially with cross-browser incompatibilities) makes writing good tests a challenge.

Selenium provides tools to make functional user interaction easier, but does not help you write well-architected test suites. In this chapter we offer advice, guidelines, and recommendations on how to approach functional web page automation.

This chapter records software design patterns popular amongst many of the users of Selenium that have proven successful over the years.

***

##### [Page object models](/documentation/test_practices/encouraged/page_object_models/)

##### [Domain specific language](/documentation/test_practices/encouraged/domain_specific_language/)

##### [Generating application state](/documentation/test_practices/encouraged/generating_application_state/)

##### [Mock external services](/documentation/test_practices/encouraged/mock_external_services/)

##### [Improved reporting](/documentation/test_practices/encouraged/improved_reporting/)

##### [Avoid sharing state](/documentation/test_practices/encouraged/avoid_sharing_state/)

##### [Tips on working with locators](/documentation/test_practices/encouraged/locators/)

When to use which locators and how best to manage them in your code.

##### [Test independency](/documentation/test_practices/encouraged/test_independency/)

##### [Consider using a fluent API](/documentation/test_practices/encouraged/consider_using_a_fluent_api/)

##### [Fresh browser per test](/documentation/test_practices/encouraged/fresh_browser_per_test/)

----
url: https://www.selenium.dev/pt-br/documentation/grid/advanced_features/observability/
----

# Observabilidade

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar standalone --log-level FINE
```

2. Jaeger UI - OpenTelemetry fornece as APIs e SDKs para instrumentar rastreamentos no código. Enquanto o Jaeger é um sistema de rastreamento de backend que auxilia na coleta de dados de telemetria de rastreamento e oferece recursos de consulta, filtragem e visualização dos dados.

Instruções detalhadas sobre como visualizar rastreamentos usando a interface do Jaeger podem ser obtidas executando o seguinte comando:

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar info tracing
```

[Um exemplo muito bom e scripts para executar o servidor e enviar rastreamentos para o Jaeger](https://github.com/manoj9788/tracing-selenium-grid)

## Explorando logs de eventos

O rastreamento deve estar habilitado para o registro de eventos, mesmo que alguém não deseje exportar rastreamentos para visualizá-los.

**Por padrão, o rastreamento está habilitado. Não é necessário passar parâmetros adicionais para ver os logs no console.**

Todos os eventos dentro de um segmento são registrados no nível FINE. Eventos de erro são registrados no nível WARN..

| Campo               | Valor do Campo  | Descrição                                                                                                                                                                                                                    |
| ------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Hora do Evento      | eventId         | Carimbo de data/hora do registro do evento em nanossegundos desde a época.                                                                                                                                                   |
| ID de Rastreamento  | tracedId        | Cada rastreamento é identificado exclusivamente por um ID de rastreamento.                                                                                                                                                   |
| ID de Segmento      | spanId          | Cada segmento dentro de um rastreamento é identificado exclusivamente por um ID de segmento.                                                                                                                                 |
| Tipo de Segmento    | spanKind        | O tipo de segmento é uma propriedade do segmento que indica o tipo de segmento. Isso ajuda a entender a natureza da unidade de trabalho realizada pelo segmento.                                                             |
| Nome do Evento      | eventName       | Isso mapeia para a mensagem de registro.                                                                                                                                                                                     |
| Atributos do Evento | eventAttributes | Isso forma a essência dos registros de eventos, com base na operação executada, ele contém pares chave-valor formatados em JSON. Isso também inclui um atributo de classe do manipulador, para mostrar a classe do registro. |

Simples log

```
FINE [LoggingOptions$1.lambda$export$1] - {
  "traceId": "fc8aef1d44b3cc8bc09eb8e581c4a8eb",
  "spanId": "b7d3b9865d3ddd45",
  "spanKind": "INTERNAL",
  "eventTime": 1597819675128886121,
  "eventName": "Session request execution complete",
  "attributes": {
    "http.status_code": 200,
    "http.handler_class": "org.openqa.selenium.grid.router.HandleSession",
    "http.url": "\u002fsession\u002fdd35257f104bb43fdfb06242953f4c85",
    "http.method": "DELETE",
    "session.id": "dd35257f104bb43fdfb06242953f4c85"
  }
}
```

Além dos campos mencionados anteriormente, com base na [especificação do OpenTelemetry](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/exceptions.md) os registros de erro consistem nos seguintes campos: :

| Campo                   | Valor do Campo       | Descrição                                                                                                  |
| ----------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------- |
| Tipo de Exceção         | exception.type       | O nome da classe da exceção.                                                                               |
| Mensagem da Exceção     | exception.message    | Motivo da exceção.                                                                                         |
| Rastreamento de Exceção | exception.stacktrace | Imprime a pilha de chamadas no momento em que a exceção foi lançada. Ajuda a entender a origem da exceção. |

Simples error log

```
WARN [LoggingOptions$1.lambda$export$1] - {
  "traceId": "7efa5ea57e02f89cdf8de586fe09f564",
  "spanId": "914df6bc9a1f6e2b",
  "spanKind": "INTERNAL",
  "eventTime": 1597820253450580272,
  "eventName": "exception",
  "attributes": {
    "exception.type": "org.openqa.selenium.ScriptTimeoutException",
    "exception.message": "Unable to execute request: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist ..." (full message will be printed),
    "exception.stacktrace": "org.openqa.selenium.ScriptTimeoutException: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist\nBuild info: version: '4.0.0-alpha-7', revision: 'Unknown'\nSystem info: host: 'XYZ-MacBook-Pro.local', ip: 'fe80:0:0:0:10d5:b63a:bdc6:1aff%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.7'\nDriver info: driver.version: unknown ...." (full stack will be printed),
    "http.handler_class": "org.openqa.selenium.grid.distributor.remote.RemoteDistributor",
    "http.url": "\u002fsession",
    "http.method": "POST"
  }
}
```

**Observação:** Os logs são formatados acima para facilitar a leitura. A formatação de logs está desativada no servidor Selenium.

Os passos acima devem configurá-lo para visualizar rastreamentos e logs.

## Referências

1. [Compreendendo o Rastreamento](https://lightstep.com/blog/opentelemetry-101-what-is-tracing/)
2. [Especificação da API de Rastreamento do OpenTelemetry](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/api.md#status)
3. [Selenium Wiki](https://github.com/SeleniumHQ/selenium/wiki)
4. [Logs Estruturados vs. Eventos](https://www.honeycomb.io/blog/how-are-structured-logs-different-from-events/)
5. [Framework Jaeger](https://github.com/jaegertracing/jaeger)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/browsers/chrome/
----

# Funcionalidade específica do Chrome

```java
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L36-L37)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L9-L10)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L30-L31)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L51-L55)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_argument("--start-maximized")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L18)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L39)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.args << '--start-maximized'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L17)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L9-L12)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L53)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.binary_location = chrome_bin
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L29)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L49)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.add_argument("--user-data-dir=#{user_data_dir}")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L25)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L41-L44)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
  @DisabledOnOs(OS.WINDOWS)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L64)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_extension(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L40)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L73-L84)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
    it 'add extensions' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L34)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L62-L66)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```py
    options.add_experimental_option("detach", True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L51)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

**Note**: This is already the default behavior in .NET.

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L45)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L29-L32)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L78)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L62)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L82)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L53)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L19-L22)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L100-L101)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY`\
Property value: String representing path to log file

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L71)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L86)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service = Selenium::WebDriver::Service.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L67)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L114-L115)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L82)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

`$stdout` and `$stderr` are both valid values

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service = Selenium::WebDriver::Service.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L76)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L129-L130)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY`\
Property value: String representation of `ChromiumDriverLogLevel` enum

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L93)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L87)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L147-L148)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows toggling these features by System Property:\
Property keys: `ChromeDriverService.CHROME_DRIVER_APPEND_LOG_PROPERTY` and `ChromeDriverService.CHROME_DRIVER_READABLE_TIMESTAMP`\
Property value: `"true"` or `"false"`

```py
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L104)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service = Selenium::WebDriver::Service.chrome(args: args)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L97-L98)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L166-L167)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows disabling build checks by System Property:\
Property key: `ChromeDriverService.CHROME_DRIVER_DISABLE_BUILD_CHECK`\
Property value: `"true"` or `"false"`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L115)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            service.DisableBuildCheck = true;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L155)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L108)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L230-L235)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L170-L174)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L119-L124)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L204-L210)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L129-L135)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
    it 'gets and sets network conditions' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L129)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L247)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    logs = driver.get_log("browser")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L186)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver = Selenium::WebDriver.for :chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L141)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    options.setBrowserVersion("stable");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L189)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    driver.set_permissions('camera', 'denied')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L149)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L149-L150)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### DevTools

Veja a secção \[Chrome DevTools] para mais informação em como usar Chrome DevTools

Última modificação April 19, 2026: [\[dotnet\] fix: test (25b39a556d7)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/25b39a556d73f3c0aff65f33da011b33b8c4d202)

----
url: https://www.selenium.dev/ja/documentation/webdriver/bidi/network/
----

# WebDriver BiDi Network Features

These features are related to networking, and are made available via a “network” namespace.

The implementation of these features is being tracked here: [#13993](https://github.com/SeleniumHQ/selenium/issues/13993)

Remember that to use WebDriver BiDi, you must enable it in Options. For more details, see [Enabling BiDi](https://www.selenium.dev/ja/documentation/webdriver/bidi/)

```rb
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds an auth handler', skip: 'Do not execute BiDi test' do
    driver.network.add_authentication_handler('test', 'test')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/network_spec.rb#L7-L11)

##### /examples/ruby/spec/bidi/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network', exclusive: {bidi: true, reason: 'only executed when bidi is enabled'},
                          only: {browser: %i[chrome edge firefox]} do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds an auth handler', skip: 'Do not execute BiDi test' do
    driver.network.add_authentication_handler('test', 'test')
    driver.navigate.to url_for('basicAuth')
    expect(driver.find_element(tag_name: 'h1').text).to eq('authorized')
  end
end
```

最終更新 August 18, 2025: [Fix path for codeblock (cb0bfc20fdf)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/cb0bfc20fdf56dfe6b16733e84cee540f2ffe04e)

----
url: https://www.selenium.dev/_print/documentation/webdriver/getting_started/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/webdriver/getting_started/).

# Getting started

If you are new to Selenium, we have a few resources that can help you get up to speed right away.

* 1: [Install a Selenium library](#pg-e44416da7e326d1e4a15fb932badef45)
* 2: [Write your first Selenium script](#pg-422333a0d0201faac798caa658508cf1)
* 3: [Organizing and Executing Selenium Code](#pg-23b7e1ca67e6c934ea40b738b1cbdf41)

# 1 - Install a Selenium library

```xml
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/pom.xml#L35-L38)

##### /examples/java/pom.xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>dev.selenium</groupId>
    <artifactId>selenium-examples</artifactId>
    <version>1.0.0</version>

    <properties>
        <surefire.parallel>1</surefire.parallel>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <selenium.version>4.41.0</selenium.version>
    </properties>

    <repositories>
        <repository>
            <name>Central Portal Snapshots</name>
            <id>central-portal-snapshots</id>
            <url>https://central.sonatype.com/repository/maven-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-grid</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>6.0.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.titusfortner</groupId>
            <artifactId>selenium-logger</artifactId>
            <version>2.4.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.5.5</version>
                <configuration>
                    <properties>
                        <configurationParameters>
                            junit.jupiter.execution.parallel.enabled = true
                            junit.jupiter.execution.parallel.mode.default = concurrent
                            junit.jupiter.execution.parallel.config.strategy = fixed
                            junit.jupiter.execution.parallel.config.fixed.parallelism = ${surefire.parallel}
                            junit.jupiter.execution.parallel.config.fixed.max-pool-size = ${surefire.parallel}
                        </configurationParameters>
                    </properties>
                    <rerunFailingTestsCount>3</rerunFailingTestsCount>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
```

### Gradle

Specify the dependency in the project `build.gradle` file as `testImplementation`:

```gradle

dependencies {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/build.gradle#L13-L14)

##### /examples/java/build.gradle

```gradle
plugins {
    id 'java'
}

group 'dev.selenium'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

ext['seleniumVersion'] = System.getProperty('selenium.version', '4.41.0')

dependencies {
    testImplementation "org.seleniumhq.selenium:selenium-java:${seleniumVersion}"
    testImplementation "org.seleniumhq.selenium:selenium-grid:${seleniumVersion}"
    testImplementation platform("org.junit:junit-bom:6.0.2")
    testImplementation 'org.junit.jupiter:junit-jupiter-engine'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    testImplementation 'com.titusfortner:selenium-logger:2.4.0'
}

test {
    useJUnitPlatform()
}
```

The minimum supported Python version for each Selenium version can be found in “Supported Python Versions” on [PyPi](https://pypi.org/project/selenium/).

There are a couple different ways to install Selenium.

### Pip

```shell
pip install selenium
```



### Download

Alternatively you can download the [PyPI Built Distribution](https://pypi.org/project/selenium/#files) (selenium-x.x.x.-py3-none-any.whl) and install it using *pip*:

```shell
pip install selenium-x.x.x.-py3-none-any.whl
```



### Require in project

To use it in a project, add it to the `requirements.txt` file:

```txt
selenium==4.41.0
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/requirements.txt#L1)

##### /examples/python/requirements.txt

```txt
selenium==4.41.0
pytest==9.0.3
trio==0.31.0
pytest-trio==0.8.0
pytest-rerunfailures==16.1
flake8==7.3.0
requests==2.33.0
tox==4.32.0
pytest-xdist==3.8.0
```

A list of all supported frameworks for each version of Selenium is available on [Nuget](https://www.nuget.org/packages/Selenium.WebDriver)

There are a few options for installing Selenium.

### Packet Manager

```shell
Install-Package Selenium.WebDriver
```



### .NET CLI

```shell
dotnet add package Selenium.WebDriver
```



### CSProj

in the project’s `csproj` file, specify the dependency as a `PackageReference` in `ItemGroup`:

```csproj
      <PackageReference Include="Selenium.WebDriver" Version="4.41.0" />
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/SeleniumDocs.csproj#L14)

##### /examples/dotnet/SeleniumDocs/SeleniumDocs.csproj

```csproj
<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <GenerateProgramFile>false</GenerateProgramFile>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
      <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="7.7.1" />
      <PackageReference Include="MSTest.TestAdapter" Version="3.6.0" />
      <PackageReference Include="MSTest.TestFramework" Version="3.6.0" />
      <PackageReference Include="Selenium.Support" Version="4.41.0" />
      <PackageReference Include="Selenium.WebDriver" Version="4.41.0" />
    </ItemGroup>

    <ItemGroup>
      <Folder Include="LocalPackages" />
    </ItemGroup>

</Project>
```

### Additional considerations

Further items of note for using Visual Studio Code (vscode) and C#

Install the compatible .NET SDK as per the section above. Also install the vscode extensions (Ctrl-Shift-X) for C# and NuGet. Follow the [instruction here](https://docs.microsoft.com/en-us/dotnet/core/tutorials/with-visual-studio-code?pivots=dotnet-5-0) to create and run the “Hello World” console project using C#. You may also create a NUnit starter project using the command line `dotnet new NUnit`. Make sure the file `%appdata%\NuGet\nuget.config` is configured properly as some developers reported that it will be empty due to some issues. If `nuget.config` is empty, or not configured properly, then .NET builds will fail for Selenium Projects. Add the following section to the file `nuget.config` if it is empty:

```
<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />   
  </packageSources>
...
```

For more info about `nuget.config` [click here](https://docs.microsoft.com/en-us/nuget/reference/nuget-config-file). You may have to customize `nuget.config` to meet you needs.

Now, go back to vscode, press Ctrl-Shift-P, and type “NuGet Add Package”, and enter the required Selenium packages such as `Selenium.WebDriver`. Press Enter and select the version. Now you can use the examples in the documentation related to C# with vscode.

You can see the minimum required version of Ruby for any given Selenium version on [rubygems.org](https://rubygems.org/gems/selenium-webdriver/)

Selenium can be installed two different ways.

### Install manually

```shell
gem install selenium-webdriver
```



### Add to project’s gemfile

```gemfile
gem 'selenium-devtools', '= 0.147.0'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/Gemfile#L10)

##### /examples/ruby/Gemfile

```gemfile
# frozen_string_literal: true

source 'https://rubygems.org'

gem 'ffi', '~> 1.15', '>= 1.15.5' if Gem.win_platform? # Windows only
gem 'rake', '~> 13.0'
gem 'rspec', '~> 3.0'
gem 'rubocop', '~> 1.35'
gem 'rubocop-rspec', '~> 3.0'
gem 'selenium-devtools', '= 0.147.0'
gem 'selenium-webdriver', '= 4.43.0'
```

You can find the minimum required version of Node for any given version of Selenium in the `Node Support Policy` section on [npmjs](https://www.npmjs.com/package/selenium-webdriver)

Selenium is typically installed using npm.

### Install locally

```shell
npm install selenium-webdriver
```



### Add to project

In your project’s `package.json`, add requirement to `dependencies`:

```json
        "mocha": "11.7.5"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/package.json#L14)

##### /examples/javascript/package.json

```json
{
    "name": "javascript-examples",
    "version": "1.0.0",
    "scripts": {
        "test": "npx mocha test/**/*.spec.js --timeout 120000 --parallel --retries 2"
    },
    "author": "The Selenium project",
    "license": "Apache-2.0",
    "dependencies": {
        "assert": "2.1.0",
        "selenium-webdriver": "4.41.0"
    },
    "devDependencies": {
        "mocha": "11.7.5"
    }
}
```

Use the Java bindings for Kotlin.

## Next Step

[Create your first Selenium script](https://www.selenium.dev/documentation/webdriver/getting_started/first_script/)

# 2 - Write your first Selenium script

```java
        WebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver = webdriver.Chrome()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L4)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L11)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver = Selenium::WebDriver.for :chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L3)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    driver = await new Builder().forBrowser(Browser.CHROME).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L8)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver = ChromeDriver()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L16)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.get("https://www.selenium.dev/selenium/web/web-form.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L6)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L13)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.get('https://www.selenium.dev/selenium/web/web-form.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L5)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L9)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.get("https://www.selenium.dev/selenium/web/web-form.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L18)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#16)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L8)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var title = driver.Title;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L15)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L7)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let title = await driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L11)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L20)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L18)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.implicitly_wait(0.5)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L10)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L17)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.manage.timeouts.implicit_wait = 500
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L9)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.manage().setTimeouts({implicit: 500});
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L14)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L23)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L20-L21)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L12-L13)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L19-L20)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L11-L12)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L16-L17)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L25-L26)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        textBox.sendKeys("Selenium");
        submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L23-L24)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
text_box.send_keys("Selenium")
submit_button.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L15-L16)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        textBox.SendKeys("Selenium");
        submitButton.Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
text_box.send_keys('Selenium')
submit_button.click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L14-L15)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await textBox.sendKeys('Selenium');
    await submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L19-L20)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        textBox.sendKeys("Selenium")
        submitButton.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L28-L29)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        WebElement message = driver.findElement(By.id("message"));
        message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-27)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
message = driver.find_element(by=By.ID, value="message")
text = message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L18-19)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-26)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
message = driver.find_element(id: 'message')
message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L17-18)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L22-23)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val message = driver.findElement(By.id("message"))
        val value = message.getText()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-32)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L21)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L28)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L20)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L28)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L35)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```md
mvn exec:java -D"exec.mainClass"="dev.selenium.getting_started.FirstScript" -D"exec.classpathScope"=test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/README.md#L60)

##### /examples/java/README.md

````md
# Running Selenium Java Tests
The following steps will guide you on how to 
run Selenium Java tests using a repository 
of `SeleniumHQ/seleniumhq.github.io` examples.

## Initial Setup

### Prerequisites

Ensure that Java Development Kit (JDK) and Maven 
are installed on your system. If they are not installed, 
you will need to download and install them. You can 
find detailed installation guides for both on their 
respective official sites.

### Clone the repository
First, we need to get the Selenium Java examples 
on your local machine. This can be done by 
cloning the `SeleniumHQ/seleniumhq.github.io` Git repository. 
Run the following command in your terminal:

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```
## Navigate to the java directory
After cloning the repository, navigate into the 
directory where the Selenium Java examples are 
located. Run the following command:

```bash
cd seleniumhq.github.io/examples/java
```

## Running the Tests
### Install dependencies
Before running the tests, we need to install all 
necessary dependencies. Maven, a software 
project management tool, can do this for us. 
Run the following command:

```bash
mvn test-compile
```

### Run all tests
To verify if everything is installed correctly and 
functioning properly, we should run all 
available tests. This can be done with the following command:

```bash
mvn test
```

Please be patient! If this is your first time running these tests, 
it might take a while to download and verify all necessary browser drivers.

## Execute a specific example
To run a specific Selenium Java example, use the following command:
```bash
mvn exec:java -D"exec.mainClass"="dev.selenium.getting_started.FirstScript" -D"exec.classpathScope"=test
```

Make sure to replace `dev.selenium.getting_started.FirstScript` with the path and name of the example you want to run.
````

```md
pytest path/to/test_script.py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/README.md#L58)

##### /examples/python/README.md

````md
# Running tests from Selenium Python examples

#### 1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

#### 2. Navigate to `python` directory

```
cd seleniumhq.github.io/examples/python
```

#### 3. Create a virtual environment

- On Windows:

```
py -m venv venv
venv\Scripts\activate
```

- On Linux/Mac:

```
python3 -m venv venv
source venv/bin/activate
```

#### 4. Install dependencies:

```
pip install -r requirements.txt
```

> for help, see: https://packaging.python.org/en/latest/tutorials/installing-packages

#### 5. Run tests

- Run all tests with the default Python interpreter:

```
pytest
```

- Run all tests with every installed/supported Python interpreter:

```
tox
```

> Please have some patience - If you are doing it for the first time, it will take a little while to download the browser drivers

- Run a specific example:

```
pytest path/to/test_script.py
```

> Make sure to replace `path/to/test_script.py` with the path and name of the example you want to run
````

```md
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/README.md#L55)

##### /examples/dotnet/README.md

````md
# Running Selenium .NET (C#) Tests

The following steps will guide you on how to  
run Selenium .NET (C#) tests using the examples  
from the `SeleniumHQ/seleniumhq.github.io` repository.

## Initial Setup

### Prerequisites

Ensure you have the following installed:

- [.NET SDK (8.0 or later)](https://dotnet.microsoft.com/en-us/download)
- An IDE like [Visual Studio](https://visualstudio.microsoft.com/) or [Visual Studio Code](https://code.visualstudio.com/)
- [.NET CLI tools](https://learn.microsoft.com/en-us/dotnet/core/tools/)

### Clone the repository

Clone the Selenium documentation repository to your local machine:

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

## Navigate to the .NET directory
### Change into the .NET examples directory:

```bash
cd seleniumhq.github.io/examples/dotnet/SeleniumDocs
```

## Running the Tests
### Restore dependencies
Install necessary dependencies using the .NET CLI:

```bash
dotnet restore
```

### Run all tests
To run all available tests:

```bash
dotnet test
```

### Run a Specific Test Method
To run a specific test method using its fully qualified name:

```bash
dotnet test --filter "FullyQualifiedName=Namespace.ClassName.MethodName"
```
For example:
```bash
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

You can also filter by test name only (if it's unique):
```bash
dotnet test --filter "Name=EightComponents"
```
````

```md
ruby example_script.rb
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/README.md#L36)

##### /examples/ruby/README.md

````md
# Running all tests from Selenium ruby example

Follow these steps to run all test example from selenium ruby

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `ruby` directory

```
cd seleniumhq.github.io/examples/ruby
```

3. Install dependencies using bundler

```
bundler install
```

4. Run all tests

```
bundle exec rspec
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a ruby script

Use this command to run a ruby script and follow the first script example

```
ruby example_script.rb
```
````

```md
node example_script.spec.js
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/README.md#L36)

##### /examples/javascript/README.md

````md
# Running all tests from Selenium javascript example

Follow these steps to run all test example from selenium javascript

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `javascript` directory

```
cd seleniumhq.github.io/examples/javascript
```

3. Install dependencies using node

```
npm install
```

4. Run all all tests

```
npm test
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a javascript test

Use this command to run a JavaScript and follow the first script example

```
node example_script.spec.js
```
````

[Add Example](/documentation/about/contributing/#creating-examples)

## Next Steps

Most Selenium users execute many sessions and need to organize them to minimize duplication and keep the code more maintainable. Read on to learn about how to put this code into context for your use case with [Using Selenium](https://www.selenium.dev/documentation/webdriver/getting_started/using_selenium/).

# 3 - Organizing and Executing Selenium Code

```java
		String title = driver.getTitle();
		assertEquals("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L30-L31)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java
package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

```py
    title = driver.title
    assert title == "Web form"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L8-L9)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

```cs
            var title = driver.Title;
            Assert.AreEqual("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs#L19-L20)

##### /examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted
{
    [TestClass]
    public class UsingSeleniumTest
    {

        [TestMethod]
        public void EightComponents()
        {
            IWebDriver driver = new ChromeDriver();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

            var title = driver.Title;
            Assert.AreEqual("Web form", title);

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            var textBox = driver.FindElement(By.Name("my-text"));
            var submitButton = driver.FindElement(By.TagName("button"));
            
            textBox.SendKeys("Selenium");
            submitButton.Click();
            
            var message = driver.FindElement(By.Id("message"));
            var value = message.Text;
            Assert.AreEqual("Received!", value);
            
            driver.Quit();
        }
    }
}
```

```rb
    title = @driver.title
    expect(title).to eq('Web form')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb#L14-L15)

##### /examples/ruby/spec/getting\_started/using\_selenium\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

```js
    let title = await driver.getTitle();
    assert.equal("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L14-L15)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

```java
	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L19-L22)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java
package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

### Tear Down

```java
	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L45-L48)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java
package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

### Set Up

```py
def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L25-L28)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

### Tear Down

```py
def teardown(driver):
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L30-31)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

### Set Up

```rb
  before do
    @driver = Selenium::WebDriver.for :chrome
  end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb#L7-L9)

##### /examples/ruby/spec/getting\_started/using\_selenium\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

### Tear Down

```rb
  config.after { @driver&.quit }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/spec_helper.rb#L30)

##### /examples/ruby/spec/spec\_helper.rb

```rb
# frozen_string_literal: true

require 'selenium-webdriver'
require 'selenium/webdriver/support/guards'

RSpec.configure do |config|
  # Enable flags like --only-failures and --next-failure
  config.example_status_persistence_file_path = '.rspec_status'

  # Disable RSpec exposing methods globally on `Module` and `main`
  config.disable_monkey_patching!
  Dir.mktmpdir('tmp')
  config.example_status_persistence_file_path = 'tmp/examples.txt'

  config.expect_with :rspec do |c|
    c.syntax = :expect
  end

  config.before do |example|
    bug_tracker = 'https://github.com/SeleniumHQ/seleniumhq.github.io/issues'
    guards = Selenium::WebDriver::Support::Guards.new(example,
                                                      bug_tracker: bug_tracker)
    guards.add_condition(:platform, Selenium::WebDriver::Platform.os)
    guards.add_condition(:ci, Selenium::WebDriver::Platform.ci)

    results = guards.disposition
    send(*results) if results
  end

  config.after { @driver&.quit }

  def start_session
    options = Selenium::WebDriver::Chrome::Options.new
    options.add_argument('disable-search-engine-choice-screen')
    options.add_argument('--no-sandbox')
    @driver = Selenium::WebDriver.for(:chrome, options: options)
  end

  def start_bidi_session
    options = Selenium::WebDriver::Chrome::Options.new(web_socket_url: true)
    @driver = Selenium::WebDriver.for :chrome, options: options
  end

  def start_firefox
    options = Selenium::WebDriver::Options.firefox(timeouts: {implicit: 1500})
    @driver = Selenium::WebDriver.for :firefox, options: options
  end
end
```

\### Set Up

```js
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L7-L9)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

\### Tear Down

```js
  after(async () => await driver.quit());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L30)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

```shell
mvn clean test
```

### Gradle

```shell
gradle clean test
```

````md
```
````

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/README.md#L35)

##### /examples/python/README.md

````md
# Running tests from Selenium Python examples

#### 1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

#### 2. Navigate to `python` directory

```
cd seleniumhq.github.io/examples/python
```

#### 3. Create a virtual environment

- On Windows:

```
py -m venv venv
venv\Scripts\activate
```

- On Linux/Mac:

```
python3 -m venv venv
source venv/bin/activate
```

#### 4. Install dependencies:

```
pip install -r requirements.txt
```

> for help, see: https://packaging.python.org/en/latest/tutorials/installing-packages

#### 5. Run tests

- Run all tests with the default Python interpreter:

```
pytest
```

- Run all tests with every installed/supported Python interpreter:

```
tox
```

> Please have some patience - If you are doing it for the first time, it will take a little while to download the browser drivers

- Run a specific example:

```
pytest path/to/test_script.py
```

> Make sure to replace `path/to/test_script.py` with the path and name of the example you want to run
````

```md
dotnet test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/README.md#L44)

##### /examples/dotnet/README.md

````md

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

## Navigate to the .NET directory
### Change into the .NET examples directory:

```bash
cd seleniumhq.github.io/examples/dotnet/SeleniumDocs
```

## Running the Tests
### Restore dependencies
Install necessary dependencies using the .NET CLI:

```bash
dotnet restore
```

### Run all tests
To run all available tests:

```bash
dotnet test
```

### Run a Specific Test Method
To run a specific test method using its fully qualified name:

```bash
dotnet test --filter "FullyQualifiedName=Namespace.ClassName.MethodName"
```
For example:
```bash
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

You can also filter by test name only (if it's unique):
```bash
dotnet test --filter "Name=EightComponents"
```
````

```md
bundle exec rspec
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/README.md#L26)

##### /examples/ruby/README.md

````md
# Running all tests from Selenium ruby example

Follow these steps to run all test example from selenium ruby

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `ruby` directory

```
cd seleniumhq.github.io/examples/ruby
```

3. Install dependencies using bundler

```
bundler install
```

4. Run all tests

```
bundle exec rspec
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a ruby script

Use this command to run a ruby script and follow the first script example

```
ruby example_script.rb
```
````

### Mocha

```shell
mocha runningTests.spec.js
```

### npx

```shell
npx mocha runningTests.spec.js
```

[Add Example](/documentation/about/contributing/#creating-examples)

### Examples

In [First script](https://www.selenium.dev/documentation/webdriver/getting_started/first_script/), we saw each of the components of a Selenium script. Here’s an example of that code using a test runner:

*
*
*
*
*
*

```java

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java)

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py)

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted
{
    [TestClass]
    public class UsingSeleniumTest
    {

        [TestMethod]
        public void EightComponents()
        {
            IWebDriver driver = new ChromeDriver();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

            var title = driver.Title;
            Assert.AreEqual("Web form", title);

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            var textBox = driver.FindElement(By.Name("my-text"));
            var submitButton = driver.FindElement(By.TagName("button"));
            
            textBox.SendKeys("Selenium");
            submitButton.Click();
            
            var message = driver.FindElement(By.Id("message"));
            var value = message.Text;
            Assert.AreEqual("Received!", value);
            
            driver.Quit();
        }
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs)

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb)

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js)

[Add Example](/documentation/about/contributing/#creating-examples)

## Next Steps

Take what you’ve learned and build out your Selenium code!

As you find more functionality that you need, read up on the rest of our [WebDriver documentation](https://www.selenium.dev/documentation/webdriver/).

## Development Partners

[](https://www.browserstack.com/automate?utm_campaign=open-source-sponsor\&utm_campaigncode=701OW000009sQwVYAU\&utm_medium=partnered\&utm_source=seleniumorg)

[](https://saucelabs.com/resources/topic-hub/selenium?utm_source=selenium\&utm_medium=website\&utm_campaign=selenium-sponsorship-fy25)

[](https://www.testmuai.com)

## Selenium Level Sponsors

[](https://brightdata.com/?utm_source=brand\&utm_campaign=brnd-mkt_partners_selenium)

[](https://applitools.com/)

[](https://www.thordata.com/?ls=waOicIkB\&lk=selenium)

## Support the Selenium Project

Learn more or view the full list of sponsors.

[Learn more**](/sponsors)

----
url: https://www.selenium.dev/documentation/webdriver/waits/
----

# Waiting Strategies

Perhaps the most common challenge for browser automation is ensuring that the web application is in a state to execute a particular Selenium command as desired. The processes often end up in a *race condition* where sometimes the browser gets into the right state first (things work as intended) and sometimes the Selenium code executes first (things do not work as intended). This is one of the primary causes of *flaky tests*.

All navigation commands wait for a specific `readyState` value based on the [page load strategy](https://www.selenium.dev/documentation/webdriver/drivers/options/#pageloadstrategy) (the default value to wait for is `"complete"`) before the driver returns control to the code. The `readyState` only concerns itself with loading assets defined in the HTML, but loaded JavaScript assets often result in changes to the site, and elements that need to be interacted with may not yet be on the page when the code is ready to execute the next Selenium command.

Similarly, in a lot of single page applications, elements get dynamically added to a page or change visibility based on a click. An element must be both present and [displayed](https://www.selenium.dev/documentation/webdriver/elements/information/#is-displayed) on the page in order for Selenium to interact with it.

Take this page for example: <https://www.selenium.dev/selenium/web/dynamic.html> When the “Add a box!” button is clicked, a “div” element that does not exist is created. When the “Reveal a new input” button is clicked, a hidden text field element is displayed. In both cases the transition takes a couple seconds. If the Selenium code is to click one of these buttons and interact with the resulting element, it will do so before that element is ready and fail.

The first solution many people turn to is adding a sleep statement to pause the code execution for a set period of time. Because the code can’t know exactly how long it needs to wait, this can fail when it doesn’t sleep long enough. Alternately, if the value is set too high and a sleep statement is added in every place it is needed, the duration of the session can become prohibitive.

Selenium provides two different mechanisms for synchronization that are better.

## Implicit waits

Selenium has a built-in way to automatically wait for elements called an *implicit wait*. An implicit wait value can be set either with the [timeouts](https://www.selenium.dev/documentation/webdriver/drivers/options/#timeouts) capability in the browser options, or with a driver method (as shown below).

```java
    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L50)

##### /examples/java/src/test/java/dev/selenium/waits/WaitsTest.java

```java
package dev.selenium.waits;

import dev.selenium.BaseTest;
import java.time.Duration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.ElementNotInteractableException;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

public class WaitsTest extends BaseTest {
  @Test
  public void fails() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Assertions.assertThrows(
        NoSuchElementException.class,
        () -> {
          driver.findElement(By.id("box0"));
        });
  }

  @Test
  public void sleep() throws InterruptedException {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Thread.sleep(1000);

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void implicit() {
    startChromeDriver(new ChromeOptions());

    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void explicit() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    wait.until(d -> revealed.isDisplayed());

    revealed.sendKeys("Displayed");
    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }

  @Test
  public void explicitWithOptions() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait =
        new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(2))
            .pollingEvery(Duration.ofMillis(300))
            .ignoring(ElementNotInteractableException.class);

    wait.until(
        d -> {
          revealed.sendKeys("Displayed");
          return true;
        });

    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }
}
```

```py
    driver.implicitly_wait(2)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/waits/test_waits.py#L27)

##### /examples/python/tests/waits/test\_waits.py

```py
import pytest
import time
from selenium.common import NoSuchElementException, ElementNotInteractableException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


def test_fails(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    with pytest.raises(NoSuchElementException):
        driver.find_element(By.ID, 'box0')


def test_sleep(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    time.sleep(2)
    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_implicit(driver):
    driver.implicitly_wait(2)
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_explicit(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(lambda _ : revealed.is_displayed())

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"


def test_explicit_options(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    errors = [NoSuchElementException, ElementNotInteractableException]
    wait = WebDriverWait(driver, timeout=2, poll_frequency=.2, ignored_exceptions=errors)
    wait.until(lambda _ : revealed.send_keys("Displayed") or True)

    assert revealed.get_property("value") == "Displayed"
```

```cs
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L39)

##### /examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs

```cs
using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Waits
{
    [TestClass]
    public class WaitsTest : BaseChromeTest
    {
        [TestMethod]
        public void Fails()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Assert.ThrowsException<NoSuchElementException>(
                () => driver.FindElement(By.Id("box0"))
            );
        }

        [TestMethod]
        public void Sleep()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Thread.Sleep(1000);

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Implicit()
        {
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
            
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Explicit()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2));
            wait.Until(d => revealed.Displayed);

            revealed.SendKeys("Displayed");
            Assert.AreEqual("Displayed", revealed.GetDomProperty("value"));
        }

        [TestMethod]
        public void ExplicitOptions()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2))
            {
                PollingInterval = TimeSpan.FromMilliseconds(300),
            };
            wait.IgnoreExceptionTypes(typeof(ElementNotInteractableException));

            wait.Until(d => {
                revealed.SendKeys("Displayed");
                return true;
            });

            Assert.AreEqual("input", revealed.TagName);
        }
    }
}
```

```rb
    driver.manage.timeouts.implicit_wait = 2
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/waits/waits_spec.rb#L28)

##### /examples/ruby/spec/waits/waits\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Waits' do
  let(:driver) { start_session }

  it 'fails' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    expect {
      driver.find_element(id: 'box0')
    }.to raise_error(Selenium::WebDriver::Error::NoSuchElementError)
  end

  it 'sleeps' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    sleep 1
    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'implicit' do
    driver.manage.timeouts.implicit_wait = 2
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    wait = Selenium::WebDriver::Wait.new
    wait.until { revealed.displayed? }

    revealed.send_keys('Displayed')
    expect(revealed.property(:value)).to eq('Displayed')
  end

  it 'options with explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    errors = [Selenium::WebDriver::Error::NoSuchElementError,
              Selenium::WebDriver::Error::ElementNotInteractableError]
    wait = Selenium::WebDriver::Wait.new(timeout: 2,
                                         interval: 0.3,
                                         ignore: errors)

    wait.until { revealed.send_keys('Displayed') || true }

    expect(revealed.property(:value)).to eq('Displayed')
  end
end
```

```js
        await driver.manage().setTimeouts({ implicit: 2000 });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/waits/waits.spec.js#L39)

##### /examples/javascript/test/waits/waits.spec.js

```js

const { By, Browser, until, Builder} = require('selenium-webdriver');
const assert = require("node:assert");


describe('Waits', function () {
    let driver;

    before(async function () {
        driver = new Builder()
          .forBrowser(Browser.CHROME)
          .build();
    });

    after(async () => await driver.quit());

    it('fail', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        await assert.rejects(async () => {
              await driver.findElement(By.id("box0"))
          },
          Error
        )
    });

    it('sleep', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        await driver.sleep(2000);
        let added = await driver.findElement(By.id("box0"));

        assert.equal(await added.getAttribute('class'), "redbox")
    });

    it('implicit', async function () {
        await driver.manage().setTimeouts({ implicit: 2000 });
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        let added = await driver.findElement(By.id("box0"));

        assert.equal(await added.getAttribute('class'), "redbox")
    });

    it('explicit', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        let revealed = await driver.findElement(By.id("revealed"));
        await driver.findElement(By.id("reveal")).click();
        await driver.wait(until.elementIsVisible(revealed), 2000);
        await revealed.sendKeys("Displayed");
        assert.equal(await revealed.getAttribute("value"), "Displayed")
    })
});
```

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk/examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt#L19)

##### examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt

```kt
```

This example shows the condition being waited for as a *lambda*. Java also supports [Expected Conditions](https://www.selenium.dev/documentation/webdriver/support_features/expected_conditions/)

```java
    Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    wait.until(d -> revealed.isDisplayed());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L67-L68)

##### /examples/java/src/test/java/dev/selenium/waits/WaitsTest.java

```java
package dev.selenium.waits;

import dev.selenium.BaseTest;
import java.time.Duration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.ElementNotInteractableException;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

public class WaitsTest extends BaseTest {
  @Test
  public void fails() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Assertions.assertThrows(
        NoSuchElementException.class,
        () -> {
          driver.findElement(By.id("box0"));
        });
  }

  @Test
  public void sleep() throws InterruptedException {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Thread.sleep(1000);

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void implicit() {
    startChromeDriver(new ChromeOptions());

    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void explicit() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    wait.until(d -> revealed.isDisplayed());

    revealed.sendKeys("Displayed");
    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }

  @Test
  public void explicitWithOptions() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait =
        new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(2))
            .pollingEvery(Duration.ofMillis(300))
            .ignoring(ElementNotInteractableException.class);

    wait.until(
        d -> {
          revealed.sendKeys("Displayed");
          return true;
        });

    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }
}
```

This example shows the condition being waited for as a *lambda*. Python also supports [Expected Conditions](https://www.selenium.dev/documentation/webdriver/support_features/expected_conditions/)

```py
    wait = WebDriverWait(driver, timeout=2)
    wait.until(lambda _ : revealed.is_displayed())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/waits/test_waits.py#L41-L42)

##### /examples/python/tests/waits/test\_waits.py

```py
import pytest
import time
from selenium.common import NoSuchElementException, ElementNotInteractableException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


def test_fails(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    with pytest.raises(NoSuchElementException):
        driver.find_element(By.ID, 'box0')


def test_sleep(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    time.sleep(2)
    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_implicit(driver):
    driver.implicitly_wait(2)
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_explicit(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(lambda _ : revealed.is_displayed())

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"


def test_explicit_options(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    errors = [NoSuchElementException, ElementNotInteractableException]
    wait = WebDriverWait(driver, timeout=2, poll_frequency=.2, ignored_exceptions=errors)
    wait.until(lambda _ : revealed.send_keys("Displayed") or True)

    assert revealed.get_property("value") == "Displayed"
```

```cs
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2));
            wait.Until(d => revealed.Displayed);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L56-L57)

##### /examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs

```cs
using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Waits
{
    [TestClass]
    public class WaitsTest : BaseChromeTest
    {
        [TestMethod]
        public void Fails()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Assert.ThrowsException<NoSuchElementException>(
                () => driver.FindElement(By.Id("box0"))
            );
        }

        [TestMethod]
        public void Sleep()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Thread.Sleep(1000);

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Implicit()
        {
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
            
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Explicit()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2));
            wait.Until(d => revealed.Displayed);

            revealed.SendKeys("Displayed");
            Assert.AreEqual("Displayed", revealed.GetDomProperty("value"));
        }

        [TestMethod]
        public void ExplicitOptions()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2))
            {
                PollingInterval = TimeSpan.FromMilliseconds(300),
            };
            wait.IgnoreExceptionTypes(typeof(ElementNotInteractableException));

            wait.Until(d => {
                revealed.SendKeys("Displayed");
                return true;
            });

            Assert.AreEqual("input", revealed.TagName);
        }
    }
}
```

```rb
    wait = Selenium::WebDriver::Wait.new
    wait.until { revealed.displayed? }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/waits/waits_spec.rb#L42-L43)

##### /examples/ruby/spec/waits/waits\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Waits' do
  let(:driver) { start_session }

  it 'fails' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    expect {
      driver.find_element(id: 'box0')
    }.to raise_error(Selenium::WebDriver::Error::NoSuchElementError)
  end

  it 'sleeps' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    sleep 1
    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'implicit' do
    driver.manage.timeouts.implicit_wait = 2
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    wait = Selenium::WebDriver::Wait.new
    wait.until { revealed.displayed? }

    revealed.send_keys('Displayed')
    expect(revealed.property(:value)).to eq('Displayed')
  end

  it 'options with explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    errors = [Selenium::WebDriver::Error::NoSuchElementError,
              Selenium::WebDriver::Error::ElementNotInteractableError]
    wait = Selenium::WebDriver::Wait.new(timeout: 2,
                                         interval: 0.3,
                                         ignore: errors)

    wait.until { revealed.send_keys('Displayed') || true }

    expect(revealed.property(:value)).to eq('Displayed')
  end
end
```

JavaScript also supports [Expected Conditions](https://www.selenium.dev/documentation/webdriver/support_features/expected_conditions/)

```js
        await driver.wait(until.elementIsVisible(revealed), 2000);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/waits/waits.spec.js#L52)

##### /examples/javascript/test/waits/waits.spec.js

```js

const { By, Browser, until, Builder} = require('selenium-webdriver');
const assert = require("node:assert");


describe('Waits', function () {
    let driver;

    before(async function () {
        driver = new Builder()
          .forBrowser(Browser.CHROME)
          .build();
    });

    after(async () => await driver.quit());

    it('fail', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        await assert.rejects(async () => {
              await driver.findElement(By.id("box0"))
          },
          Error
        )
    });

    it('sleep', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        await driver.sleep(2000);
        let added = await driver.findElement(By.id("box0"));

        assert.equal(await added.getAttribute('class'), "redbox")
    });

    it('implicit', async function () {
        await driver.manage().setTimeouts({ implicit: 2000 });
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        let added = await driver.findElement(By.id("box0"));

        assert.equal(await added.getAttribute('class'), "redbox")
    });

    it('explicit', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        let revealed = await driver.findElement(By.id("revealed"));
        await driver.findElement(By.id("reveal")).click();
        await driver.wait(until.elementIsVisible(revealed), 2000);
        await revealed.sendKeys("Displayed");
        assert.equal(await revealed.getAttribute("value"), "Displayed")
    })
});
```

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk/examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt#L36-L37)

##### examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt

```kt
```

```java
    Wait<WebDriver> wait =
        new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(2))
            .pollingEvery(Duration.ofMillis(300))
            .ignoring(ElementNotInteractableException.class);

    wait.until(
        d -> {
          revealed.sendKeys("Displayed");
          return true;
        });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L82-L92)

##### /examples/java/src/test/java/dev/selenium/waits/WaitsTest.java

```java
package dev.selenium.waits;

import dev.selenium.BaseTest;
import java.time.Duration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.ElementNotInteractableException;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

public class WaitsTest extends BaseTest {
  @Test
  public void fails() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Assertions.assertThrows(
        NoSuchElementException.class,
        () -> {
          driver.findElement(By.id("box0"));
        });
  }

  @Test
  public void sleep() throws InterruptedException {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Thread.sleep(1000);

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void implicit() {
    startChromeDriver(new ChromeOptions());

    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void explicit() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    wait.until(d -> revealed.isDisplayed());

    revealed.sendKeys("Displayed");
    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }

  @Test
  public void explicitWithOptions() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait =
        new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(2))
            .pollingEvery(Duration.ofMillis(300))
            .ignoring(ElementNotInteractableException.class);

    wait.until(
        d -> {
          revealed.sendKeys("Displayed");
          return true;
        });

    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }
}
```

```py
    errors = [NoSuchElementException, ElementNotInteractableException]
    wait = WebDriverWait(driver, timeout=2, poll_frequency=.2, ignored_exceptions=errors)
    wait.until(lambda _ : revealed.send_keys("Displayed") or True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/waits/test_waits.py#L53-L55)

##### /examples/python/tests/waits/test\_waits.py

```py
import pytest
import time
from selenium.common import NoSuchElementException, ElementNotInteractableException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


def test_fails(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    with pytest.raises(NoSuchElementException):
        driver.find_element(By.ID, 'box0')


def test_sleep(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    time.sleep(2)
    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_implicit(driver):
    driver.implicitly_wait(2)
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_explicit(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(lambda _ : revealed.is_displayed())

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"


def test_explicit_options(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    errors = [NoSuchElementException, ElementNotInteractableException]
    wait = WebDriverWait(driver, timeout=2, poll_frequency=.2, ignored_exceptions=errors)
    wait.until(lambda _ : revealed.send_keys("Displayed") or True)

    assert revealed.get_property("value") == "Displayed"
```

```cs
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2))
            {
                PollingInterval = TimeSpan.FromMilliseconds(300),
            };
            wait.IgnoreExceptionTypes(typeof(ElementNotInteractableException));

            wait.Until(d => {
                revealed.SendKeys("Displayed");
                return true;
            });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L70-L79)

##### /examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs

```cs
using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Waits
{
    [TestClass]
    public class WaitsTest : BaseChromeTest
    {
        [TestMethod]
        public void Fails()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Assert.ThrowsException<NoSuchElementException>(
                () => driver.FindElement(By.Id("box0"))
            );
        }

        [TestMethod]
        public void Sleep()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Thread.Sleep(1000);

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Implicit()
        {
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
            
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Explicit()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2));
            wait.Until(d => revealed.Displayed);

            revealed.SendKeys("Displayed");
            Assert.AreEqual("Displayed", revealed.GetDomProperty("value"));
        }

        [TestMethod]
        public void ExplicitOptions()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2))
            {
                PollingInterval = TimeSpan.FromMilliseconds(300),
            };
            wait.IgnoreExceptionTypes(typeof(ElementNotInteractableException));

            wait.Until(d => {
                revealed.SendKeys("Displayed");
                return true;
            });

            Assert.AreEqual("input", revealed.TagName);
        }
    }
}
```

```rb
    errors = [Selenium::WebDriver::Error::NoSuchElementError,
              Selenium::WebDriver::Error::ElementNotInteractableError]
    wait = Selenium::WebDriver::Wait.new(timeout: 2,
                                         interval: 0.3,
                                         ignore: errors)

    wait.until { revealed.send_keys('Displayed') || true }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/waits/waits_spec.rb#L54-L60)

##### /examples/ruby/spec/waits/waits\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Waits' do
  let(:driver) { start_session }

  it 'fails' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    expect {
      driver.find_element(id: 'box0')
    }.to raise_error(Selenium::WebDriver::Error::NoSuchElementError)
  end

  it 'sleeps' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    sleep 1
    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'implicit' do
    driver.manage.timeouts.implicit_wait = 2
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    wait = Selenium::WebDriver::Wait.new
    wait.until { revealed.displayed? }

    revealed.send_keys('Displayed')
    expect(revealed.property(:value)).to eq('Displayed')
  end

  it 'options with explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    errors = [Selenium::WebDriver::Error::NoSuchElementError,
              Selenium::WebDriver::Error::ElementNotInteractableError]
    wait = Selenium::WebDriver::Wait.new(timeout: 2,
                                         interval: 0.3,
                                         ignore: errors)

    wait.until { revealed.send_keys('Displayed') || true }

    expect(revealed.property(:value)).to eq('Displayed')
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk/examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt#L51-L60)

##### examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt

```kt
```

Last modified October 31, 2025: [Added Kotlin Code Examples (#2499) (e49b07e4f68)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e49b07e4f68275d61faff820b9b2b640e9d16fb3)

----
url: https://www.selenium.dev/ja/_print/documentation/test_practices/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/test_practices/).

# テストの実践

Seleniumプロジェクトからのテストに関するいくつかのガイドラインと推奨事項

* 1: [デザインパターンと開発戦略](#pg-2143df9d35d226a88c0cc7767125c6e5)
* 2: [テスト自動化について](#pg-67b8539251778f10297499fc150c3fd4)
* 3: [テストの種類](#pg-41cb2ef6faea1a7cfd7d7d3bdb86daa4)
* 4: [推奨された行動](#pg-bdf1456594fb6ec70c9694f04ee90ff6)
* * 4.1: [ページオブジェクトモデル](#pg-42bae4628f031de88c649b709ec0f8c6)
  * 4.2: [ドメイン固有言語（DSL）](#pg-733a3a2cedeac8ca6de96d3d413edbd9)
  * 4.3: [アプリケーション状態の生成](#pg-cfd646f6a4f65016394c853e4d80d659)
  * 4.4: [モック外部サービス](#pg-62c8faa9fe4698bf3ed3466cbd528ff0)
  * 4.5: [改善されたレポート](#pg-00238dd2c8fbe56f45215ed579d9e3ca)
  * 4.6: [ロケータをうまく扱うTips](#pg-2cf63df95d95443722f314e0c8512887)
  * 4.7: [状態を共有しない](#pg-40c3ab25efecc76d33c7f383e0826b87)
  * 4.8: [テストの独立性](#pg-6d60e52a318221cb890ffeae48c949d5)
  * 4.9: [Fluent APIの使用を検討する](#pg-29a52db54ab1f274413bf1630d2644e6)
  * 4.10: [テストごとに新しいブラウザを起動する](#pg-58a1235b5fcacba8271f76d27a479aaa)
  5: [推奨されない行動](#pg-a889efde3001c1482b017464dd04af90)
  * 5.1: [CAPTCHA（キャプチャ）](#pg-39f9e51e0f4ba8c3e8698a77a7a121c9)
  * 5.2: [ファイルダウンロード](#pg-13dc546cdf40904f2b8d17d2d10912b5)
  * 5.3: [HTTPレスポンスコード](#pg-cd608bb3235f3fdba483c5af1d7989e8)
  * 5.4: [Gmail、Eメール、Facebookログイン](#pg-2bda5750ae2f47398811b74c5335df8d)
  * 5.5: [テストの依存関係](#pg-3838eea374f78e0ae303bf7bf2468369)
  * 5.6: [パフォーマンステスト](#pg-eca347e22c127712a44437f535a8745b)
  * 5.7: [リンクスパイダー](#pg-8314dd156c805a24994aecd6df02e160)
  * 5.8: [二要素認証](#pg-fb1bf62414b2a3444b5611af6d361a5f)

「ベストプラクティス」に関するメモ：このドキュメントでは、“ベストプラクティス"というフレーズを意図的に避けています。 すべての状況に有効なアプローチはありません。 “ガイドラインとレコメンデーション"というアイデアを好みます。 これらを一通り読み、特定の環境でどのアプローチが効果的かを慎重に決定することをお勧めします。

機能テストは、多くの理由で適切に行うのが困難です。 まるでアプリケーションの状態、複雑さ、および依存関係が、テストを十分に難しくしないと思えるほど、ブラウザ（特にクロスブラウザの非互換性）を扱うのは、良いテストの作成を難しくします。

Seleniumは、機能的なユーザーインタラクションを簡単にするツールを提供しますが、適切に設計されたテストスイートの作成には役立ちません。 この章では、機能的なWebページの自動化に取り組む方法に関するアドバイス、ガイドライン、および推奨事項を提供します。

この章では、長年にわたって成功を収めてきたSeleniumの多くのユーザーの間で人気のあるソフトウェア設計パターンを記録します。

# 1 - デザインパターンと開発戦略

```java
package com.example.webdriver;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class EditIssue {

  private final WebDriver driver;

  public EditIssue(WebDriver driver) {
    this.driver = driver;
  }

  public void setTitle(String title) {
    WebElement field = driver.findElement(By.id("issue_title")));
    clearAndType(field, title);
  }

  public void setBody(String body) {
    WebElement field = driver.findElement(By.id("issue_body"));
    clearAndType(field, body);
  }

  public void setHowToReproduce(String howToReproduce) {
    WebElement field = driver.findElement(By.id("issue_form_repro-command"));
    clearAndType(field, howToReproduce);
  }

  public void setLogOutput(String logOutput) {
    WebElement field = driver.findElement(By.id("issue_form_logs"));
    clearAndType(field, logOutput);
  }

  public void setOperatingSystem(String operatingSystem) {
    WebElement field = driver.findElement(By.id("issue_form_operating-system"));
    clearAndType(field, operatingSystem);
  }

  public void setSeleniumVersion(String seleniumVersion) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-version"));
    clearAndType(field, logOutput);
  }

  public void setBrowserVersion(String browserVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-versions"));
    clearAndType(field, browserVersion);
  }

  public void setDriverVersion(String driverVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-driver-versions"));
    clearAndType(field, driverVersion);
  }

  public void setUsingGrid(String usingGrid) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-grid-version"));
    clearAndType(field, usingGrid);
  }

  public IssueList submit() {
    driver.findElement(By.cssSelector("button[type='submit']")).click();
    return new IssueList(driver);
  }

  private void clearAndType(WebElement field, String text) {
    field.clear();
    field.sendKeys(text);
  }
}
```

これをLoadableComponentに変換するには、これを基本型として設定するだけです。

```java
public class EditIssue extends LoadableComponent<EditIssue> {
  // rest of class ignored for now
}
```

この署名は少し変わっているように見えますが、それは、このクラスがEditIssueページをロードするLoadableComponentを表すことを意味します。

このベースクラスを拡張することにより、2つの新しいメソッドを実装する必要があります。

```java
  @Override
  protected void load() {
    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();
    assertTrue("Not on the issue entry page: " + url, url.endsWith("/new"));
  }
```

`load` メソッドはページに移動するために使用され、　`isLoaded` メソッドは正しいページにいるかどうかを判断するために使用されます。 このメソッドはブール値を返す必要があるように見えますが、代わりにJUnitのAssertクラスを使用して一連のアサーションを実行します。 アサーションは好きなだけ少なくても多くてもかまいません。 これらのアサーションを使用することで、クラスのユーザーにテストのデバッグに使用できる明確な情報を提供することができます。

少し手直しすると、PageObjectは次のようになります。

```java
package com.example.webdriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

import static junit.framework.Assert.assertTrue;

public class EditIssue extends LoadableComponent<EditIssue> {

  private final WebDriver driver;
  
  // By default the PageFactory will locate elements with the same name or id
  // as the field. Since the issue_title element has an id attribute of "issue_title"
  // we don't need any additional annotations.
  private WebElement issue_title;
  
  // But we'd prefer a different name in our code than "issue_body", so we use the
  // FindBy annotation to tell the PageFactory how to locate the element.
  @FindBy(id = "issue_body") private WebElement body;
  
  public EditIssue(WebDriver driver) {
    this.driver = driver;
    
    // This call sets the WebElement fields.
    PageFactory.initElements(driver, this);
  }

  @Override
  protected void load() {
    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();
    assertTrue("Not on the issue entry page: " + url, url.endsWith("/new"));
  }

  public void setHowToReproduce(String howToReproduce) {
    WebElement field = driver.findElement(By.id("issue_form_repro-command"));
    clearAndType(field, howToReproduce);
  }

  public void setLogOutput(String logOutput) {
    WebElement field = driver.findElement(By.id("issue_form_logs"));
    clearAndType(field, logOutput);
  }

  public void setOperatingSystem(String operatingSystem) {
    WebElement field = driver.findElement(By.id("issue_form_operating-system"));
    clearAndType(field, operatingSystem);
  }

  public void setSeleniumVersion(String seleniumVersion) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-version"));
    clearAndType(field, logOutput);
  }

  public void setBrowserVersion(String browserVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-versions"));
    clearAndType(field, browserVersion);
  }

  public void setDriverVersion(String driverVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-driver-versions"));
    clearAndType(field, driverVersion);
  }

  public void setUsingGrid(String usingGrid) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-grid-version"));
    clearAndType(field, usingGrid);
  }

  public IssueList submit() {
    driver.findElement(By.cssSelector("button[type='submit']")).click();
    return new IssueList(driver);
  }

  private void clearAndType(WebElement field, String text) {
    field.clear();
    field.sendKeys(text);
  }
}
```

それは私たちをあまり信じられなかったようですよね？ これまでに行ったことの1つは、ページに移動する方法に関する情報をページ自体にカプセル化することです。 つまり、この情報はコードベース全体に散らばっていません。 これは、テストで下記を実行できることも意味します。

```java
EditIssue page = new EditIssue(driver).get();
```

この呼び出しにより、ドライバーは必要に応じてページに移動します。

### ネストされたコンポーネント

LoadableComponentsは、他のLoadableComponentsと組み合わせて使用すると、より便利になります。 この例を使用すると、 “edit issue” ページをプロジェクトのWebサイト内のコンポーネントとして表示できます（結局のところ、そのサイトのタブからアクセスします）。 また、issue を報告するにはログインする必要があります。 これをネストされたコンポーネントのツリーとしてモデル化できます。

```
 + ProjectPage
 +---+ SecuredPage
     +---+ EditIssue
```

これはコードではどのように見えますか？ まず、各論理コンポーネントには独自のクラスがあります。 それぞれの “load” メソッドは、親クラスを “get” します。 上記のEditIssueクラスに加えて、最終結果は次のようになります。

ProjectPage.java:

```java
package com.example.webdriver;

import org.openqa.selenium.WebDriver;

import static org.junit.Assert.assertTrue;

public class ProjectPage extends LoadableComponent<ProjectPage> {

  private final WebDriver driver;
  private final String projectName;

  public ProjectPage(WebDriver driver, String projectName) {
    this.driver = driver;
    this.projectName = projectName;
  }

  @Override
  protected void load() {
    driver.get("http://" + projectName + ".googlecode.com/");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();

    assertTrue(url.contains(projectName));
  }
}
```

and SecuredPage.java:

```java
package com.example.webdriver;

import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import static org.junit.Assert.fail;

public class SecuredPage extends LoadableComponent<SecuredPage> {

  private final WebDriver driver;
  private final LoadableComponent<?> parent;
  private final String username;
  private final String password;

  public SecuredPage(WebDriver driver, LoadableComponent<?> parent, String username, String password) {
    this.driver = driver;
    this.parent = parent;
    this.username = username;
    this.password = password;
  }

  @Override
  protected void load() {
    parent.get();

    String originalUrl = driver.getCurrentUrl();

    // Sign in
    driver.get("https://www.google.com/accounts/ServiceLogin?service=code");
    driver.findElement(By.name("Email")).sendKeys(username);
    WebElement passwordField = driver.findElement(By.name("Passwd"));
    passwordField.sendKeys(password);
    passwordField.submit();

    // Now return to the original URL
    driver.get(originalUrl);
  }

  @Override
  protected void isLoaded() throws Error {
    // If you're signed in, you have the option of picking a different login.
    // Let's check for the presence of that.

    try {
      WebElement div = driver.findElement(By.id("multilogin-dropdown"));
    } catch (NoSuchElementException e) {
      fail("Cannot locate user name link");
    }
  }
}
```

EditIssueの “load” メソッドは次のようになります。

```java
  @Override
  protected void load() {
    securedPage.get();

    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }
```

これは、コンポーネントがすべて相互に “ネストされている” ことを示しています。 EditIssueで `get()` を呼び出すと、そのすべての依存関係も読み込まれます。 使用例：

```java
public class FooTest {
  private EditIssue editIssue;

  @Before
  public void prepareComponents() {
    WebDriver driver = new FirefoxDriver();

    ProjectPage project = new ProjectPage(driver, "selenium");
    SecuredPage securedPage = new SecuredPage(driver, project, "example", "top secret");
    editIssue = new EditIssue(driver, securedPage);
  }

  @Test
  public void demonstrateNestedLoadableComponents() {
    editIssue.get();

    editIssue.title.sendKeys('Title');
    editIssue.body.sendKeys('What Happened');
    editIssue.setHowToReproduce('How to Reproduce');
    editIssue.setLogOutput('Log Output');
    editIssue.setOperatingSystem('Operating System');
    editIssue.setSeleniumVersion('Selenium Version');
    editIssue.setBrowserVersion('Browser Version');
    editIssue.setDriverVersion('Driver Version');
    editIssue.setUsingGrid('I Am Using Grid');
  }
}
```

テストで [Guiceberry](https://github.com/zorzella/guiceberry) などのライブラリを使用している場合は、PageObjectsの設定の前文を省略して、わかりやすく読みやすいテストを作成できます。

## ボットパターン

(以前の場所: <https://github.com/SeleniumHQ/selenium/wiki/Bot-Style-Tests>)

PageObjectsは、テストでの重複を減らすための便利な方法ですが、チームが快適にフォローできるパターンであるとは限りません。 別のアプローチは、より “コマンドのような” スタイルのテストに従うことです。

“ボット” は、生のSeleniumAPIに対するアクション指向の抽象化です。 つまり、コマンドがアプリに対して正しいことをしていないことがわかった場合、コマンドを簡単に変更できます。 例として：

```java
public class ActionBot {
  private final WebDriver driver;

  public ActionBot(WebDriver driver) {
    this.driver = driver;
  }

  public void click(By locator) {
    driver.findElement(locator).click();
  }

  public void submit(By locator) {
    driver.findElement(locator).submit();
  }

  /** 
   * Type something into an input field. WebDriver doesn't normally clear these
   * before typing, so this method does that first. It also sends a return key
   * to move the focus out of the element.
   */
  public void type(By locator, String text) { 
    WebElement element = driver.findElement(locator);
    element.clear();
    element.sendKeys(text + "\n");
  }
}
```

```py
import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L6-L26)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L28-L65)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L67-L80)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L82-L172)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L174-L240)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

# 2 - テスト自動化について

```java
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
User user = UserFactory.createCommonUser(); //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
AccountPage accountPage = loginAs(user.getEmail(), user.getPassword());
  
```

```python
# Create a user who has read-only permissions--they can configure a unicorn,
# but they do not have payment information set up, nor do they have
# administrative privileges. At the time the user is created, its email
# address and password are randomly generated--you don't even need to
# know them.
user = user_factory.create_common_user() #This method is defined elsewhere.

# Log in as this user.
# Logging in on this site takes you to your personal "My Account" page, so the
# AccountPage object is returned by the loginAs method, allowing you to then
# perform actions from the AccountPage.
account_page = login_as(user.get_email(), user.get_password())
  
```

```csharp
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
User user = UserFactory.CreateCommonUser(); //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
AccountPage accountPage = LoginAs(user.Email, user.Password);
  
```

```ruby
# Create a user who has read-only permissions--they can configure a unicorn,
# but they do not have payment information set up, nor do they have
# administrative privileges. At the time the user is created, its email
# address and password are randomly generated--you don't even need to
# know them.
user = UserFactory.create_common_user #This method is defined elsewhere.

# Log in as this user.
# Logging in on this site takes you to your personal "My Account" page, so the
# AccountPage object is returned by the loginAs method, allowing you to then
# perform actions from the AccountPage.
account_page = login_as(user.email, user.password)
  
```

```javascript
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
var user = userFactory.createCommonUser(); //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
var accountPage = loginAs(user.email, user.password);
  
```

```kotlin
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
val user = UserFactory.createCommonUser() //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
val accountPage = loginAs(user.getEmail(), user.getPassword())
  
```

```java
// The Unicorn is a top-level Object--it has attributes, which are set here. 
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
Unicorn sparkles = new Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS);

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.
AddUnicornPage addUnicornPage = accountPage.addUnicorn();

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
UnicornConfirmationPage unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles);
  
```

```python
# The Unicorn is a top-level Object--it has attributes, which are set here.
# This only stores the values; it does not fill out any web forms or interact
# with the browser in any way.
sparkles = Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

# Since we're already "on" the account page, we have to use it to get to the
# actual place where you configure unicorns. Calling the "Add Unicorn" method
# takes us there.
add_unicorn_page = account_page.add_unicorn()

# Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
# its createUnicorn() method. This method will take Sparkles' attributes,
# fill out the form, and click submit.
unicorn_confirmation_page = add_unicorn_page.create_unicorn(sparkles)
  
```

```csharp
// The Unicorn is a top-level Object--it has attributes, which are set here. 
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
Unicorn sparkles = new Unicorn("Sparkles", UnicornColors.Purple, UnicornAccessories.Sunglasses, UnicornAdornments.StarTattoos);

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.
AddUnicornPage addUnicornPage = accountPage.AddUnicorn();

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
UnicornConfirmationPage unicornConfirmationPage = addUnicornPage.CreateUnicorn(sparkles);
  
```

```ruby
# The Unicorn is a top-level Object--it has attributes, which are set here.
# This only stores the values; it does not fill out any web forms or interact
# with the browser in any way.
sparkles = Unicorn.new('Sparkles', UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

# Since we're already "on" the account page, we have to use it to get to the
# actual place where you configure unicorns. Calling the "Add Unicorn" method
# takes us there.
add_unicorn_page = account_page.add_unicorn

# Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
# its createUnicorn() method. This method will take Sparkles' attributes,
# fill out the form, and click submit.
unicorn_confirmation_page = add_unicorn_page.create_unicorn(sparkles)
  
```

```javascript
// The Unicorn is a top-level Object--it has attributes, which are set here.
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
var sparkles = new Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS);

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.

var addUnicornPage = accountPage.addUnicorn();

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
var unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles);

  
```

```kotlin
// The Unicorn is a top-level Object--it has attributes, which are set here. 
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
val sparkles = Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.
val addUnicornPage = accountPage.addUnicorn()

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles)

  
```

```java
// The exists() method from UnicornConfirmationPage will take the Sparkles 
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
Assert.assertTrue("Sparkles should have been created, with all attributes intact", unicornConfirmationPage.exists(sparkles));
  
```

```python
# The exists() method from UnicornConfirmationPage will take the Sparkles
# object--a specification of the attributes you want to see, and compare
# them with the fields on the page.
assert unicorn_confirmation_page.exists(sparkles), "Sparkles should have been created, with all attributes intact"
  
```

```csharp
// The exists() method from UnicornConfirmationPage will take the Sparkles 
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
Assert.True(unicornConfirmationPage.Exists(sparkles), "Sparkles should have been created, with all attributes intact");
  
```

```ruby
# The exists() method from UnicornConfirmationPage will take the Sparkles
# object--a specification of the attributes you want to see, and compare
# them with the fields on the page.
expect(unicorn_confirmation_page.exists?(sparkles)).to be, 'Sparkles should have been created, with all attributes intact'
  
```

```javascript
// The exists() method from UnicornConfirmationPage will take the Sparkles
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
assert(unicornConfirmationPage.exists(sparkles), "Sparkles should have been created, with all attributes intact");

  
```

```kotlin
// The exists() method from UnicornConfirmationPage will take the Sparkles 
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
assertTrue("Sparkles should have been created, with all attributes intact", unicornConfirmationPage.exists(sparkles))
  
```

テスターはまだこのコードでユニコーンについて話しているだけです。 ボタンもロケーターもブラウザーコントロールもありません。 ラリーが来週、Ruby-on-Railsが好きではなくなったと判断し、Fortranフロントエンドを使用して最新のHaskellバインディングでサイト全体を再実装することを決めた場合でも、アプリケーションを *モデル化する* この方法により、これらのテストレベルのコマンドを所定の位置に変えずに維持できます。

ページオブジェクトは、サイトの再設計に準拠するために若干のメンテナンスが必要になりますが、これらのテストは同じままです。 この基本的な設計を採用することで、可能な限りブラウザに面した最小限の手順でワークフローを進めていきたいと思うでしょう。 次のワークフローでは、ユニコーンをショッピングカートに追加します。 カートの状態が適切に維持されていることを確認するために、おそらくこのテストを何度も繰り返す必要があります。 開始する前に、カートに複数のユニコーンがありますか？ ショッピングカートには何個収容できますか？ 同じ名前や機能で複数作成すると、壊れますか？ 既存のものを保持するだけですか、それとも別のものを追加しますか？

ワークフローを移動するたびに、アカウントを作成し、ユーザーとしてログインし、ユニコーンを設定する必要を避けたいと考えています。 理想的には、APIまたはデータベースを介してアカウントを作成し、ユニコーンを事前設定できるようになります。 その後、ユーザーとしてログインし、きらめきを見つけてカートに追加するだけです。

### 自動化するかしないか

自動化は常に有利ですか？ テストケースの自動化をいつ決定する必要がありますか？

テストケースを自動化することは必ずしも有利ではありません。 手動テストがより適切な場合があります。 たとえば、近い将来にアプリケーションのユーザーインターフェースが大幅に変更される場合は、自動化を書き換える必要があるかもしれません。 また、テストの自動化を構築する時間が足りない場合もあります。 短期的には、手動テストの方が効果的です。 アプリケーションの期限が非常に厳しい場合、現在利用できるテストの自動化はなく、その期間内にテストを実施することが不可欠です。 手動テストが最適なソリューションです。

# 3 - テストの種類

### 受け入れテスト

このタイプのテストは、機能またはシステムが顧客の期待と要件を満たしているかどうかを判断するために行われます。 このタイプのテストには通常、顧客の協力またはフィードバックが関与します。 下記質問に答えることで確認することができます。

> ***正しい*** 製品を作っていますか？

Webアプリケーションの場合、ユーザーの予想される動作をシミュレートすることで、 このテストの自動化をSeleniumで直接実行できます。 このシミュレーションは、このドキュメントで説明されているように、記録/再生によって、 またはサポートされているさまざまな言語によって実行できます。 注：受け入れテストは ***機能テスト*** のサブタイプであり、一部の人はこれにも言及する場合があります。

### 機能テスト

このタイプのテストは、機能またはシステムが問題なく正常に機能するかどうかを判断するために行われます。 システムをさまざまなレベルでチェックして、すべてのシナリオがカバーされていること、 およびシステムが実行すべきことを実行していることを確認します。 下記質問に答えることで確認することができます。

> 製品を ***正しく*** 作っていますか？

> For example, ***Testing that the site can handle numerous orders/users at once.***

#### ストレステスト

ストレステストは、ストレス下（またはサポートされている最大負荷以上）でアプリケーションがどの程度機能するかを確認するために行われます。

> For example, ***Testing that your ecommerce site can handle Black Friday***

> For example, ***Testing that your new search bar doesn’t break the other buttons on the menu***

# 4 - 推奨された行動

Seleniumプロジェクトからのテストに関するいくつかのガイドラインと推奨事項

「ベストプラクティス」に関するメモ：このドキュメントでは、“ベストプラクティス"というフレーズを意図的に避けています。 すべての状況に有効なアプローチはありません。 “ガイドラインとレコメンデーション"というアイデアを好みます。 これらを一通り読み、特定の環境でどのアプローチが効果的かを慎重に決定することをお勧めします。

機能テストは、多くの理由で適切に行うのが困難です。 まるでアプリケーションの状態、複雑さ、および依存関係が、テストを十分に難しくしないと思えるほど、ブラウザ（特にクロスブラウザの非互換性）を扱うのは、良いテストの作成を難しくします。

Seleniumは、機能的なユーザーインタラクションを簡単にするツールを提供しますが、適切に設計されたテストスイートの作成には役立ちません。 この章では、機能的なWebページの自動化に取り組む方法に関するアドバイス、ガイドライン、および推奨事項を提供します。

この章では、長年にわたって成功を収めてきたSeleniumの多くのユーザーの間で人気のあるソフトウェア設計パターンを記録します。

# 4.1 - ページオブジェクトモデル

```java
/***
 * Tests login feature
 */
public class Login {

  public void testLogin() {
    // fill login data on sign-in page
    driver.findElement(By.name("user_name")).sendKeys("userName");
    driver.findElement(By.name("password")).sendKeys("my supersecret password");
    driver.findElement(By.name("sign-in")).click();

    // verify h1 tag is "Hello userName" after login
    driver.findElement(By.tagName("h1")).isDisplayed();
    assertThat(driver.findElement(By.tagName("h1")).getText(), is("Hello userName"));
  }
}
```

There are two problems with this approach.

* There is no separation between the test method and the AUT’s locators (IDs in this example); both are intertwined in a single method. If the AUT’s UI changes its identifiers, layout, or how a login is input and processed, the test itself must change.
* The ID-locators would be spread in multiple tests, in all tests that had to use this login page.

Applying the page object model, this example could be rewritten like this in the following example of a page object for a Sign-in page.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Sign-in page.
 */
public class SignInPage {
  protected WebDriver driver;

  // <input name="user_name" type="text" value="">
  private By usernameBy = By.name("user_name");
  // <input name="password" type="password" value="">
  private By passwordBy = By.name("password");
  // <input name="sign_in" type="submit" value="SignIn">
  private By signinBy = By.name("sign_in");

  public SignInPage(WebDriver driver){
    this.driver = driver;
     if (!driver.getTitle().equals("Sign In Page")) {
      throw new IllegalStateException("This is not Sign In Page," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Login as valid user
    *
    * @param userName
    * @param password
    * @return HomePage object
    */
  public HomePage loginValidUser(String userName, String password) {
    driver.findElement(usernameBy).sendKeys(userName);
    driver.findElement(passwordBy).sendKeys(password);
    driver.findElement(signinBy).click();
    return new HomePage(driver);
  }
}
```

and page object for a Home page could look like this.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Home Page
 */
public class HomePage {
  protected WebDriver driver;

  // <h1>Hello userName</h1>
  private By messageBy = By.tagName("h1");

  public HomePage(WebDriver driver){
    this.driver = driver;
    if (!driver.getTitle().equals("Home Page of logged in user")) {
      throw new IllegalStateException("This is not Home Page of logged in user," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Get message (h1 tag)
    *
    * @return String message text
    */
  public String getMessageText() {
    return driver.findElement(messageBy).getText();
  }

  public HomePage manageProfile() {
    // Page encapsulation to manage profile functionality
    return new HomePage(driver);
  }
  /* More methods offering the services represented by Home Page
  of Logged User. These methods in turn might return more Page Objects
  for example click on Compose mail button could return ComposeMail class object */
}
```

So now, the login test would use these two page objects as follows.

```java
/***
 * Tests login feature
 */
public class TestLogin {

  @Test
  public void testLogin() {
    SignInPage signInPage = new SignInPage(driver);
    HomePage homePage = signInPage.loginValidUser("userName", "password");
    assertThat(homePage.getMessageText(), is("Hello userName"));
  }

}
```

```html
<!-- Products Page -->
<div class="header_container">
    <span class="title">Products</span>
</div>

<div class="inventory_list">
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
</div>
```

Each product is a component of the Products page.

```html
<!-- Inventory Item -->
<div class="inventory_item">
    <div class="inventory_item_name">Backpack</div>
    <div class="pricebar">
        <div class="inventory_item_price">$29.99</div>
        <button id="add-to-cart-backpack">Add to cart</button>
    </div>
</div>
```

The Products page HAS-A list of products. This object relationship is called Composition. In simpler terms, something is *composed of* another thing.

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

// Page Object
public class ProductsPage extends BasePage {
    public ProductsPage(WebDriver driver) {
        super(driver);
        // No assertions, throws an exception if the element is not loaded
        new WebDriverWait(driver, Duration.ofSeconds(3))
            .until(d -> d.findElement(By.className​("header_container")));
    }

    // Returning a list of products is a service of the page
    public List<Product> getProducts() {
        return driver.findElements(By.className​("inventory_item"))
            .stream()
            .map(e -> new Product(e)) // Map WebElement to a product component
            .toList();
    }

    // Return a specific product using a boolean-valued function (predicate)
    // This is the behavioral Strategy Pattern from GoF
    public Product getProduct(Predicate<Product> condition) {
        return getProducts()
            .stream()
            .filter(condition) // Filter by product name or price
            .findFirst()
            .orElseThrow(() -> new RuntimeException("Product not found")); // Error thrown during actual test run
    }
}
```

The Product component object is used inside the Products page object.

```java
public abstract class BaseComponent {
    protected WebElement root;

    public BaseComponent(WebElement root) {
        this.root = root;
    }
}

// Page Component Object
public class Product extends BaseComponent {
    // The root element contains the entire component
    public Product(WebElement root) {
        super(root); // inventory_item
    }

    public String getName() {
        // Locating an element begins at the root of the component
        return root.findElement(By.className("inventory_item_name")).getText();
    }

    public BigDecimal getPrice() {
        return new BigDecimal(
                root.findElement(By.className("inventory_item_price"))
                    .getText()
                    .replace("$", "")
            ).setScale(2, RoundingMode.UNNECESSARY); // Sanitation and formatting
    }

    public void addToCart() {
        root.findElement(By.id("add-to-cart-backpack")).click();
    }
}
```

So now, the products test would use the page object and the page component object as follows.

```java
public class ProductsTest {
    @Test
    public void testProductInventory() {
        var productsPage = new ProductsPage(driver); // page object
        var products = productsPage.getProducts();
        assertEquals(6, products.size()); // expected, actual
    }
    
    @Test
    public void testProductPrices() {
        var productsPage = new ProductsPage(driver);

        // Pass a lambda expression (predicate) to filter the list of products
        // The predicate or "strategy" is the behavior passed as parameter
        var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); // page component object
        var bikeLight = productsPage.getProduct(p -> p.getName().equals("Bike Light"));

        assertEquals(new BigDecimal("29.99"), backpack.getPrice());
        assertEquals(new BigDecimal("9.99"), bikeLight.getPrice());
    }
}
```

```java
public class LoginPage {
    public HomePage loginAs(String username, String password) {
        // ... clever magic happens here
    }
    
    public LoginPage loginAsExpectingError(String username, String password) {
        //  ... failed login here, maybe because one or both of the username and password are wrong
    }
    
    public String getErrorMessage() {
        // So we can verify that the correct error is shown
    }
}
```

The code presented above shows an important point: the tests, not the Page Objects, should be responsible for making assertions about the state of a page. For example:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    inbox.assertMessageWithSubjectIsUnread("I like cheese");
    inbox.assertMessageWithSubjectIsNotUnread("I'm not fond of tofu");
}
```

could be re-written as:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    assertTrue(inbox.isMessageWithSubjectIsUnread("I like cheese"));
    assertFalse(inbox.isMessageWithSubjectIsUnread("I'm not fond of tofu"));
}
```

```java
public class LoginPage {
    private final WebDriver driver;

    public LoginPage(WebDriver driver) {
        this.driver = driver;

        // Check that we're on the right page.
        if (!"Login".equals(driver.getTitle())) {
            // Alternatively, we could navigate to the login page, perhaps logging out first
            throw new IllegalStateException("This is not the login page");
        }
    }

    // The login page contains several HTML elements that will be represented as WebElements.
    // The locators for these elements should only be defined once.
        By usernameLocator = By.id("username");
        By passwordLocator = By.id("passwd");
        By loginButtonLocator = By.id("login");

    // The login page allows the user to type their username into the username field
    public LoginPage typeUsername(String username) {
        // This is the only place that "knows" how to enter a username
        driver.findElement(usernameLocator).sendKeys(username);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to type their password into the password field
    public LoginPage typePassword(String password) {
        // This is the only place that "knows" how to enter a password
        driver.findElement(passwordLocator).sendKeys(password);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to submit the login form
    public HomePage submitLogin() {
        // This is the only place that submits the login form and expects the destination to be the home page.
        // A seperate method should be created for the instance of clicking login whilst expecting a login failure. 
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the login page ever
        // go somewhere else (for example, a legal disclaimer) then changing the method signature
        // for this method will mean that all tests that rely on this behaviour won't compile.
        return new HomePage(driver);	
    }

    // The login page allows the user to submit the login form knowing that an invalid username and / or password were entered
    public LoginPage submitLoginExpectingFailure() {
        // This is the only place that submits the login form and expects the destination to be the login page due to login failure.
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the user ever be navigated to the home page after submiting a login with credentials 
        // expected to fail login, the script will fail when it attempts to instantiate the LoginPage PageObject.
        return new LoginPage(driver);	
    }

    // Conceptually, the login page offers the user the service of being able to "log into"
    // the application using a user name and password. 
    public HomePage loginAs(String username, String password) {
        // The PageObject methods that enter username, password & submit login have already defined and should not be repeated here.
        typeUsername(username);
        typePassword(password);
        return submitLogin();
    }
}
```

# 4.2 - ドメイン固有言語（DSL）

```java
/**
 * Takes a username and password, fills out the fields, and clicks "login".
 * @return An instance of the AccountPage
 */
public AccountPage loginAsUser(String username, String password) {
  WebElement loginField = driver.findElement(By.id("loginField"));
  loginField.clear();
  loginField.sendKeys(username);

  // Fill out the password field. The locator we're using is "By.id", and we should
  // have it defined elsewhere in the class.
  WebElement passwordField = driver.findElement(By.id("password"));
  passwordField.clear();
  passwordField.sendKeys(password);

  // Click the login button, which happens to have the id "submit".
  driver.findElement(By.id("submit")).click();

  // Create and return a new instance of the AccountPage (via the built-in Selenium
  // PageFactory).
  return PageFactory.newInstance(AccountPage.class);
}
```

このメソッドは、テストコードから入力フィールド、ボタン、クリック、さらにはページの概念を完全に抽象化します。 このアプローチを使用すると、テスターはこのメソッドを呼び出すだけで済みます。 これにより、メンテナンスの利点が得られます。 ログインフィールドが変更された場合、テストではなく、このメソッドを変更するだけで済みます。

```java
public void loginTest() {
    loginAsUser("cbrown", "cl0wn3");

    // Now that we're logged in, do some other stuff--since we used a DSL to support
    // our testers, it's as easy as choosing from available methods.
    do.something();
    do.somethingElse();
    Assert.assertTrue("Something should have been done!", something.wasDone());

    // Note that we still haven't referred to a button or web control anywhere in this
    // script...
}
```

繰り返しになります。 主な目標の1つは、 テストが **UIの問題ではなく、手元の問題** に対処できるAPIを作成することです。 UIはユーザーにとって二次的な関心事です。ユーザーはUIを気にせず、ただ仕事をやりたいだけです。 テストスクリプトは、ユーザーがやりたいことと知りたいことの長々としたリストのように読む必要があります。 テストでは、UIがどのようにそれを実行するように要求するかについて、気にするべきではありません。

\***AUT**: Application under test（テスト対象アプリケーション）

# 4.3 - アプリケーション状態の生成

Seleniumはテストケースの準備に使用しないでください。 テストケースのすべての反復アクションと準備は、他の方法で行う必要があります。 たとえば、ほとんどのWeb UIには認証があります（ログインフォームなど）。 すべてのテストの前にWebブラウザーからのログインをなくすことで、テストの速度と安定性の両方が向上します。 AUT\* にアクセスするためのメソッドを作成する必要があります（APIを使用してログインし、Cookieを設定するなど）。 また、テスト用にデータをプリロードするメソッドの作成は、Seleniumを使用して実行しないほうがいいです。 前述のように、AUT\* のデータを作成するには、既存のAPIを活用する必要があります。

\***AUT**: Application under test（テスト対象アプリケーション）

# 4.4 - モック外部サービス

外部サービスへの依存を排除すると、テストの速度と安定性が大幅に向上します。

# 4.5 - 改善されたレポート

Seleniumは、実行されたテストケースのステータスをレポートするようには設計されていません。 単体テストフレームワークの組み込みのレポート機能を利用することは、良いスタートです。 ほとんどの単体テストフレームワークには、xUnitまたはHTML形式のレポートを生成できるレポートがあります。 xUnitレポートは、Jenkins、Travis、Bambooなどの継続的インテグレーション（CI）サーバーに結果をインポートするのに人気があります。 いくつかの言語のレポート出力に関する詳細情報へのリンクがあります。

[NUnit 3 Console Runner](//github.com/nunit/docs/wiki/Console-Runner)

[NUnit 3 Console Command Line](//github.com/nunit/docs/wiki/Console-Command-Line)

[xUnit getting test results in TeamCity](//xunit.net/docs/getting-test-results-in-teamcity)

[xUnit getting test results in CruiseControl.NET](//xunit.net/docs/getting-test-results-in-ccnet)

[xUnit getting test results in Azure DevOps](//xunit.net/docs/getting-test-results-in-azure-devops)

# 4.6 - ロケータをうまく扱うTips

# 4.7 - 状態を共有しない

いくつかの場所で言及されていますが、再度言及する価値があります。 テストが互いに分離されていることを確認してください。

* テストデータを共有しないでください。 アクションを実行する1つを選択する前に、それぞれが有効な注文をデータベースに照会するいくつかのテストを想像してください。 2つのテストで同じ順序を選択すると、予期しない動作が発生する可能性があります。

* 別のテストで取得される可能性のあるアプリケーション内の古いデータを削除します。 例: 無効な注文レコード

* テストごとに新しいWebDriverインスタンスを作成します。 これにより、テストの分離が保証され、並列化がより簡単になります。

  * If you choose [pytest](https://pytest.org/) as your test runner, this can be easily done by yielding your driver in a global fixture. This way each test gets its own driver instance, and you can ensure that drivers always quit after a test is finished (pass or fail).

# 4.8 - テストの独立性

各テストを独自のユニットとして記述します。 他のテストに依存しない方法でテストを記述してください。

公開後にモジュールとしてWebサイトに表示されるカスタムコンテンツを作成できるコンテンツ管理システム（CMS）があり、CMSとアプリケーション間の同期に時間がかかる場合があるとします。

モジュールをテストする間違った方法は、1つのテストでコンテンツが作成および公開され、別のテストでモジュールをチェックすることです。 コンテンツは公開後、他のテストですぐに利用できない可能性があるため、この方法はふさわしくありません。

代わりに、影響を受けるテスト内でオン/オフできるスタブコンテンツを作成し、それをモジュールの検証に使用できます。 ただし、コンテンツの作成については、別のテストを行うことができます。

# 4.9 - Fluent APIの使用を検討する

マーチン・ファウラーは[“Fluent API”](//www.martinfowler.com/bliki/FluentInterface.html)という用語を作り出しました。 Seleniumは既に、`FluentWait`クラスでこのようなものを実装しています。 これは、標準の`Wait`クラスの代替としてのものです。 ページオブジェクトでFluent APIデザインパターンを有効にしてから、次のようなコードスニペットを使用してGoogle検索ページを照会できます。

```java
driver.get( "http://www.google.com/webhp?hl=en&amp;tab=ww" );
GoogleSearchPage gsp = new GoogleSearchPage(driver);
gsp.setSearchString().clickSearchButton();
```

この流暢な動作を持つGoogleページオブジェクトクラスは次のようになります。

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

public class GoogleSearchPage extends BasePage {
    public GoogleSearchPage(WebDriver driver) {
        super(driver);
        // Generally do not assert within pages or components.
        // Effectively throws an exception if the lambda condition is not met.
        new WebDriverWait(driver, Duration.ofSeconds(3)).until(d -> d.findElement(By.id("logo")));
    }

    public GoogleSearchPage setSearchString(String sstr) {
        driver.findElement(By.id("gbqfq")).sendKeys(sstr);
        return this;
    }

    public void clickSearchButton() {
        driver.findElement(By.id("gbqfb")).click();
    }
}
```

# 4.10 - テストごとに新しいブラウザを起動する

クリーンな既知の状態から各テストを開始します。 理想的には、テストごとに新しい仮想マシンを起動します。 新しい仮想マシンの起動が実用的でない場合は、少なくともテストごとに新しいWebDriverを起動してください。 Firefoxの場合、既知のプロファイルでWebDriverを起動します。 Most browser drivers like GeckoDriver and ChromeDriver will start with a clean known state with a new user profile, by default.

```java
WebDriver driver = new FirefoxDriver();
```

# 5 - 推奨されない行動

Seleniumでブラウザを自動化するときに避けるべきこと。

# 5.1 - CAPTCHA（キャプチャ）

CAPTCHA（キャプチャ）は、 *Completely Automated Public Turing test to tell Computers and Humans Apart* （コンピューターと人間を区別するための完全に自動化された公開チューリングテスト）の略で、自動化を防ぐように明示的に設計されているため、試さないでください！ CAPTCHAチェックを回避するための2つの主要な戦略があります。

* テスト環境でCAPTCHAを無効にします
* テストがCAPTCHAをバイパスできるようにするフックを追加します

# 5.2 - ファイルダウンロード

Seleniumの管理下にあるブラウザーでリンクをクリックしてダウンロードを開始することは可能ですが、APIはダウンロードの進行状況を公開しないため、ダウンロードしたファイルのテストには理想的ではありません。 これは、ファイルのダウンロードは、Webプラットフォームとのユーザーインタラクションをエミュレートする重要な側面とは見なされないためです。 代わりに、Selenium（および必要なCookie）を使用してリンクを見つけ、 [curl](https://curl.se/) などのHTTPリクエストライブラリに渡します。

[HtmlUnitドライバー](https://github.com/SeleniumHQ/htmlunit-driver)は、 [AttachmentHandler](https://htmlunit.sourceforge.io/apidocs/com/gargoylesoftware/htmlunit/attachment/AttachmentHandler.html) インターフェイスを実装することで、 入力ストリームとして添付ファイルにアクセスすることによって、添付ファイルをダウンロードできます。 AttachmentHandlerは、[HtmlUnit](https://htmlunit.sourceforge.io/) に追加できます。

# 5.3 - HTTPレスポンスコード

Selenium RCの一部のブラウザー構成では、Seleniumはブラウザーと自動化されているサイトの間のプロキシとして機能しました。 これは、Seleniumを通過したすべてのブラウザートラフィックをキャプチャまたは操作できることを意味していました。 `captureNetworkTraffic()` メソッドは、HTTPレスポンスコードを含むブラウザーと自動化されているサイト間のすべてのネットワークトラフィックをキャプチャすることを目的としています。

Selenium WebDriverは、ブラウザーの自動化に対するまったく異なるアプローチであり、ユーザーのように振る舞うことを好むため、WebDriverを使用してテストを記述する方法で表現します。 自動化された機能テストでは、ステータスコードの確認はテストの失敗の特に重要な詳細ではありません。 それに先行する手順がより重要です。

ブラウザーは常にHTTPステータスコードを表します。たとえば、404または500エラーページを想像してください。 これらのエラーページの1つに遭遇したときに"早く失敗"する簡単な方法は、ページが読み込まれるたびにページタイトルまたは信頼できるポイント（たとえば `<h1>` タグ）のコンテンツをチェックすることです。 ページオブジェクトモデルを使用している場合、このチェックをクラスコンストラクターまたはページの読み込みが予想される同様のポイントに含めることができます。 場合によっては、HTTPコードがブラウザーのエラーページに表示されることもあります。 WebDriverを使用してこれを読み取り、デバッグ出力を改善できます。

Webページ自体を確認することは、WebDriverの理想的なプラクティスに沿っており、WebDriverのユーザーのWebサイトの見え方を表現し、主張します。

HTTPステータスコードをキャプチャするための高度なソリューションは、プロキシを使用してSelenium RCの動作を複製することです。 WebDriver APIは、ブラウザーのプロキシを設定する機能を提供します。 Webサーバーとの間で送受信されるリクエストのコンテンツをプログラムで操作できるプロキシがいくつかあります。 プロキシを使用すると、リダイレクトレスポンスコードへの応答方法を決めることができます。 さらに、すべてのブラウザーがWebDriverでレスポンスコードを利用できるようにするわけではないため、プロキシを使用することを選択すると、すべてのブラウザーで機能するソリューションが得られます。

# 5.4 - Gmail、Eメール、Facebookログイン

複数の理由から、WebDriverを使用してGmailやFacebookなどのサイトにログインすることはお勧めしません。 これらのサイトの使用条件（アカウントがシャットダウンされるリスクがある）に違反することは別として、それは遅く、信頼性がありません。

理想的なプラクティスは、メールプロバイダーが提供するAPIを使用すること、またはFacebookの場合、テストアカウントや友人などを作成するためのAPIを公開する開発者ツールサービスを使用することです。 APIの使用は少し大変な作業のように思えるかもしれませんが、速度、信頼性、および安定性に見返りがあります。 また、APIが変更されることはほとんどありませんが、WebページとHTMLロケーターは頻繁に変更され、テストフレームワークを更新する必要があります。

テストの任意の時点でWebDriverを使用してサードパーティのサイトにログインすると、テストが長くなるため、テストが失敗するリスクが高くなります。 一般的な経験則として、テストが長くなるほど脆弱で信頼性が低くなります。

[W3C準拠](//w3c.github.io/webdriver/webdriver-spec.html) のWebDriver実装は、サービス拒否攻撃を軽減できるように、`navigator`オブジェクトに`WebDriver`プロパティで注釈を付けます。

# 5.5 - テストの依存関係

自動テストに関する一般的な考え方と誤解は、特定のテスト順序に関するものです。 テストは **任意** の順序で実行でき、成功するために完了するために他のテストに依存してはなりません。

# 5.6 - パフォーマンステスト

通常、SeleniumとWebDriverを使用したパフォーマンステストはお勧めしません。 それができないからではなく、ジョブに最適化されておらず、良い結果が得られないからです。

ユーザーのコンテキストでパフォーマンステストを行うのが理想的なように思えるかもしれませんが、WebDriverテストスイートは、外部および内部の脆弱性の多くのポイントにさらされます。 たとえば、ブラウザの起動速度、HTTPサーバーの速度、JavaScriptまたはCSSをホストするサードパーティサーバーの応答、およびWebDriver実装自体の計測ペナルティ。 これらのポイントが変わることで、結果が変わります。 Webサイトのパフォーマンスと外部リソースのパフォーマンスの違いを区別することは困難です。また、ブラウザでWebDriverを使用すること、特にスクリプトを挿入する場合のパフォーマンスの低下を把握することも困難です。

他の潜在的な魅力は “時間の節約” です。 機能テストとパフォーマンステストを同時に実行します。 ただし、機能テストとパフォーマンステストには反対の目的があります。 機能をテストするために、テスターは忍耐強くロードを待つ必要があるかもしれませんが、これはパフォーマンステスト結果を曖昧にし、その逆もまた同様です。

Webサイトのパフォーマンスを改善するには、改善すべき点を知るために、環境の違いに関係なく全体的なパフォーマンスを分析し、貧弱なコードプラクティス、個々のリソース（例えば、CSSまたはJavaScript）のパフォーマンスの内訳を特定できる必要があります。 このジョブを実行できるパフォーマンステストツールが既にあり、それらは改善を提案できるレポートと分析を提供します。

使用する（オープンソース）パッケージの例は次のとおりです。: [JMeter](/ja/)

# 5.7 - リンクスパイダー

WebDriverを使用してリンクをスパイダーすることは、実行できないためではなく、最も理想的なツールではないため明らかに推奨される方法ではありません。 WebDriverの起動には時間が必要であり、テストの記述方法によっては、ページに到達してDOMを通過するために数秒から1分かかる場合があります。

このためにWebDriverを使用する代わりに、[curl](https://curl.se/) コマンドを実行するか、BeautifulSoupなどのライブラリを使用することにより、これらの方法はブラウザーの作成やページへの移動に依存しないため、時間を大幅に節約できます。 このタスクにWebDriverを使用しないことで、時間を大幅に節約できます。

# 5.8 - 二要素認証

----
url: https://www.selenium.dev/documentation/legacy/developers/summer_of_code/
----

# Google Summer of Code 2011

----
url: https://www.selenium.dev/ja/documentation/
----

# Seleniumブラウザー自動化プロジェクト

Seleniumはブラウザー自動化を可能にし、それを支えるツール群とライブラリー群プロジェクトです。

ユーザーとブラウザーのやり取りのエミュレーション、ブラウザーの割当を増強したり縮減する分散型サーバー、そしてすべてのメジャーなブラウザー用に置換可能なコードの実装を可能にする[W3C WebDriver 仕様](//www.w3.org/TR/webdriver/)インフラの提供します。

このプロジェクトは多くの有志貢献者の何千時間に及ぶ個々の時間を費やした事とソースコード[自由に利用可能](https://www.selenium.dev/ja/documentation/about/copyright/#license)を誰にでも利用、楽しめ、そして改良できることによって実現しました。

Seleniumはウェブプラットフォームの自動化のより開かれた議論をするためブラウザーベンダー、エンジニア、愛好家をまとめます。このプロジェクトはコミュニティーを導きと育成のために[年次カンファレンス](/ja/)開催します。

Seleniumの中核は[WebDriver](https://www.selenium.dev/ja/documentation/webdriver/)であり、様々なブラウザーを変えてインストラクション集を実行できるインターフェースです。これは作りえる一番基本的な インストラクションの一つです:

*
*
*
*
*
*

```java
package dev.selenium.hello;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class HelloSelenium {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://selenium.dev");

        driver.quit();
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/hello/HelloSelenium.java)

```py
from selenium import webdriver


driver = webdriver.Chrome()

driver.get("http://selenium.dev")

driver.quit()
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/hello/hello_selenium.py)

```cs
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Hello;

public static class HelloSelenium
{
    public static void Main()
    {
        var driver = new ChromeDriver();
            
        driver.Navigate().GoToUrl("https://selenium.dev");
            
        driver.Quit();
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/HelloSelenium.cs)

```rb
# frozen_string_literal: true

require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get 'https://selenium.dev'

driver.quit
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/hello/hello_selenium.rb)

```js
const {Builder, Browser} = require('selenium-webdriver');

(async function helloSelenium() {
  let driver = await new Builder().forBrowser(Browser.CHROME).build();

  await driver.get('https://selenium.dev');

  await driver.quit();
})();
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/hello/helloSelenium.js)

```kt
package dev.selenium.hello

import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()

    driver.get("https://selenium.dev")

    driver.quit()
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/hello/HelloSelenium.kt)

[概要](https://www.selenium.dev/ja/documentation/overview/)を参照して、さまざまなプロジェクトコンポーネントを確認し、 Seleniumが適切なツールであるかどうかを判断してください。

[入門](https://www.selenium.dev/ja/documentation/webdriver/getting_started/)に進んで、 Seleniumをインストールし、テスト自動化ツールとして正常に使用する方法を理解し、 このような単純なテストをスケーリングして、複数のブラウザー、 複数の異なるオペレーティングシステムの大規模な分散環境で実行する必要があります。

***

##### [概要](/ja/documentation/overview/)

Seleniumはあなたに適していますか？さまざまなプロジェクトのコンポーネントの概要を参照してください。

##### [WebDriver](/ja/documentation/webdriver/)

WebDriverはブラウザをネイティブに操作します。詳細については、こちらをご覧ください。

##### [Selenium Manager (Beta)](/ja/documentation/selenium_manager/)

Selenium Manager is a command-line tool implemented in Rust that provides automated driver and browser management for Selenium. Selenium bindings use this tool by default, so you do not need to download it or add anything to your code or do anything else to use it.

##### [Grid](/ja/documentation/grid/)

複数のマシンで並行してテストを実行したいですか？ Grid が手助けします。

##### [IE Driver サーバー](/ja/documentation/ie_driver_server/)

Internet Explorer Driverは、WebDriverの仕様を実装するスタンドアロンサーバーです。

##### [Selenium IDE](/ja/documentation/ide/)

Selenium IDEは、ユーザーのアクションを記録および再生するブラウザー拡張機能です。

##### [テストの実践](/ja/documentation/test_practices/)

Seleniumプロジェクトからのテストに関するいくつかのガイドラインと推奨事項

##### [レガシー](/ja/documentation/legacy/)

このセクションでは、Seleniumのレガシーコンポーネントに関連するすべてのドキュメントを見つけることができます。 これは、非推奨コンポーネントを使用する動機としてではなく、純粋に歴史的な理由で保持されることを意図しています。

##### [このドキュメントについて](/ja/documentation/about/)

最終更新 April 6, 2025: [\[rb\] do not run hello selenium in examples (efaae63f2b6)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/efaae63f2b66029b5022e5b0348414a1a29c631f)

----
url: https://www.selenium.dev/documentation/webdriver/actions_api/
----

# Actions API

A low-level interface for providing virtualized device input actions to the web browser.

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/ActionsTest.java#L21-L28)

##### /examples/java/src/test/java/dev/selenium/actions\_api/ActionsTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;

public class ActionsTest extends BaseChromeTest {
    @Test
    public void pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        long start = System.currentTimeMillis();

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();

        long duration = System.currentTimeMillis() - start;
        Assertions.assertTrue(duration > 2000);
        Assertions.assertTrue(duration < 3000);
    }

    @Test
    public void releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        Actions actions = new Actions(driver);
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        ((RemoteWebDriver) driver).resetInputState();

        actions.sendKeys("a").perform();
        Assertions.assertEquals("A", String.valueOf(clickable.getAttribute("value").charAt(0)));
        Assertions.assertEquals("a", String.valueOf(clickable.getAttribute("value").charAt(1)));
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_actions.py#L13-L20)

##### /examples/python/tests/actions\_api/test\_actions.py

```py
from time import time

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.by import By


def test_pauses(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    start = time()

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()

    duration = time() - start
    assert duration > 2
    assert duration < 3


def test_releases_all(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .click_and_hold(clickable)\
        .key_down(Keys.SHIFT)\
        .key_down("a")\
        .perform()

    ActionBuilder(driver).clear_actions()

    ActionChains(driver).key_down('a').perform()

    assert clickable.get_attribute('value')[0] == "A"
    assert clickable.get_attribute('value')[1] == "a"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs#L18-L25)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class ActionsTest : BaseChromeTest
    {
        [TestMethod]
        public void Pause()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            DateTime start = DateTime.Now;

            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();

            TimeSpan duration = DateTime.Now - start;
            Assert.IsTrue(duration > TimeSpan.FromSeconds(2));
            Assert.IsTrue(duration < TimeSpan.FromSeconds(3));
        }

        [TestMethod]
        public void ReleaseAll()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            var actions = new Actions(driver);
            actions.ClickAndHold(clickable)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            ((WebDriver)driver).ResetInputState();

            actions.SendKeys("a").Perform();
            var value = clickable.GetAttribute("value");
            Assert.AreEqual("A", value[..1]);
            Assert.AreEqual("a", value.Substring(1, 1));
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/actions_spec.rb#L12-L19)

##### /examples/ruby/spec/actions\_api/actions\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Actions' do
  let(:driver) { start_session }

  it 'pauses' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
    start = Time.now

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform

    duration = Time.now - start
    expect(duration).to be > 2
    expect(duration).to be < 3
  end

  it 'releases all' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    action = driver.action
                   .click_and_hold(clickable)
                   .key_down(:shift)
                   .key_down('a')
    action.perform

    driver.action.release_actions

    action.key_down('a').perform
    expect(clickable.attribute('value')[0]).to eq 'A'
    expect(clickable.attribute('value')[-1]).to eq 'a'
  end
end
```

```js
    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/actionsTest.spec.js#L18-L25)

##### /examples/javascript/test/actionsApi/actionsTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Pause and Release All Actions', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('Pause', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const start = Date.now()

    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()

    const end = Date.now() - start
    assert.ok(end > 2000)
    assert.ok(end < 4000)
  })

  it('Clear', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const clickable = driver.findElement(By.id('clickable'))
    await driver.actions()
      .click(clickable)
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    await driver.actions().clear()
    await driver.actions().sendKeys('a').perform()

    const value = await clickable.getAttribute('value')
    assert.deepStrictEqual('A', value.substring(0, 1))
    assert.deepStrictEqual('a', value.substring(1, 2))
  })
})
```

```kt
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/ActionsTest.kt#L22-L29)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/ActionsTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration

class ActionsTest : BaseTest() {

    @Test
    fun pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val start = System.currentTimeMillis()

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 

        val duration = System.currentTimeMillis() - start
        Assertions.assertTrue(duration > 2000)
        Assertions.assertTrue(duration < 4000)
    }

    @Test
    fun releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        val actions = Actions(driver)
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        (driver as RemoteWebDriver).resetInputState()

        actions.sendKeys("a").perform()
        Assertions.assertEquals("A", clickable.getAttribute("value")!!.get(0).toString())
        Assertions.assertEquals("a", clickable.getAttribute("value")!!.get(1).toString())
    }
}
```

```java
        ((RemoteWebDriver) driver).resetInputState();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/ActionsTest.java#L46)

##### /examples/java/src/test/java/dev/selenium/actions\_api/ActionsTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;

public class ActionsTest extends BaseChromeTest {
    @Test
    public void pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        long start = System.currentTimeMillis();

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();

        long duration = System.currentTimeMillis() - start;
        Assertions.assertTrue(duration > 2000);
        Assertions.assertTrue(duration < 3000);
    }

    @Test
    public void releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        Actions actions = new Actions(driver);
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        ((RemoteWebDriver) driver).resetInputState();

        actions.sendKeys("a").perform();
        Assertions.assertEquals("A", String.valueOf(clickable.getAttribute("value").charAt(0)));
        Assertions.assertEquals("a", String.valueOf(clickable.getAttribute("value").charAt(1)));
    }
}
```

```py
    ActionBuilder(driver).clear_actions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_actions.py#L37)

##### /examples/python/tests/actions\_api/test\_actions.py

```py
from time import time

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.by import By


def test_pauses(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    start = time()

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()

    duration = time() - start
    assert duration > 2
    assert duration < 3


def test_releases_all(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .click_and_hold(clickable)\
        .key_down(Keys.SHIFT)\
        .key_down("a")\
        .perform()

    ActionBuilder(driver).clear_actions()

    ActionChains(driver).key_down('a').perform()

    assert clickable.get_attribute('value')[0] == "A"
    assert clickable.get_attribute('value')[1] == "a"
```

```cs
            ((WebDriver)driver).ResetInputState();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs#L44)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class ActionsTest : BaseChromeTest
    {
        [TestMethod]
        public void Pause()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            DateTime start = DateTime.Now;

            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();

            TimeSpan duration = DateTime.Now - start;
            Assert.IsTrue(duration > TimeSpan.FromSeconds(2));
            Assert.IsTrue(duration < TimeSpan.FromSeconds(3));
        }

        [TestMethod]
        public void ReleaseAll()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            var actions = new Actions(driver);
            actions.ClickAndHold(clickable)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            ((WebDriver)driver).ResetInputState();

            actions.SendKeys("a").Perform();
            var value = clickable.GetAttribute("value");
            Assert.AreEqual("A", value[..1]);
            Assert.AreEqual("a", value.Substring(1, 1));
        }
    }
}
```

```rb
    driver.action.release_actions
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/actions_spec.rb#L36)

##### /examples/ruby/spec/actions\_api/actions\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Actions' do
  let(:driver) { start_session }

  it 'pauses' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
    start = Time.now

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform

    duration = Time.now - start
    expect(duration).to be > 2
    expect(duration).to be < 3
  end

  it 'releases all' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    action = driver.action
                   .click_and_hold(clickable)
                   .key_down(:shift)
                   .key_down('a')
    action.perform

    driver.action.release_actions

    action.key_down('a').perform
    expect(clickable.attribute('value')[0]).to eq 'A'
    expect(clickable.attribute('value')[-1]).to eq 'a'
  end
end
```

```js
    await driver.actions().clear()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/actionsTest.spec.js#L42)

##### /examples/javascript/test/actionsApi/actionsTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Pause and Release All Actions', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('Pause', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const start = Date.now()

    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()

    const end = Date.now() - start
    assert.ok(end > 2000)
    assert.ok(end < 4000)
  })

  it('Clear', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const clickable = driver.findElement(By.id('clickable'))
    await driver.actions()
      .click(clickable)
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    await driver.actions().clear()
    await driver.actions().sendKeys('a').perform()

    const value = await clickable.getAttribute('value')
    assert.deepStrictEqual('A', value.substring(0, 1))
    assert.deepStrictEqual('a', value.substring(1, 2))
  })
})
```

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/ActionsTest.kt#L47)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/ActionsTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration

class ActionsTest : BaseTest() {

    @Test
    fun pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val start = System.currentTimeMillis()

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 

        val duration = System.currentTimeMillis() - start
        Assertions.assertTrue(duration > 2000)
        Assertions.assertTrue(duration < 4000)
    }

    @Test
    fun releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        val actions = Actions(driver)
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        (driver as RemoteWebDriver).resetInputState()

        actions.sendKeys("a").perform()
        Assertions.assertEquals("A", clickable.getAttribute("value")!!.get(0).toString())
        Assertions.assertEquals("a", clickable.getAttribute("value")!!.get(1).toString())
    }
}
```

***

##### [Keyboard actions](/documentation/webdriver/actions_api/keyboard/)

A representation of any key input device for interacting with a web page.

##### [Mouse actions](/documentation/webdriver/actions_api/mouse/)

A representation of any pointer device for interacting with a web page.

##### [Pen actions](/documentation/webdriver/actions_api/pen/)

A representation of a pen stylus kind of pointer input for interacting with a web page.

##### [Scroll wheel actions](/documentation/webdriver/actions_api/wheel/)

A representation of a scroll wheel input device for interacting with a web page.

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/encouraged/page_object_models/
----

# Modelos de objetos de página

```java
/***
 * Tests login feature
 */
public class Login {

  public void testLogin() {
    // fill login data on sign-in page
    driver.findElement(By.name("user_name")).sendKeys("userName");
    driver.findElement(By.name("password")).sendKeys("my supersecret password");
    driver.findElement(By.name("sign-in")).click();

    // verify h1 tag is "Hello userName" after login
    driver.findElement(By.tagName("h1")).isDisplayed();
    assertThat(driver.findElement(By.tagName("h1")).getText(), is("Hello userName"));
  }
}
```

There are two problems with this approach.

* There is no separation between the test method and the AUT’s locators (IDs in this example); both are intertwined in a single method. If the AUT’s UI changes its identifiers, layout, or how a login is input and processed, the test itself must change.
* The ID-locators would be spread in multiple tests, in all tests that had to use this login page.

Applying the page object model, this example could be rewritten like this in the following example of a page object for a Sign-in page.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Sign-in page.
 */
public class SignInPage {
  protected WebDriver driver;

  // <input name="user_name" type="text" value="">
  private By usernameBy = By.name("user_name");
  // <input name="password" type="password" value="">
  private By passwordBy = By.name("password");
  // <input name="sign_in" type="submit" value="SignIn">
  private By signinBy = By.name("sign_in");

  public SignInPage(WebDriver driver){
    this.driver = driver;
     if (!driver.getTitle().equals("Sign In Page")) {
      throw new IllegalStateException("This is not Sign In Page," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Login as valid user
    *
    * @param userName
    * @param password
    * @return HomePage object
    */
  public HomePage loginValidUser(String userName, String password) {
    driver.findElement(usernameBy).sendKeys(userName);
    driver.findElement(passwordBy).sendKeys(password);
    driver.findElement(signinBy).click();
    return new HomePage(driver);
  }
}
```

and page object for a Home page could look like this.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Home Page
 */
public class HomePage {
  protected WebDriver driver;

  // <h1>Hello userName</h1>
  private By messageBy = By.tagName("h1");

  public HomePage(WebDriver driver){
    this.driver = driver;
    if (!driver.getTitle().equals("Home Page of logged in user")) {
      throw new IllegalStateException("This is not Home Page of logged in user," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Get message (h1 tag)
    *
    * @return String message text
    */
  public String getMessageText() {
    return driver.findElement(messageBy).getText();
  }

  public HomePage manageProfile() {
    // Page encapsulation to manage profile functionality
    return new HomePage(driver);
  }
  /* More methods offering the services represented by Home Page
  of Logged User. These methods in turn might return more Page Objects
  for example click on Compose mail button could return ComposeMail class object */
}
```

So now, the login test would use these two page objects as follows.

```java
/***
 * Tests login feature
 */
public class TestLogin {

  @Test
  public void testLogin() {
    SignInPage signInPage = new SignInPage(driver);
    HomePage homePage = signInPage.loginValidUser("userName", "password");
    assertThat(homePage.getMessageText(), is("Hello userName"));
  }

}
```

```html
<!-- Products Page -->
<div class="header_container">
    <span class="title">Products</span>
</div>

<div class="inventory_list">
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
</div>
```

Each product is a component of the Products page.

```html
<!-- Inventory Item -->
<div class="inventory_item">
    <div class="inventory_item_name">Backpack</div>
    <div class="pricebar">
        <div class="inventory_item_price">$29.99</div>
        <button id="add-to-cart-backpack">Add to cart</button>
    </div>
</div>
```

The Products page HAS-A list of products. This object relationship is called Composition. In simpler terms, something is *composed of* another thing.

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

// Page Object
public class ProductsPage extends BasePage {
    public ProductsPage(WebDriver driver) {
        super(driver);
        // No assertions, throws an exception if the element is not loaded
        new WebDriverWait(driver, Duration.ofSeconds(3))
            .until(d -> d.findElement(By.className​("header_container")));
    }

    // Returning a list of products is a service of the page
    public List<Product> getProducts() {
        return driver.findElements(By.className​("inventory_item"))
            .stream()
            .map(e -> new Product(e)) // Map WebElement to a product component
            .toList();
    }

    // Return a specific product using a boolean-valued function (predicate)
    // This is the behavioral Strategy Pattern from GoF
    public Product getProduct(Predicate<Product> condition) {
        return getProducts()
            .stream()
            .filter(condition) // Filter by product name or price
            .findFirst()
            .orElseThrow(() -> new RuntimeException("Product not found")); // Error thrown during actual test run
    }
}
```

The Product component object is used inside the Products page object.

```java
public abstract class BaseComponent {
    protected WebElement root;

    public BaseComponent(WebElement root) {
        this.root = root;
    }
}

// Page Component Object
public class Product extends BaseComponent {
    // The root element contains the entire component
    public Product(WebElement root) {
        super(root); // inventory_item
    }

    public String getName() {
        // Locating an element begins at the root of the component
        return root.findElement(By.className("inventory_item_name")).getText();
    }

    public BigDecimal getPrice() {
        return new BigDecimal(
                root.findElement(By.className("inventory_item_price"))
                    .getText()
                    .replace("$", "")
            ).setScale(2, RoundingMode.UNNECESSARY); // Sanitation and formatting
    }

    public void addToCart() {
        root.findElement(By.id("add-to-cart-backpack")).click();
    }
}
```

So now, the products test would use the page object and the page component object as follows.

```java
public class ProductsTest {
    @Test
    public void testProductInventory() {
        var productsPage = new ProductsPage(driver); // page object
        var products = productsPage.getProducts();
        assertEquals(6, products.size()); // expected, actual
    }
    
    @Test
    public void testProductPrices() {
        var productsPage = new ProductsPage(driver);

        // Pass a lambda expression (predicate) to filter the list of products
        // The predicate or "strategy" is the behavior passed as parameter
        var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); // page component object
        var bikeLight = productsPage.getProduct(p -> p.getName().equals("Bike Light"));

        assertEquals(new BigDecimal("29.99"), backpack.getPrice());
        assertEquals(new BigDecimal("9.99"), bikeLight.getPrice());
    }
}
```

```java
public class LoginPage {
    public HomePage loginAs(String username, String password) {
        // ... clever magic happens here
    }
    
    public LoginPage loginAsExpectingError(String username, String password) {
        //  ... failed login here, maybe because one or both of the username and password are wrong
    }
    
    public String getErrorMessage() {
        // So we can verify that the correct error is shown
    }
}
```

The code presented above shows an important point: the tests, not the Page Objects, should be responsible for making assertions about the state of a page. For example:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    inbox.assertMessageWithSubjectIsUnread("I like cheese");
    inbox.assertMessageWithSubjectIsNotUnread("I'm not fond of tofu");
}
```

could be re-written as:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    assertTrue(inbox.isMessageWithSubjectIsUnread("I like cheese"));
    assertFalse(inbox.isMessageWithSubjectIsUnread("I'm not fond of tofu"));
}
```

```java
public class LoginPage {
    private final WebDriver driver;

    public LoginPage(WebDriver driver) {
        this.driver = driver;

        // Check that we're on the right page.
        if (!"Login".equals(driver.getTitle())) {
            // Alternatively, we could navigate to the login page, perhaps logging out first
            throw new IllegalStateException("This is not the login page");
        }
    }

    // The login page contains several HTML elements that will be represented as WebElements.
    // The locators for these elements should only be defined once.
        By usernameLocator = By.id("username");
        By passwordLocator = By.id("passwd");
        By loginButtonLocator = By.id("login");

    // The login page allows the user to type their username into the username field
    public LoginPage typeUsername(String username) {
        // This is the only place that "knows" how to enter a username
        driver.findElement(usernameLocator).sendKeys(username);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to type their password into the password field
    public LoginPage typePassword(String password) {
        // This is the only place that "knows" how to enter a password
        driver.findElement(passwordLocator).sendKeys(password);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to submit the login form
    public HomePage submitLogin() {
        // This is the only place that submits the login form and expects the destination to be the home page.
        // A seperate method should be created for the instance of clicking login whilst expecting a login failure. 
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the login page ever
        // go somewhere else (for example, a legal disclaimer) then changing the method signature
        // for this method will mean that all tests that rely on this behaviour won't compile.
        return new HomePage(driver);	
    }

    // The login page allows the user to submit the login form knowing that an invalid username and / or password were entered
    public LoginPage submitLoginExpectingFailure() {
        // This is the only place that submits the login form and expects the destination to be the login page due to login failure.
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the user ever be navigated to the home page after submiting a login with credentials 
        // expected to fail login, the script will fail when it attempts to instantiate the LoginPage PageObject.
        return new LoginPage(driver);	
    }

    // Conceptually, the login page offers the user the service of being able to "log into"
    // the application using a user name and password. 
    public HomePage loginAs(String username, String password) {
        // The PageObject methods that enter username, password & submit login have already defined and should not be repeated here.
        typeUsername(username);
        typePassword(password);
        return submitLogin();
    }
}
```

Última modificação October 30, 2025: [docs: improve consistency and readability of the guide (#2168) (708f32f0c58)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/708f32f0c58c2386be472aec8b74801183f6743a)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/elements/locators/
----

# Localizando elementos

Formas de identificar um ou mais elementos no DOM.

Um localizador é uma forma de identificar elementos numa página. São os argumentos passados aos métodos [Finders](https://www.selenium.dev/pt-br/documentation/webdriver/elements/finders/) .

Visite os nossas [directrizes e recomendações](https://www.selenium.dev/pt-br/documentation/test_practices/encouraged/) para dicas sobre [locators](https://www.selenium.dev/pt-br/documentation/test_practices/encouraged/locators/), incluindo quais usar e quando, e também porque é que deve declarar localizadores separadamente dos finders.

### Estratégias de seleção de elemento

Existem oito estratégias diferentes de localização de elementos embutidas no WebDriver:

| Localizador       | Descrição                                                                                                                                               |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| class name        | Localiza elementos cujo nome de classe contém o valor de pesquisa (nomes de classes compostas não são permitidos)                                       |
| css selector      | Localiza elementos que correspondem a um seletor CSS                                                                                                    |
| id                | Localiza elementos cujo atributo de ID corresponde ao valor de pesquisa                                                                                 |
| name              | Localiza elementos cujo atributo NAME corresponde ao valor de pesquisa                                                                                  |
| link text         | Localiza elementos âncora cujo texto visível corresponde ao valor de pesquisa                                                                           |
| partial link text | Localiza elementos âncora cujo texto visível contém o valor da pesquisa. Se vários elementos forem correspondentes, apenas o primeiro será selecionado. |
| tag name          | Localiza elementos cujo nome de tag corresponde ao valor de pesquisa                                                                                    |
| xpath             | Localiza elementos que correspondem a uma expressão XPath                                                                                               |

## Creating Locators

To work on a web element using Selenium, we need to first locate it on the web page. Selenium provides us above mentioned ways, using which we can locate element on the page. To understand and create locator we will use the following HTML snippet.

```html
<html>
<body>
<style>
.information {
  background-color: white;
  color: black;
  padding: 10px;
}
</style>
<h2>Contact Selenium</h2>

<form>
  <input type="radio" name="gender" value="m" />Male &nbsp;
  <input type="radio" name="gender" value="f" />Female <br>
  <br>
  <label for="fname">First name:</label><br>
  <input class="information" type="text" id="fname" name="fname" value="Jane"><br><br>
  <label for="lname">Last name:</label><br>
  <input class="information" type="text" id="lname" name="lname" value="Doe"><br><br>
  <label for="newsletter">Newsletter:</label>
  <input type="checkbox" name="newsletter" value="1" /><br><br>
  <input type="submit" value="Submit">
</form> 

<p>To know more about Selenium, visit the official page 
<a href ="www.selenium.dev">Selenium Official Page</a> 
</p>

</body>
</html>
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L31" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L7-L9)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.ClassName("information"));
  
```

```rb
    driver.find_element(class: 'information')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L7)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.className('information'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.className("information"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L38" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L17-L19)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.CssSelector("#fname"));
  
```

```rb
    driver.find_element(css: '#fname')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L11)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.css('#fname'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.css("#fname"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L45" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L27-L29)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.Id("lname"));
  
```

```rb
    driver.find_element(id: 'lname')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L15)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.id('lname'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.id("lname"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L52" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L37-L39)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.Name("newsletter"));
  
```

```rb
    driver.find_element(name: 'newsletter')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L19)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.name('newsletter'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.name("newsletter"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L59" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L47-L49)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.LinkText("Selenium Official Page"));
  
```

```rb
    driver.find_element(link_text: 'Selenium Official Page')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L23)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.linkText('Selenium Official Page'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.linkText("Selenium Official Page"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L66" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L57-L59)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.PartialLinkText("Official Page"));
  
```

```rb
    driver.find_element(partial_link_text: 'Official Page')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L27)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.partialLinkText('Official Page'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.partialLinkText("Official Page"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L73" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L67-L69)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.TagName("a"));
  
```

```rb
    driver.find_element(tag_name: 'a')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L31)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.tagName('a'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.tagName("a"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L80" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L77-L79)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.Xpath("//input[@value='f']"));
  
```

```rb
    driver.find_element(xpath: "//input[@value='f']")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L35)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.xpath('//input[@value='f']'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.xpath('//input[@value='f']'))
  
```

```java
    import org.openqa.selenium.By;
    WebDriver driver = new ChromeDriver();
	driver.findElement(By.className("information"));
  
```

```python
    from selenium.webdriver.common.by import By
    driver = webdriver.Chrome()
	driver.find_element(By.CLASS_NAME, "information")
  
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.ClassName("information"));
  
```

```rb
    driver.find_element(class: 'information')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L7)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.className('information'));
  
```

```kotlin
    import org.openqa.selenium.By
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.className("information"))
  
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java#L37-L38)

##### /examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java

```java
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java#L22-L23)

##### /examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java

```java
```

```java
By emailLocator = RelativeLocator.with(By.tagName("input")).above(By.id("password"));
```

```python
email_locator = locate_with(By.TAG_NAME, "input").above({By.ID: "password"})
```

```csharp
var emailLocator = RelativeBy.WithLocator(By.TagName("input")).Above(By.Id("password"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L40)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let emailLocator = locateWith(By.tagName('input')).above(By.id('password'));
```

```kotlin
val emailLocator = RelativeLocator.with(By.tagName("input")).above(By.id("password"))
```

```java
By passwordLocator = RelativeLocator.with(By.tagName("input")).below(By.id("email"));
```

```python
password_locator = locate_with(By.TAG_NAME, "input").below({By.ID: "email"})
```

```csharp
var passwordLocator = RelativeBy.WithLocator(By.TagName("input")).Below(By.Id("email"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L44)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let passwordLocator = locateWith(By.tagName('input')).below(By.id('email'));
```

```kotlin
val passwordLocator = RelativeLocator.with(By.tagName("input")).below(By.id("email"))
```

```java
By cancelLocator = RelativeLocator.with(By.tagName("button")).toLeftOf(By.id("submit"));
```

```python
cancel_locator = locate_with(By.TAG_NAME, "button").to_left_of({By.ID: "submit"})
```

```csharp
var cancelLocator = RelativeBy.WithLocator(By.tagName("button")).LeftOf(By.Id("submit"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L48)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let cancelLocator = locateWith(By.tagName('button')).toLeftOf(By.id('submit'));
```

```kotlin
val cancelLocator = RelativeLocator.with(By.tagName("button")).toLeftOf(By.id("submit"))
```

```java
By submitLocator = RelativeLocator.with(By.tagName("button")).toRightOf(By.id("cancel"));
```

```python
submit_locator = locate_with(By.TAG_NAME, "button").to_right_of({By.ID: "cancel"})
```

```csharp
var submitLocator = RelativeBy.WithLocator(By.tagName("button")).RightOf(By.Id("cancel"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L52)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let submitLocator = locateWith(By.tagName('button')).toRightOf(By.id('cancel'));
```

```kotlin
val submitLocator = RelativeLocator.with(By.tagName("button")).toRightOf(By.id("cancel"))
```

```java
By emailLocator = RelativeLocator.with(By.tagName("input")).near(By.id("lbl-email"));
```

```python
email_locator = locate_with(By.TAG_NAME, "input").near({By.ID: "lbl-email"})
```

```csharp
var emailLocator = RelativeBy.WithLocator(By.tagName("input")).Near(By.Id("lbl-email"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L56)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let emailLocator = locateWith(By.tagName('input')).near(By.id('lbl-email'));
```

```kotlin
val emailLocator = RelativeLocator.with(By.tagName("input")).near(By.id("lbl-email"));
```

```java
By submitLocator = RelativeLocator.with(By.tagName("button")).below(By.id("email")).toRightOf(By.id("cancel"));
```

```python
submit_locator = locate_with(By.TAG_NAME, "button").below({By.ID: "email"}).to_right_of({By.ID: "cancel"})
```

```csharp
var submitLocator = RelativeBy.WithLocator(By.tagName("button")).Below(By.Id("email")).RightOf(By.Id("cancel"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L60)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let submitLocator = locateWith(By.tagName('button')).below(By.id('email')).toRightOf(By.id('cancel'));
```

```kotlin
val submitLocator = RelativeLocator.with(By.tagName("button")).below(By.id("email")).toRightOf(By.id("cancel"))
```

Última modificação February 16, 2026: [added locator code file for java for locator strategies Section and added content in diff languages files (#2583) (77549cd7301)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/77549cd7301dea332c7559cb6a5365a82a357e50)

----
url: https://www.selenium.dev/_print/documentation/grid/configuration/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/grid/configuration/).

# Configuration of Components

Here you can see how each Grid component can be configured individually based on common configuration values and component-specific configuration values.

* 1: [Configuration help](#pg-b0833a230d156d49a170ccaf66b15c1e)
* 2: [CLI options in the Selenium Grid](#pg-06c8cbccc2ebce678b8300b1dbf16cfa)
* 3: [TOML configuration options](#pg-84bc4f2f9f496018f9d4d76137abb5a3)

# 1 - Configuration help

```shell
java -jar selenium-server-<version>.jar info config
```

### Security

To get details on setting up the Grid servers for secure communication and node registration:

```shell
java -jar selenium-server-<version>.jar info security
```

### Session Map setup

By default, Grid uses a local session map to store session information. Grid supports additional storage options like Redis and JDBC - SQL supported databases. To set up different session storage, use the following command to get setup steps:

```shell
java -jar selenium-server-<version>.jar info sessionmap
```

### Setting up tracing with OpenTelemetry and Jaeger

By default, tracing is enabled. To export traces and visualize them via Jaeger, use the following command for instructions:

```shell
java -jar selenium-server-<version>.jar info tracing
```

## List the Selenium Grid commands

```shell
java -jar selenium-server-<version>.jar --config-help
```

It will show all the available commands and description for each one.

## Component help commands

Pass –help config option after the Selenium role to get component-specific config information.

### Standalone

```shell
java -jar selenium-server-<version>.jar standalone --help
```

### Hub

```shell
java -jar selenium-server-<version>.jar hub --help
```

### Sessions

```shell
java -jar selenium-server-<version>.jar sessions --help
```

### New Session Queue

```shell
java -jar selenium-server-<version>.jar sessionqueue --help
```

### Distributor

```shell
java -jar selenium-server-<version>.jar distributor --help
```

### Router

```shell
java -jar selenium-server-<version>.jar router --help
```

### Node

```shell
java -jar selenium-server-<version>.jar node --help
```

# 2 - CLI options in the Selenium Grid

All Grid components configuration CLI options in detail.

Different sections are available to configure a Grid. Each section has options can be configured through command line arguments.

A complete description of the component to section mapping can be seen below.

Note that this documentation could be outdated if an option was modified or added but has not been documented yet. In case you bump into this situation, please check the [“Config help”](https://www.selenium.dev/documentation/grid/configuration/help/) section and feel free to send us a pull request updating this page.

## Sections

|                               | Standalone | Hub | Node | Distributor | Router | Sessions | SessionQueue |
| ----------------------------- | ---------- | --- | ---- | ----------- | ------ | -------- | ------------ |
| [Distributor](#distributor)   | **         | **  |      | **          | **     |          |              |
| [Docker](#docker)             | **         |     | **   |             |        |          |              |
| [Kubernetes](#kubernetes)     | **         |     | **   |             |        |          |              |
| [Events](#events)             |            | **  | **   | **          |        | **       | **           |
| [Logging](#logging)           | **         | **  | **   | **          | **     | **       | **           |
| [Network](#network)           | **         | **  |      |             | **     |          |              |
| [Node](#node)                 | **         |     | **   |             |        |          |              |
| [Router](#router)             | **         | **  |      |             | **     |          |              |
| [Relay](#relay)               | **         |     | **   |             |        |          |              |
| [Server](#server)             | **         | **  | **   | **          | **     | **       | **           |
| [SessionQueue](#sessionqueue) | **         | **  |      | **          | **     |          | **           |
| [Sessions](#sessions)         |            |     |      | **          | **     | **       |              |

### Distributor

| Option                         | Type    | Value/Example                                                       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ------------------------------ | ------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--healthcheck-interval`       | int     | `120`                                                               | How often, in seconds, will the health check run for all Nodes. This ensures the server can ping all the Nodes successfully.                                                                                                                                                                                                                                                                                                                        |
| `--distributor`                | uri     | `http://localhost:5553`                                             | Url of the distributor.                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `--distributor-host`           | string  | `localhost`                                                         | Host on which the distributor is listening.                                                                                                                                                                                                                                                                                                                                                                                                         |
| `--distributor-implementation` | string  | `org.openqa.selenium.grid.distributor.local.LocalDistributor`       | Full class name of non-default distributor implementation                                                                                                                                                                                                                                                                                                                                                                                           |
| `--distributor-port`           | int     | `5553`                                                              | Port on which the distributor is listening.                                                                                                                                                                                                                                                                                                                                                                                                         |
| `--reject-unsupported-caps`    | boolean | `false`                                                             | Allow the Distributor to reject a request immediately if the Grid does not support the requested capability. Rejecting requests immediately is suitable for a Grid setup that does not spin up Nodes on demand.                                                                                                                                                                                                                                     |
| `--slot-matcher`               | string  | `org.openqa.selenium.grid.data.DefaultSlotMatcher`                  | Full class name of non-default slot matcher to use. This is used to determine whether a Node can support a particular session.                                                                                                                                                                                                                                                                                                                      |
| `--slot-selector`              | string  | `org.openqa.selenium.grid.distributor.selector.DefaultSlotSelector` | Full class name of non-default slot selector. This is used to select a slot in a Node once the Node has been matched.                                                                                                                                                                                                                                                                                                                               |
| `--newsession-threadpool-size` | int     | `24`                                                                | The Distributor uses a fixed-sized thread pool to create new sessions as it consumes new session requests from the queue. This allows configuring the size of the thread pool. The default value is no. of available processors \* 3. Note: If the no. of threads is way greater than the available processors it will not always increase the performance. A high number of threads causes more context switching which is an expensive operation. |
| `--purge-nodes-interval`       | int     | `30`                                                                | How often, in seconds, will the Distributor purge Nodes that have been down for a while. This is calculated based on the heartbeat received from a particular node.                                                                                                                                                                                                                                                                                 |

### Docker

| Option                          | Type      | Value/Example                                                     | Description                                                                                                                                                                                                                                                                                 |
| ------------------------------- | --------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--docker-assets-path`          | string    | `/opt/selenium/assets`                                            | Absolute path where assets will be stored                                                                                                                                                                                                                                                   |
| `--docker` / `-D`               | string\[] | `selenium/standalone-firefox:latest '{"browserName": "firefox"}'` | Docker configs which map image name to stereotype capabilities (example: `-D selenium/standalone-firefox:latest '{"browserName": "firefox"}'`)                                                                                                                                              |
| `--docker-devices`              | string\[] | `/dev/kvm:/dev/kvm`                                               | Exposes devices to a container. Each device mapping declaration must have at least the path of the device in both host and container separated by a colon like in this example: /device/path/in/host:/device/path/in/container                                                              |
| `--docker-host`                 | string    | `localhost`                                                       | Host name where the Docker daemon is running                                                                                                                                                                                                                                                |
| `--docker-port`                 | int       | `2375`                                                            | Port where the Docker daemon is running                                                                                                                                                                                                                                                     |
| `--docker-url`                  | string    | `http://localhost:2375`                                           | URL for connecting to the Docker daemon                                                                                                                                                                                                                                                     |
| `--docker-video-image`          | string    | `selenium/video:latest`                                           | Docker image to be used when video recording is enabled                                                                                                                                                                                                                                     |
| `--docker-host-config-keys`     | string\[] | `Dns DnsOptions DnsSearch ExtraHosts Binds`                       | Specify which docker host configuration keys should be passed to browser containers. Keys name can be found in the Docker API [documentation](https://docs.docker.com/engine/api/v1.41/#tag/Container/operation/ContainerCreate), or by running `docker inspect` the node-docker container. |
| `--docker-api-version`          | string    | `1.40`                                                            | Docker API version to use. Pin a specific API version instead of relying on auto-detection by the implementation.                                                                                                                                                                           |
| `--docker-server-start-timeout` | int       | `55`                                                              | Max time (in seconds) to wait for the browser server to successfully start up inside the container, before cancelling the process.                                                                                                                                                          |
| `--docker-grouping-labels`      | string\[] | `azure.container.group aws.ecs.cluster`                           | Custom labels used for grouping dynamic containers. Makes the system more flexible for different platforms and use cases.                                                                                                                                                                   |

### Kubernetes

| Option                                  | Type      | Value/Example                                                     | Description                                                                                                                                                                                                                                                                    |
| --------------------------------------- | --------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--kubernetes-url`                      | string    | `"https://my-k8s-cluster:6443"`                                   | Kubernetes API server URL. When set, connects to a remote cluster instead of using in-cluster or kubeconfig auto-discovery.                                                                                                                                                    |
| `--kubernetes-configs` / `-K`           | string\[] | `selenium/standalone-firefox:latest '{"browserName": "firefox"}'` | Kubernetes configs which map image name to stereotype capabilities (example: `-K selenium/standalone-firefox:latest '{"browserName": "firefox"}'`). Use `configmap:[namespace/]<name>` as the key to load a Job template from a Kubernetes ConfigMap instead of an image name. |
| `--kubernetes-namespace`                | string    | `"selenium"`                                                      | Kubernetes namespace to create browser Jobs in. Auto-detected from the client when running in-cluster if not set.                                                                                                                                                              |
| `--kubernetes-service-account`          | string    | `"selenium-session"`                                              | Override service account for browser Jobs. Auto-inherited from the Node Pod when running in K8s.                                                                                                                                                                               |
| `--kubernetes-image-pull-policy`        | string    | `"IfNotPresent"`                                                  | Override image pull policy for browser containers (`Always`, `IfNotPresent`, `Never`). Auto-inherited from the Node Pod when running in K8s.                                                                                                                                   |
| `--kubernetes-server-start-timeout`     | int       | `120`                                                             | Max time (in seconds) to wait for the browser server to start up in the K8s Pod.                                                                                                                                                                                               |
| `--kubernetes-termination-grace-period` | int       | `30`                                                              | Seconds to wait for containers to shut down gracefully before force-killing them.                                                                                                                                                                                              |
| `--kubernetes-resource-requests`        | string    | `"cpu=500m,memory=512Mi"`                                         | Override resource requests for browser containers (comma-separated `key=value` pairs). Auto-inherited from the Node Pod when running in K8s.                                                                                                                                   |
| `--kubernetes-resource-limits`          | string    | `"cpu=1,memory=1Gi"`                                              | Override resource limits for browser containers (comma-separated `key=value` pairs). Auto-inherited from the Node Pod when running in K8s.                                                                                                                                     |
| `--kubernetes-node-selector`            | string    | `"disktype=ssd,region=us-west"`                                   | Override node selector for scheduling browser Pods (comma-separated `key=value` pairs). Auto-inherited from the Node Pod when running in K8s.                                                                                                                                  |
| `--kubernetes-video-image`              | string    | `"selenium/video:latest"`                                         | Container image to use as a video recording sidecar. Set to `false` to disable video recording (default).                                                                                                                                                                      |
| `--kubernetes-assets-path`              | string    | `"/opt/selenium/assets"`                                          | Absolute path where session assets will be stored.                                                                                                                                                                                                                             |
| `--kubernetes-label-inherit-prefix`     | string    | `"se/"`                                                           | Prefix filter for inheriting labels/annotations from the Node Pod to browser Jobs. Only labels/annotations whose keys start with this prefix are inherited. An empty string inherits all.                                                                                      |

### Events

| Option                        | Type    | Value/Example                                      | Description                                                                                                                                                                                                                                                                         |
| ----------------------------- | ------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--bind-bus`                  | boolean | `false`                                            | Whether the connection string should be bound or connected. When true, the component will be bound to the Event Bus (as in the Event Bus will also be started by the component, typically by the Distributor and the Hub). When false, the component will connect to the Event Bus. |
| `--events-implementation`     | string  | `org.openqa.selenium.events.zeromq.ZeroMqEventBus` | Full class name of non-default event bus implementation                                                                                                                                                                                                                             |
| `--publish-events`            | string  | `tcp://*:4442`                                     | Connection string for publishing events to the event bus                                                                                                                                                                                                                            |
| `--subscribe-events`          | string  | `tcp://*:4443`                                     | Connection string for subscribing to events from the event bus                                                                                                                                                                                                                      |
| `--eventbus-heartbeat-period` | int     | `30`                                               | How often, in seconds, will the EventBus socket send heartbeats.                                                                                                                                                                                                                    |

### Logging

| Option                   | Type    | Value/Example                                                                                                                                              | Description                                                                                                                                                            |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--http-logs`            | boolean | `false`                                                                                                                                                    | Enable http logging. Tracing should be enabled to log http logs.                                                                                                       |
| `--log-encoding`         | string  | `UTF-8`                                                                                                                                                    | Log encoding                                                                                                                                                           |
| `--log`                  | string  | Windows path example : `'\path\to\file\gridlog.log'` or `'C:\path\path\to\file\gridlog.log'` Linux/Unix/MacOS path example : `'/path/to/file/gridlog.log'` | File to write out logs. Ensure the file path is compatible with the operating system’s file path.                                                                      |
| `--log-level`            | string  | `“INFO”`                                                                                                                                                   | Log level. Default logging level is INFO. Log levels are described here <https://docs.oracle.com/en/java/javase/11/docs/api/java.logging/java/util/logging/Level.html> |
| `--plain-logs`           | boolean | `true`                                                                                                                                                     | Use plain log lines                                                                                                                                                    |
| `--structured-logs`      | boolean | `false`                                                                                                                                                    | Use structured logs                                                                                                                                                    |
| `--tracing`              | boolean | `true`                                                                                                                                                     | Enable trace collection                                                                                                                                                |
| `--log-timestamp-format` | string  | `HH:mm:ss.SSS`                                                                                                                                             | Allows the configure log timestamp format                                                                                                                              |

### Network

| Option           | Type    | Value/Example | Description                                                                                                          |
| ---------------- | ------- | ------------- | -------------------------------------------------------------------------------------------------------------------- |
| `--relax-checks` | boolean | `false`       | Relax checks on origin header and content type of incoming requests, in contravention of strict W3C spec compliance. |

### Node

| Option                           | Type      | Value/Example                                                                                                                                                                                                                                                              | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| -------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--detect-drivers`               | boolean   | `true`                                                                                                                                                                                                                                                                     | Autodetect which drivers are available on the current system, and add them to the Node.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `--driver-configuration`         | string\[] | `display-name="Firefox Nightly" max-sessions=2 webdriver-path="/usr/local/bin/geckodriver" stereotype="{\"browserName\": \"firefox\", \"browserVersion\": \"86\", \"moz:firefoxOptions\": {\"binary\":\"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"` | List of configured drivers a Node supports. It is recommended to provide this type of configuration through a toml config file to improve readability                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `--driver-factory`               | string\[] | `org.openqa.selenium.example.LynxDriverFactory '{"browserName": "lynx"}'`                                                                                                                                                                                                  | Mapping of fully qualified class name to a browser configuration that this matches against.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `--driver-implementation`        | string\[] | `"firefox"`                                                                                                                                                                                                                                                                | Drivers that should be checked. If specified, will skip autoconfiguration.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `--node-implementation`          | string    | `"org.openqa.selenium.grid.node.local.LocalNodeFactory"`                                                                                                                                                                                                                   | Full classname of non-default Node implementation. This is used to manage a session’s lifecycle.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `--grid-url`                     | string    | `https://grid.example.com`                                                                                                                                                                                                                                                 | Public URL of the Grid as a whole (typically the address of the Hub or the Router)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `--heartbeat-period`             | int       | `60`                                                                                                                                                                                                                                                                       | How often, in seconds, will the Node send heartbeat events to the Distributor to inform it that the Node is up.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `--max-sessions`                 | int       | `8`                                                                                                                                                                                                                                                                        | Maximum number of concurrent sessions. Default value is the number of available processors.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `--override-max-sessions`        | boolean   | `false`                                                                                                                                                                                                                                                                    | The # of available processors is the recommended max sessions value (1 browser session per processor). Setting this flag to true allows the recommended max value to be overwritten. Session stability and reliability might suffer as the host could run out of resources.                                                                                                                                                                                                                                                                                                                             |
| `--register-cycle`               | int       | `10`                                                                                                                                                                                                                                                                       | How often, in seconds, the Node will try to register itself for the first time to the Distributor.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `--register-period`              | int       | `120`                                                                                                                                                                                                                                                                      | How long, in seconds, will the Node try to register to the Distributor for the first time. After this period is completed, the Node will not attempt to register again.                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `--session-timeout`              | int       | `300`                                                                                                                                                                                                                                                                      | Let X be the session-timeout in seconds. The Node will automatically kill a session that has not had any activity in the last X seconds. This will release the slot for other tests.                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `--vnc-env-var`                  | string\[] | `SE_START_XVFB SE_START_VNC SE_START_NO_VNC`                                                                                                                                                                                                                               | Environment variable to check in order to determine if a vnc stream is available or not.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `--no-vnc-port`                  | int       | `7900`                                                                                                                                                                                                                                                                     | If VNC is available, sets the port where the local noVNC stream can be obtained                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `--drain-after-session-count`    | int       | `1`                                                                                                                                                                                                                                                                        | Drain and shutdown the Node after X sessions have been executed. Useful for environments like Kubernetes. A value higher than zero enables this feature.                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `--hub`                          | string    | `http://localhost:4444`                                                                                                                                                                                                                                                    | The address of the Hub in a Hub-and-Node configuration. Can be a hostname or IP address (`hostname`), in which case the Hub will be assumed to be `http://hostname:4444`, the `--grid-url` will be the same `--publish-events` will be `tcp://hostname:4442` and `--subscribe-events` will be `tcp://hostname:4443`. If `hostname` contains a port number, that will be used for `--grid-url` but the URIs for the event bus will remain the same. Any of these default values may be overridden but setting the correct flags. If the hostname has a protocol (such as `https`) that will be used too. |
| `--enable-cdp`                   | boolean   | `true`                                                                                                                                                                                                                                                                     | Enable CDP proxying in Grid. A Grid admin can disable CDP if the network does not allow websockets. True by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `--enable-bidi`                  | boolean   | `true`                                                                                                                                                                                                                                                                     | Enable BiDi proxying in Grid. A Grid admin can disable BiDi if the network does not allow websockets. True by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `--enable-managed-downloads`     | boolean   | `false`                                                                                                                                                                                                                                                                    | This causes the Node to auto manage files downloaded for a given session on the Node.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `--selenium-manager`             | boolean   | `false`                                                                                                                                                                                                                                                                    | When drivers are not available on the current system, use Selenium Manager. False by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `--connection-limit-per-session` | int       | `10`                                                                                                                                                                                                                                                                       | Let X be the maximum number of websocket connections per session. This will ensure one session is not able to exhaust the connection limit of the host.                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `--delete-session-on-ui`         | boolean   | `false`                                                                                                                                                                                                                                                                    | Enable capability to support deleting a session via the Grid UI. False by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `--register-shutdown-on-failure` | boolean   | `false`                                                                                                                                                                                                                                                                    | If enabled, the Node will shut down after the register period is completed without a successful registration. Useful in container environments to trigger a restart.                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `--node-down-failure-threshold`  | int       | `3`                                                                                                                                                                                                                                                                        | Maximum number of consecutive session creation failures before the Node is marked as DOWN. A value of `0` (default) disables this feature and allows unlimited retries.                                                                                                                                                                                                                                                                                                                                                                                                                                 |

### Relay

| Option                       | Type      | Value/Example                                                                                                     | Description                                                                                                                                                              |
| ---------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--service-url`              | string    | `http://localhost:4723`                                                                                           | URL for connecting to the service that supports WebDriver commands like an Appium server or a cloud service.                                                             |
| `--service-host`             | string    | `localhost`                                                                                                       | Host name where the service that supports WebDriver commands is running                                                                                                  |
| `--service-port`             | int       | `4723`                                                                                                            | Port where the service that supports WebDriver commands is running                                                                                                       |
| `--service-status-endpoint`  | string    | `/status`                                                                                                         | Optional, endpoint to query the WebDriver service status, an HTTP 200 response is expected                                                                               |
| `--service-protocol-version` | string    | `HTTP/1.1`                                                                                                        | Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status                                                          |
| `--service-configuration`    | string\[] | `max-sessions=2 stereotype='{"browserName": "safari", "platformName": "iOS", "appium:platformVersion": "14.5"}}'` | Configuration for the service where calls will be relayed to. It is recommended to provide this type of configuration through a toml config file to improve readability. |

### Router

| Option         | Type    | Value/Example              | Description                                                                                                         |
| -------------- | ------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `--password`   | string  | `myStrongPassword`         | Password clients must use to connect to the server. Both this and the username need to be set in order to be used.  |
| `--username`   | string  | `admin`                    | User name clients must use to connect to the server. Both this and the password need to be set in order to be used. |
| `--sub-path`   | string  | `my_company/selenium_grid` | A sub-path that should be considered for all user facing routes on the Hub/Router/Standalone.                       |
| `--disable-ui` | boolean | `true`                     | Disable the Grid UI.                                                                                                |

### Server

| Option                  | Type    | Value/Example           | Description                                                                                                                                                                                                                                                                           |
| ----------------------- | ------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--external-url`        | string  | `http://10.0.1.1:33333` | External URL where component is generally available. Useful on complex network topologies when components are on different networks and proxy servers are involved.                                                                                                                   |
| `--allow-cors`          | boolean | `true`                  | Whether the Selenium server should allow web browser connections from any host                                                                                                                                                                                                        |
| `--host`                | string  | `localhost`             | Server IP or hostname: usually determined automatically.                                                                                                                                                                                                                              |
| `--bind-host`           | boolean | `true`                  | Whether the server should bind to the host address/name, or only use it to" report its reachable url. Helpful in complex network topologies where the server cannot report itself with the current IP/hostname but rather an external IP or hostname (e.g. inside a Docker container) |
| `--https-certificate`   | path    | `/path/to/cert.pem`     | Server certificate for https. Get more detailed information by running “java -jar selenium-server.jar info security”                                                                                                                                                                  |
| `--https-private-key`   | path    | `/path/to/key.pkcs8`    | Private key for https. Get more detailed information by running “java -jar selenium-server.jar info security”                                                                                                                                                                         |
| `--max-threads`         | int     | `24`                    | Maximum number of listener threads. Default value is: (available processors) \* 3.                                                                                                                                                                                                    |
| `--port`                | int     | `4444`                  | Port to listen on. There is no default as this parameter is used by different components, for example, Router/Hub/Standalone will use 4444 and Node will use 5555.                                                                                                                    |
| `--registration-secret` | string  | `"Hunter2"`             | Shared secret used to authenticate Node registration requests. Must match the value set on the Hub/Distributor.                                                                                                                                                                       |

### SessionQueue

| Option                             | Type   | Value/Example           | Description                                                                                                                                                                            |
| ---------------------------------- | ------ | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--sessionqueue` / `--sq`          | uri    | `http://localhost:1237` | Address of the session queue server.                                                                                                                                                   |
| `--sessionqueue-host`              | string | `localhost`             | Host on which the session queue server is listening.                                                                                                                                   |
| `--sessionqueue-port`              | int    | `1234`                  | Port on which the session queue server is listening.                                                                                                                                   |
| `--session-request-timeout`        | int    | `300`                   | Timeout in seconds. A new incoming session request is added to the queue. Requests sitting in the queue for longer than the configured time will timeout.                              |
| `--session-request-timeout-period` | int    | `10`                    | How often, in seconds, the timeout for queued new session requests is checked.                                                                                                         |
| `--session-retry-interval`         | int    | `15`                    | Retry interval in milliseconds. If all slots are busy, new session request will be retried after the given interval.                                                                   |
| `--sessionqueue-batch-size`        | int    | `20`                    | Maximum number of session requests that can be consumed from the queue at a time, based on the available slots.                                                                        |
| `--maximum-response-delay`         | int    | `8`                     | How often, in seconds, will the SessionQueue respond in case there is no data, to reduce the http requests while polling for new session requests. (Config file only; not a CLI flag.) |

### Sessions

| Option            | Type   | Value/Example           | Description                                        |
| ----------------- | ------ | ----------------------- | -------------------------------------------------- |
| `--sessions`      | uri    | `http://localhost:1234` | Address of the session map server.                 |
| `--sessions-host` | string | `localhost`             | Host on which the session map server is listening. |
| `--sessions-port` | int    | `1234`                  | Port on which the session map server is listening. |

## Configuration examples

All the options mentioned above can be used when starting the Grid components. They are a good way of exploring the Grid options, and trying out values to find a suitable configuration.

We recommend the use of [Toml files](https://www.selenium.dev/documentation/grid/configuration/toml_options/) to configure a Grid. Configuration files improve readability, and you can also check them in source control.

When needed, you can combine a Toml file configuration with CLI arguments.

### Command-line flags

To pass config options as command-line flags, identify the valid options for the component and follow the template below.

```
java -jar selenium-server-<version>.jar <component> --<option> value
```

#### Standalone, setting max sessions and main port

```
java -jar selenium-server-<version>.jar standalone --max-sessions 4 --port 4444
```

#### Hub, setting a new session request timeout, a main port, and disabling tracing

```
java -jar selenium-server-<version>.jar hub --session-request-timeout 500 --port 3333 --tracing false
```

#### Node, with 4 max sessions, with debug(fine) log, 7777 as port, and only with Firefox and Edge

```
java -jar selenium-server-<version>.jar node --max-sessions 4 --log-level "fine" --port 7777 --driver-implementation "firefox" --driver-implementation "edge"
```

#### Distributor, setting Session Map server url, Session Queue server url, and disabling bus

```
java -jar selenium-server-<version>.jar distributor --sessions http://localhost:5556 --sessionqueue http://localhost:5559 --bind-bus false
```

#### Setting custom capabilities for matching specific Nodes

**Important:** Custom capabilities need to be set in the configuration in all Nodes. They also need to be included always in every session request.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node A with custom cap set to `true`

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":true}' --port 6161
```

##### Start the Node B with custom cap set to `false`

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":false}' --port 6262
```

##### Matching Node A

```java
ChromeOptions options = new ChromeOptions();
options.setCapability("gsg:customcap", true);
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

Set the custom capability to `false` in order to match the Node B.

#### Enabling Managed downloads by the Node

At times a test may need to access files that were downloaded by it on the Node. To retrieve such files, following can be done.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node with manage downloads enabled

```
java -jar selenium-server-<version>.jar node --enable-managed-downloads true
```

##### Set the capability at the test level

Tests that want to use this feature should set the capability `"se:downloadsEnabled"`to `true`

```java
options.setCapability("se:downloadsEnabled", true);
```

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

In the response the list of file names appear under the key `names`.

##### Dowloading a file:

* The endpoint to `POST` from is `/session/<sessionId>/se/files` with a payload of the form `{"name": "fileNameGoesHere}`
* The session needs to be active in order for the command to work.
* The raw response looks like below:

```json
{
	"value": {
		"filename": "Red-blue-green-channel.jpg",
		"contents": "Base64EncodedStringContentsOfDownloadedFileAsZipGoesHere"
	}
}
```

* The response blob contains two keys,

  * `filename` - The file name that was downloaded.
  * `contents` - Base64 encoded zipped contents of the file.

* The file contents are Base64 encoded and they need to be unzipped.

##### List files that can be downloaded

The below mentioned `curl` example can be used to list all the files that were downloaded by the current session in the Node, and which can be retrieved locally.

```bash
curl -X GET "http://localhost:4444/session/90c0149a-2e75-424d-857a-e78734943d4c/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

##### Retrieve a downloaded file

Assuming the downloaded file is named `Red-blue-green-channel.jpg`, and using `curl`, the file could be downloaded with the following command:

```bash
curl -H "Accept: application/json" \
-H "Content-Type: application/json; charset=utf-8" \
-X POST -d '{"name":"Red-blue-green-channel.jpg"}' \
"http://localhost:4444/session/18033434-fa4f-4d11-a7df-9e6d75920e19/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "UEsDBBQACAgIAJpagVYAAAAAAAAAAAAAAAAaAAAAUmVkLWJsAAAAAAAAAAAAUmVkLWJsdWUtZ3JlZW4tY2hhbm5lbC5qcGdQSwUGAAAAAAEAAQBIAAAAcNkAAAAA"
  }
}
```

##### Complete sample code in Java

Below is an example in Java that does the following:

* Sets the capability to indicate that the test requires automatic managing of downloaded files.
* Triggers a file download via a browser.
* Lists the files that are available for retrieval from the remote node (These are essentially files that were downloaded in the current session)
* Picks one file and downloads the file from the remote node to the local machine.

```java
import com.google.common.collect.ImmutableMap;

import org.openqa.selenium.By;
import org.openqa.selenium.io.Zip;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.io.File;
import java.net.URL;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import static org.openqa.selenium.remote.http.Contents.asJson;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.HttpMethod.GET;
import static org.openqa.selenium.remote.http.HttpMethod.POST;

public class DownloadsSample {

  public static void main(String[] args) throws Exception {
    // Assuming the Grid is running locally.
    URL gridUrl = new URL("http://localhost:4444");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("se:downloadsEnabled", true);
    RemoteWebDriver driver = new RemoteWebDriver(gridUrl, options);
    try {
      demoFileDownloads(driver, gridUrl);
    } finally {
      driver.quit();
    }
  }

	private static void demoFileDownloads(RemoteWebDriver driver, URL gridUrl) throws Exception {
		driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
		// Download the two available files on the page
		driver.findElement(By.id("file-1")).click();
		driver.findElement(By.id("file-2")).click();

		// The download happens in a remote Node, which makes it difficult to know when the file
		// has been completely downloaded. For demonstration purposes, this example uses a
		// 10-second sleep which should be enough time for a file to be downloaded.
		// We strongly recommend to avoid hardcoded sleeps, and ideally, to modify your
		// application under test, so it offers a way to know when the file has been completely
		// downloaded.
		TimeUnit.SECONDS.sleep(10);

		//This is the endpoint which will provide us with list of files to download and also to
		//let us download a specific file.
		String downloadsEndpoint = String.format("/session/%s/se/files", driver.getSessionId());

		String fileToDownload;

		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To list all files that are were downloaded on the remote node for the current session
			// we trigger GET request.
			HttpRequest request = new HttpRequest(GET, downloadsEndpoint);
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			@SuppressWarnings("unchecked")
			List<String> names = (List<String>) value.get("names");
			// Let's say there were "n" files downloaded for the current session, we would like
			// to retrieve ONLY the first file.
			fileToDownload = names.get(0);
		}

		// Now, let's download the file
		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To retrieve a specific file from one or more files that were downloaded by the current session
			// on a remote node, we use a POST request.
			HttpRequest request = new HttpRequest(POST, downloadsEndpoint);
			request.setContent(asJson(ImmutableMap.of("name", fileToDownload)));
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			// The returned map would contain 2 keys,
			// filename - This represents the name of the file (same as what was provided by the test)
			// contents - Base64 encoded String which contains the zipped file.
			String zippedContents = value.get("contents").toString();
			// The file contents would always be a zip file and has to be unzipped.
			File downloadDir = Zip.unzipToTempDir(zippedContents, "download", "");
			// Read the file contents
			File downloadedFile = Optional.ofNullable(downloadDir.listFiles()).orElse(new File[]{})[0];
			String fileContent = String.join("", Files.readAllLines(downloadedFile.toPath()));
			System.out.println("The file which was "
					+ "downloaded in the node is now available in the directory: "
					+ downloadDir.getAbsolutePath() + " and has the contents: " + fileContent);
		}
	}


}
```

# 3 - TOML configuration options

```toml
[section1]
option1="value"

[section2]
option2=["value1","value2"]
option3=true
```

Below are some examples of Grid components configured with a Toml file, the component can be started in the following way:

```
java -jar selenium-server-<version>.jar <component> --config /path/to/file/<file-name>.toml
```

### Standalone

A Standalone server, running on port 4449, and a new session request timeout of 500 seconds.

```toml
[server]
port = 4449

[sessionqueue]
session-request-timeout = 500
```

### Specific browsers and a limit of max sessions

A Standalone server or a Node which only has Firefox and Chrome enabled by default.

```toml
[node]
drivers = ["chrome", "firefox"]
max-sessions = 3
```

### Configuring and customising drivers

Standalone or Node server with customised drivers, which allows things like having Firefox Beta or Nightly, and having different browser versions.

```toml
[node]
detect-drivers = false
[[node.driver-configuration]]
max-sessions = 100
display-name = "Firefox Nightly"
stereotype = "{\"browserName\": \"firefox\", \"browserVersion\": \"93\", \"platformName\": \"MAC\", \"moz:firefoxOptions\": {\"binary\": \"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"
[[node.driver-configuration]]
display-name = "Chrome Beta"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"94\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta\"}}"
[[node.driver-configuration]]
display-name = "Chrome Dev"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"95\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev\"}}"
webdriver-executable = '/path/to/chromedriver/95/chromedriver'
```

### Standalone or Node with Docker

A Standalone or Node server that is able to run each new session in a Docker container. Disabling drivers detection, having maximum 2 concurrent sessions. Stereotypes configured need to be mapped to a Docker image, and the Docker daemon needs to be exposed via http/tcp. In addition, it is possible to define which device files, accessible on the host, will be available in containers through the `devices` property. Refer to the [docker](https://docs.docker.com/engine/reference/commandline/run/#add-host-device-to-container---device) documentation for more information about how docker device mapping works.

```toml
[node]
detect-drivers = false
max-sessions = 2

[docker]
configs = [
    "selenium/standalone-chrome:93.0", "{\"browserName\": \"chrome\", \"browserVersion\": \"91\"}", 
    "selenium/standalone-firefox:92.0", "{\"browserName\": \"firefox\", \"browserVersion\": \"92\"}"
]
#Optionally define all device files that should be mapped to docker containers
#devices = [
#    "/dev/kvm:/dev/kvm"
#]
url = "http://localhost:2375"
video-image = "selenium/video:latest"
```

### Relaying commands to a service endpoint that supports WebDriver

It is useful to connect an external service that supports WebDriver to Selenium Grid. An example of such service could be a cloud provider or an Appium server. In this way, Grid can enable more coverage to platforms and versions not present locally.

The following is an en example of connecting an Appium server to Grid.

```toml
[node]
detect-drivers = false

[relay]
# Default Appium/Cloud server endpoint
url = "http://localhost:4723/wd/hub"
status-endpoint = "/status"
# Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status (e.g. HTTP/1.1, HTTP/2)
protocol-version = "HTTP/1.1"
# Stereotypes supported by the service. The initial number is "max-sessions", and will allocate 
# that many test slots to that particular configuration
configs = [
  "5", "{\"browserName\": \"chrome\", \"platformName\": \"android\", \"appium:platformVersion\": \"11\"}"
]
```

### Basic auth enabled

It is possible to protect a Grid with basic auth by configuring the Router/Hub/Standalone with a username and password. This user/password combination will be needed when loading the Grid UI or starting a new session.

```toml
[router]
username = "admin"
password = "myStrongPassword"
```

Here is a Java example showing how to start a session using the configured user and password.

```java
ClientConfig clientConfig = ClientConfig.defaultConfig()
  .baseUrl(new URL("http://localhost:4444"))
  .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"));
HttpCommandExecutor executor = new HttpCommandExecutor(clientConfig);
RemoteWebDriver driver = new RemoteWebDriver(executor, new ChromeOptions());
```

In other languages, you can use the URL http\://admin:myStrongPassword\@localhost:4444

### Setting custom capabilities for matching specific Nodes

**Important:** Custom capabilities need to be set in the configuration in all Nodes. They also need to be included always in every session request.

```toml
[node]
detect-drivers = false

[[node.driver-configuration]]
display-name = "firefox"
stereotype = '{"browserName": "firefox", "platformName": "macOS", "browserVersion":"96", "networkname:applicationName":"node_1", "nodename:applicationName":"app_1" }'
max-sessions = 5
```

Here is a Java example showing how to match that Node

```java
FirefoxOptions options = new FirefoxOptions();
options.setCapability("networkname:applicationName", "node_1");
options.setCapability("nodename:applicationName", "app_1");
options.setBrowserVersion("96");
options.setPlatformName("macOS");
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

### Enabling Managed downloads by the Node.

The Node can be instructed to manage downloads automatically. This will cause the Node to save all files that were downloaded for a particular session into a temp directory, which can later be retrieved from the node. To turn this capability on, use the below configuration:

```toml
[node]
enable-managed-downloads = true
```

Refer to the [CLI section](https://www.selenium.dev/documentation/grid/configuration/cli_options/#enabling-managed-downloads-by-the-node) for a complete example.

----
url: https://www.selenium.dev/zh-cn/_print/documentation/legacy/selenium_ide/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/legacy/selenium_ide/).

# Legacy Selenium IDE

* 1: [HTML runner](#pg-79b55613fab8efd3102a974a15d92b90)

```html
<tr>
    <td>Command</td>
    <td>target (locator)</td>
    <td>Value</td>
</tr>
```

|            |              |       |
| ---------- | ------------ | ----- |
| verifyText | //div//a\[2] | Login |

The parameters are not always required; it depends on the command. In some cases both are required, in others one parameter is required, and in still others the command may take no parameters at all. Here are a couple more examples:

|                   |             |                         |
| ----------------- | ----------- | ----------------------- |
| goBackAndWait     |             |                         |
| verifyTextPresent |             | Welcome to My Home Page |
| type              | id=phone    | (555) 666-7066          |
| type              | id=address1 | ${myVariableAddress}    |

```html
<table>
    <tr><td>open</td><td>/download/</td><td></td></tr>
    <tr><td>assertTitle</td><td></td><td>Downloads</td></tr>
    <tr><td>verifyText</td><td>//h2</td><td>Downloads</td></tr>
</table>
```

Rendered as a table in a browser this would look like the following:

|             |            |           |
| ----------- | ---------- | --------- |
| open        | /download/ |           |
| assertTitle |            | Downloads |
| verifyText  | //h2       | Downloads |

The Selenese HTML syntax can be used to write and run tests without requiring knowledge of a programming language. With a basic knowledge of selenese and Selenium-IDE you can quickly produce and run testcases.

## Test Suites

A test suite is a collection of tests. Often one will run all the tests in a test suite as one continuous batch-job.

When using Selenium-IDE, test suites also can be defined using a simple HTML file. The syntax again is simple. An HTML table defines a list of tests where each row defines the filesystem path to each test. An example tells it all.

```html
<html>
<head>
<title>Test Suite Function Tests - Priority 1</title>
</head>
<body>
<table>
  <tr><td><b>Suite Of Tests</b></td></tr>
  <tr><td><a href="./Login.html">Login</a></td></tr>
  <tr><td><a href="./SearchValues.html">Test Searching for Values</a></td></tr>
  <tr><td><a href="./SaveValues.html">Test Save</a></td></tr>
</table>
</body>
</html>
```

| Command     | Target     | Value        |
| ----------- | ---------- | ------------ |
| open        | /download/ |              |
| assertTitle |            | Downloads    |
| verifyText  | //h2       | Downloads    |
| assertTable | 1.2.1      | Selenium IDE |
| verifyTable | 1.2.2      | June 3, 2008 |
| verifyTable | 1.2.3      | 1.0 beta 2   |

The above example first opens a page and then “asserts” that the correct page is loaded by comparing the title with the expected value. Only if this passes will the following command run and “verify” that the text is present in the expected location. The test case then “asserts” the first column in the second row of the first table contains the expected value, and only if this passed will the remaining cells in that row be “verified”.

### **verifyTextPresent**

The command `verifyTextPresent` is used to verify specific text exists somewhere on the page. It takes a single argument–the text pattern to be verified. For example:

| Command           | Target             | Value |
| ----------------- | ------------------ | ----- |
| verifyTextPresent | Marketing Analysis |       |

This would cause Selenium to search for, and verify, that the text string “Marketing Analysis” appears somewhere on the page currently being tested. Use verifyTextPresent when you are interested in only the text itself being present on the page. Do not use this when you also need to test where the text occurs on the page.

### **verifyElementPresent**

Use this command when you must test for the presence of a specific UI element, rather than its content. This verification does not check the text, only the HTML tag. One common use is to check for the presence of an image.

| Command              | Target      | Value |
| -------------------- | ----------- | ----- |
| verifyElementPresent | //div/p/img |       |

This command verifies that an image, specified by the existence of an HTML tag, is present on the page, and that it follows a

tag and a

tag. The first (and only) parameter is a locator for telling the Selenese command how to find the element. Locators are explained in the next section.

`verifyElementPresent` can be used to check the existence of any HTML tag within the page. You can check the existence of links, paragraphs, divisions

, etc. Here are a few more examples.

| Command              | Target                        | Value |
| -------------------- | ----------------------------- | ----- |
| verifyElementPresent | //div/p                       |       |
| verifyElementPresent | //div/a                       |       |
| verifyElementPresent | id=Login                      |       |
| verifyElementPresent | link=Go to Marketing Research |       |
| verifyElementPresent | //a\[2]                       |       |
| verifyElementPresent | //head/title                  |       |

These examples illustrate the variety of ways a UI element may be tested. Again, locators are explained in the next section.

### **verifyText**

Use `verifyText` when both the text and its UI element must be tested. verifyText must use a locator. If you choose an *XPath* or *DOM* locator, you can verify that specific text appears at a specific location on the page relative to other UI components on the page.

| Command    | Target              | Value                                                               |
| ---------- | ------------------- | ------------------------------------------------------------------- |
| verifyText | //table/tr/td/div/p | This is my text and it occurs right after the div inside the table. |

## Locating Elements

For many Selenium commands, a target is required. This target identifies an element in the content of the web application, and consists of the location strategy followed by the location in the format `locatorType=location`. The locator type can be omitted in many cases. The various locator types are explained below with examples for each.

### Locating by Identifier

This is probably the most common method of locating elements and is the catch-all default when no recognized locator type is used. With this strategy, the first element with the id attribute value matching the location will be used. If no element has a matching id attribute, then the first element with a name attribute matching the location will be used.

For instance, your page source could have id and name attributes as follows:

```html
  <html>
   <body>
    <form id="loginForm">
     <input name="username" type="text" />
     <input name="password" type="password" />
     <input name="continue" type="submit" value="Login" />
    </form>
   </body>
  <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
    </body>
   <html>
```

* `id=loginForm` (3)

### Locating by Name

The name locator type will locate the first element with a matching name attribute. If multiple elements have the same value for a name attribute, then you can use filters to further refine your location strategy. The default filter type is value (matching the value attribute).

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
  <html>
   <body>
    <p>Are you sure you want to do this?</p>
    <a href="continue.html">Continue</a> 
    <a href="cancel.html">Cancel</a>
  </body>
  <html>
```

* `link=Continue` (4)
* `link=Cancel` (5)

### Locating by DOM

The Document Object Model represents an HTML document and can be accessed using JavaScript. This location strategy takes JavaScript that evaluates to an element on the page, which can be simply the element’s location using the hierarchical dotted notation.

Since only `dom` locators start with “document”, it is not necessary to include the `dom=` label when specifying a DOM locator.

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input class="required" name="username" type="text" />
      <input class="required passfield" name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | glob:\*Film\*Television\*             |       |

The actual title of the page reached by clicking on the link was “De Anza Film And Television Department - Menu”. By using a pattern rather than the exact text, the `verifyTitle` will pass as long as the two words “Film” and “Television” appear (in that order) anywhere in the page’s title. For example, if the page’s owner should shorten the title to just “Film & Television Department,” the test would still pass. Using a pattern for both a link and a simple test that the link worked (such as the `verifyTitle` above does) can greatly reduce the maintenance for such test cases.

#### Regular Expression Patterns

*Regular expression* patterns are the most powerful of the three types of patterns that Selenese supports. Regular expressions are also supported by most high-level programming languages, many text editors, and a host of tools, including the Linux/Unix command-line utilities **grep**, **sed**, and **awk**. In Selenese, regular expression patterns allow a user to perform many tasks that would be very difficult otherwise. For example, suppose your test needed to ensure that a particular table cell contained nothing but a number. `regexp: [0-9]+` is a simple pattern that will match a decimal number of any length.

Whereas Selenese globbing patterns support only the **\*** and **\[ ]** (character class) features, Selenese regular expression patterns offer the same wide array of special characters that exist in JavaScript. Below are a subset of those special characters:

| PATTERN | MATCH                                                                            |
| ------- | -------------------------------------------------------------------------------- |
| .       | any single character                                                             |
| \[ ]    | character class: any single character that appears inside the brackets           |
| \*      | quantifier: 0 or more of the preceding character (or group)                      |
| +       | quantifier: 1 or more of the preceding character (or group)                      |
| ?       | quantifier: 0 or 1 of the preceding character (or group)                         |
| {1,5}   | quantifier: 1 through 5 of the preceding character (or group)                    |
| \|      | alternation: the character/group on the left or the character/group on the right |
| ( )     | grouping: often used with alternation and/or quantifier                          |

Regular expression patterns in Selenese need to be prefixed with either `regexp:` or `regexpi:`. The former is case-sensitive; the latter is case-insensitive.

A few examples will help clarify how regular expression patterns can be used with Selenese commands. The first one uses what is probably the most commonly used regular expression pattern–**.\*** (“dot star”). This two-character sequence can be translated as “0 or more occurrences of any character” or more simply, “anything or nothing.” It is the equivalent of the one-character globbing pattern **\*** (a single asterisk).

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | regexp:.\*Film.\*Television.\*        |       |

The example above is functionally equivalent to the earlier example that used globbing patterns for this same test. The only differences are the prefix (**regexp:** instead of **glob:**) and the “anything or nothing” pattern (**.\*** instead of just **\***).

The more complex example below tests that the Yahoo! Weather page for Anchorage, Alaska contains info on the sunrise time:

| Command           | Target                                            | Value |
| ----------------- | ------------------------------------------------- | ----- |
| open              | <http://weather.yahoo.com/forecast/USAK0012.html> |       |
| verifyTextPresent | regexp:Sunrise: \*\[0-9]{1,2}:\[0-9]{2} \[ap]m    |       |

Let’s examine the regular expression above one part at a time:

|              |                                                      |
| ------------ | ---------------------------------------------------- |
| `Sunrise: *` | The string **Sunrise:** followed by 0 or more spaces |
| `[0-9]{1,2}` | 1 or 2 digits (for the hour of the day)              |
| `:`          | The character **:** (no special characters involved) |
| `[0-9]{2}`   | 2 digits (for the minutes) followed by a space       |
| `[ap]m`      | “a” or “p” followed by “m” (am or pm)                |

#### Exact Patterns

The **exact** type of Selenium pattern is of marginal usefulness. It uses no special characters at all. So, if you needed to look for an actual asterisk character (which is special for both globbing and regular expression patterns), the **exact** pattern would be one way to do that. For example, if you wanted to select an item labeled “Real \*” from a dropdown, the following code might work or it might not. The asterisk in the `glob:Real *` pattern will match anything or nothing. So, if there was an earlier select option labeled “Real Numbers,” it would be the option selected rather than the “Real \*” option.

| Command | Target   | Value        |
| ------- | -------- | ------------ |
| select  | //select | glob:Real \* |

In order to ensure that the “Real \*” item would be selected, the `exact:` prefix could be used to create an **exact** pattern as shown below:

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| select  | //select | exact:Real \* |

But the same effect could be achieved via escaping the asterisk in a regular expression pattern:

| Command | Target   | Value            |
| ------- | -------- | ---------------- |
| select  | //select | regexp:Real \\\* |

| Command | Target            | Value |
| ------- | ----------------- | ----- |
| store   | <paul@mysite.org> |       |

Later in your script, you’ll want to use the stored value of your variable. To access the value of a variable, enclose the variable in curly brackets ({}) and precede it with a dollar sign like this.

| Command    | Target  | Value         |
| ---------- | ------- | ------------- |
| verifyText | //div/p | \\${userName} |

A common use of variables is for storing input for an input field.

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| type    | id=login | \\${userName} |

| Command         | Target                                         | Value       |
| --------------- | ---------------------------------------------- | ----------- |
| store           | 10                                             | hits        |
| storeXpathCount | //blockquote                                   | blockquotes |
| storeEval       | storedVars\[‘hits’].storedVars\[‘blockquotes’] | paragraphs  |

This next example illustrates how a JavaScript snippet can include calls to methods, in this case the JavaScript String object’s `toUpperCase` method and `toLowerCase` method.

| Command   | Target                            | Value |
| --------- | --------------------------------- | ----- |
| store     | Edith Wharton                     | name  |
| storeEval | storedVars\[’name’].toUpperCase() | uc    |
| storeEval | storedVars\[’name’].toUpperCase() | lc    |

#### JavaScript Usage with Non-Script Parameters

JavaScript can also be used to help generate values for parameters, even when the parameter is not specified to be of type **script**.\
However, in this case, special syntax is required–the *entire* parameter value must be prefixed by `javascript{` with a trailing `}`, which encloses the JavaScript snippet, as in `javascript{*yourCodeHere*}`. Below is an example in which the `type` command’s second parameter `value` is generated via JavaScript code using this special syntax:

| Command | Target            | Value                                                 |
| ------- | ----------------- | ----------------------------------------------------- |
| store   | league of nations | searchString                                          |
| type    | q                 | javascript{storedVars\[‘searchString’].toUpperCase()} |

## *echo* - The Selenese Print Command

Selenese has a simple command that allows you to print text to your test’s output. This is useful for providing informational progress notes in your test which display on the console as your test is running. These notes also can be used to provide context within your test result reports, which can be useful for finding where a defect exists on a page in the event your test finds a problem. Finally, echo statements can be used to print the contents of Selenium variables.

| Command | Target                    | Value |
| ------- | ------------------------- | ----- |
| echo    | Testing page footer now.  |       |
| echo    | Username is \\${userName} |       |

## Alerts, Popups, and Multiple Windows

Suppose that you are testing a page that looks like this.

```html
  <!DOCTYPE HTML>
  <html>
  <head>
    <script type="text/javascript">
      function output(resultText){
        document.getElementById('output').childNodes[0].nodeValue=resultText;
      }

      function show_confirm(){
        var confirmation=confirm("Chose an option.");
        if (confirmation==true){
          output("Confirmed.");
        }
        else{
          output("Rejected!");
        }
      }
      
      function show_alert(){
        alert("I'm blocking!");
        output("Alert is gone.");
      }
      function show_prompt(){
        var response = prompt("What's the best web QA tool?","Selenium");
        output(response);
      }
      function open_window(windowName){
        window.open("newWindow.html",windowName);
      }
      </script>
  </head>
  <body>

    <input type="button" id="btnConfirm" onclick="show_confirm()" value="Show confirm box" />
    <input type="button" id="btnAlert" onclick="show_alert()" value="Show alert" />
    <input type="button" id="btnPrompt" onclick="show_prompt()" value="Show prompt" />
    <a href="newWindow.html" id="lnkNewWindow" target="_blank">New Window Link</a>
    <input type="button" id="btnNewNamelessWindow" onclick="open_window()" value="Open Nameless Window" />
    <input type="button" id="btnNewNamedWindow" onclick="open_window('Mike')" value="Open Named Window" />

    <br />
    <span id="output">
    </span>
  </body>
  </html>
```

The user must respond to alert/confirm boxes, as well as moving focus to newly opened popup windows. Fortunately, Selenium can cover JavaScript pop-ups.

But before we begin covering alerts/confirms/prompts in individual detail, it is helpful to understand the commonality between them. Alerts, confirmation boxes and prompts all have variations of the following

| Command                   | Description                                                           |
| ------------------------- | --------------------------------------------------------------------- |
| assertFoo(pattern)        | throws error if pattern doesn’t match the text of the pop-up          |
| assertFooPresent          | throws error if pop-up is not available                               |
| assertFooNotPresent       | throws error if any pop-up is present                                 |
| storeFoo(variable)        | stores the text of the pop-up in a variable                           |
| storeFooPresent(variable) | stores the text of the pop-up in a variable and returns true or false |

When running under Selenium, JavaScript pop-ups will not appear. This is because the function calls are actually being overridden at runtime by Selenium’s own JavaScript. However, just because you cannot see the pop-up doesn’t mean you don’t have to deal with it. To handle a pop-up, you must call its `assertFoo(pattern)` function. If you fail to assert the presence of a pop-up your next command will be blocked and you will get an error similar to the following `[error] Error: There was an unexpected Confirmation! [Chose an option.]`

### Alerts

Let’s start with alerts because they are the simplest pop-up to handle. To begin, open the HTML sample above in a browser and click on the “Show alert” button. You’ll notice that after you close the alert the text “Alert is gone.” is displayed on the page. Now run through the same steps with Selenium IDE recording, and verify the text is added after you close the alert. Your test will look something like this:

| Command           | Target         | Value |
| ----------------- | -------------- | ----- |
| open              | /              |       |
| click             | btnAlert       |       |
| assertAlert       | I’m blocking!  |       |
| verifyTextPresent | Alert is gone. |       |

You may be thinking “That’s odd, I never tried to assert that alert.” But this is Selenium-IDE handling and closing the alert for you. If you remove that step and replay the test you will get the following error `[error] Error: There was an unexpected Alert! [I'm blocking!]`. You must include an assertion of the alert to acknowledge its presence.

If you just want to assert that an alert is present but either don’t know or don’t care what text it contains, you can use `assertAlertPresent`. This will return true or false, with false halting the test.

### Confirmations

Confirmations behave in much the same way as alerts, with `assertConfirmation` and `assertConfirmationPresent` offering the same characteristics as their alert counterparts. However, by default Selenium will select OK when a confirmation pops up. Try recording clicking on the “Show confirm box” button in the sample page, but click on the “Cancel” button in the popup, then assert the output text. Your test may look something like this:

| Command                        | Target            | Value |
| ------------------------------ | ----------------- | ----- |
| open                           | /                 |       |
| click                          | btnConfirm        |       |
| chooseCancelOnNextConfirmation |                   |       |
| assertConfirmation             | Choose an option. |       |
| verifyTextPresent              | Rejected          |       |

The `chooseCancelOnNextConfirmation` function tells Selenium that all following confirmation should return false. It can be reset by calling chooseOkOnNextConfirmation.

You may notice that you cannot replay this test, because Selenium complains that there is an unhandled confirmation. This is because the order of events Selenium-IDE records causes the click and chooseCancelOnNextConfirmation to be put in the wrong order (it makes sense if you think about it, Selenium can’t know that you’re cancelling before you open a confirmation) Simply switch these two commands and your test will run fine.

### Prompts

Prompts behave in much the same way as alerts, with `assertPrompt` and `assertPromptPresent` offering the same characteristics as their alert counterparts. By default, Selenium will wait for you to input data when the prompt pops up. Try recording clicking on the “Show prompt” button in the sample page and enter “Selenium” into the prompt. Your test may look something like this:

| Command            | Target                       | Value |
| ------------------ | ---------------------------- | ----- |
| open               | /                            |       |
| answerOnNextPrompt | Selenium!                    |       |
| click              | id=btnPrompt                 |       |
| assertPrompt       | What’s the best web QA tool? |       |
| verifyTextPresent  | Selenium!                    |       |

```html
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Sample Selenium Test Suite</title>
    </head>
    <body>
        <table cellpadding="1" cellspacing="1" border="1">
            <thead>
                <tr><td>Test Cases for De Anza A-Z Directory Links</td></tr>
            </thead>
        <tbody>
            <tr><td><a href="./a.html">A Links</a></td></tr>
            <tr><td><a href="./b.html">B Links</a></td></tr>
            <tr><td><a href="./c.html">C Links</a></td></tr>
            <tr><td><a href="./d.html">D Links</a></td></tr>
        </tbody>
        </table>
    </body>
</html>
```

***

*error loading test case: no command found*

You’ve used **File=>Open** to try to open a test suite file. Use **File=>Open Test Suite** instead.

An enhancement request has been raised to improve this error message. See [issue 1010](http://code.google.com/p/selenium/issues/detail?id=1010).

***

This type of **error** may indicate a timing problem, i.e., the element specified by a locator in your command wasn’t fully loaded when the command was executed. Try putting a **pause 5000** before the command to determine whether the problem is indeed related to timing. If so, investigate using an appropriate **waitFor\*** or **\*AndWait** command before the failing command.

***

Whenever your attempt to use variable substitution fails as is the case for the **open** command above, it indicates that you haven’t actually created the variable whose value you’re trying to access. This is sometimes due to putting the variable in the **Value** field when it should be in the **Target** field or vice versa. In the example above, the two parameters for the **store** command have been erroneously placed in the reverse order of what is required. For any Selenese command, the first required parameter must go in the **Target** field, and the second required parameter (if one exists) must go in the **Value** field.

***

*error loading test case: \[Exception… “Component returned failure code: 0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND) \[nsIFileInputStream.init]” nresult: “0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND)” location: “JS frame :: chrome://selenium-ide/content/file-utils.js :: anonymous :: line 48” data: no]*

One of the test cases in your test suite cannot be found. Make sure that the test case is indeed located where the test suite indicates it is located. Also, make sure that your actual test case files have the .html extension both in their filenames, and in the test suite file where they are referenced.

An enhancement request has been raised to improve this error message. See [issue 1011](http://code.google.com/p/selenium/issues/detail?id=1011).

***

Your extension file’s contents have not been read by Selenium-IDE. Be sure you have specified the proper pathname to the extensions file via **Options=>Options=>General** in the **Selenium Core extensions** field. Also, Selenium-IDE must be restarted after any change to either an extensions file *or* to the contents of the **Selenium Core extensions** field.

# 1 - HTML runner

```shell
[user@localhost ~]$ cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

[user@localhost ~]$ rpm -qa | egrep -i "xvfb|java-1.8|firefox"
xorg-x11-server-Xvfb-1.19.3-11.el7.x86_64
firefox-52.4.0-1.el7.centos.x86_64
java-1.8.0-openjdk-1.8.0.151-1.b12.el7_4.x86_64
java-1.8.0-openjdk-headless-1.8.0.151-1.b12.el7_4.x86_64
```

Test Suite 示例：

```html
[user@localhost ~]$ cat testsuite.html
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
  <title>Test Suite</title>
</head>
<body>
<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium"><tbody>
<tr><td><b>Test Suite</b></td></tr>
<tr><td><a href="YOUR-TEST-SCENARIO.html">YOUR-TEST-SCENARIO</a></td></tr>
</tbody></table>
</body>
</html>
```

## 如何运行 selenium-html-runner headless

现在，最重要的部分，一个如何运行 selenium-html-runner 的例子！ 您的体验可能因软件组合而异 - geckodriver / FF / html-runner 版本。

```shell
xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
```

```shell
[user@localhost ~]$ xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "*firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
Multi-window mode is longer used as an option and will be ignored.
1510061109691   geckodriver     INFO    geckodriver 0.18.0
1510061109708   geckodriver     INFO    Listening on 127.0.0.1:2885
1510061110162   geckodriver::marionette INFO    Starting browser /usr/bin/firefox with args ["-marionette"]
1510061111084   Marionette      INFO    Listening on port 43229
1510061111187   Marionette      WARN    TLS certificate errors will be ignored for this session
Nov 07, 2017 1:25:12 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
2017-11-07 13:25:12.714:INFO::main: Logging initialized @3915ms to org.seleniumhq.jetty9.util.log.StdErrLog
2017-11-07 13:25:12.804:INFO:osjs.Server:main: jetty-9.4.z-SNAPSHOT
2017-11-07 13:25:12.822:INFO:osjsh.ContextHandler:main: Started o.s.j.s.h.ContextHandler@87a85e1{/tests,null,AVAILABLE}
2017-11-07 13:25:12.843:INFO:osjs.AbstractConnector:main: Started ServerConnector@52102734{HTTP/1.1,[http/1.1]}{0.0.0.0:31892}
2017-11-07 13:25:12.843:INFO:osjs.Server:main: Started @4045ms
Nov 07, 2017 1:25:13 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |open | /auth_mellon.php |  |
Nov 07, 2017 1:25:14 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |waitForPageToLoad | 3000 |  |
.
.
.etc

<td>result:</td>
<td>PASS</td>
```

----
url: https://www.selenium.dev/documentation/overview/details/
----

# A deeper look at Selenium

Last modified November 7, 2024: [Rephrase/reformat a few sentences (#1981) (77ae509e3ca)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/77ae509e3ca40109ca5e74fec1f4f05f69df75f7)

----
url: https://www.selenium.dev/pt-br/documentation/grid/getting_started/
----

# Configurando a sua

Instruções para criar uma Selenium Grid simples

## Início rápido

1. Pré-requisitos

   * Java 11 ou superior instalado

   * Navegador(es) instalados

   * Drivers do(s) navegador(es)

     * [Selenium Manager](https://www.selenium.dev/pt-br/documentation/selenium_manager/) will configure the drivers automatically if you add `--selenium-manager true`.
     * [Installed and on the `PATH`](https://www.selenium.dev/pt-br/documentation/webdriver/troubleshooting/errors/driver_location/#use-the-path-environment-variable)

```shell
java -jar selenium-server-<version>.jar standalone
```

```shell
java -jar selenium-server-<version>.jar hub
```

Por omissão, o servidor irá estar à escuta por pedidos de sessão `RemoteWebDriver` em <http://localhost:4444>.

#### Node

Ao iniciar, o **Node** irá detectar os drivers disponíveis através do [`PATH`](https://www.selenium.dev/pt-br/documentation/webdriver/troubleshooting/errors/driver_location/#3-a-variável-de-ambiente--path).

O comando exemplo seguinte assume que o **Node** está a executar na mesma máquina onde o **Hub** está em execução.

```shell
java -jar selenium-server-<version>.jar node
```

##### Mais do que um Node na mesma máquina

**Node** 1

```shell
java -jar selenium-server-<version>.jar node --port 5555
```

**Node** 2

```shell
java -jar selenium-server-<version>.jar node --port 6666
```

##### Node e Hub em máquinas diferentes

A comunicação entre **Hub** e **Nodes** ocorre via HTTP. Para iniciar o processo de registo, o **Node** envia uma mensagem para o **Hub** através do [**Event Bus**](https://www.selenium.dev/pt-br/documentation/grid/components/#event-bus) (o **Event Bus** reside dentro do **Hub**). Quando o **Hub** recebe a mensagem, tenta comunicar com o **Node** para confirmar a sua existencia.

Para que um **Node** se consiga registar no **Hub**, é importante que as portas do **Event Bus** sejam expostas na máquina **Hub**. As portas por omissão são 4442 e 4443 para o **Event Bus** e 4444 para o **Hub**.

Se o **Hub** estiver a usar as portas por omissão, pode usar a flag `--hub` para registar o **Node**

```shell
java -jar selenium-server-<version>.jar node --hub http://<hub-ip>:4444
```

Quando o **Hub** não estiver a usar as portas por omissão, necessita usar as flags`--publish-events` e `--subscribe-events`.

Por exemplo, se o **Hub** usar as portas`8886`, `8887`, e `8888`

```shell
java -jar selenium-server-<version>.jar hub --publish-events tcp://<hub-ip>:8886 --subscribe-events tcp://<hub-ip>:8887 --port 8888
```

O **Node** necessita de especificar as portas para conseguir registar-se com sucesso

```shell
java -jar selenium-server-<version>.jar node --publish-events tcp://<hub-ip>:8886 --subscribe-events tcp://<hub-ip>:8887
```

### Distribuida

Quando usar uma Grid distribuida, cada componente é iniciado separadamente e preferencialmente em máquinas diferentes.

É de extrema importância expor todas as portas necessárias de forma a que a comunicação flua correctamente entre todos os componentes.

1. **Event Bus**: permite comunicação interna entre os diferentes componentes da Grid.

As portas por omissão são: `4442`, `4443`, and `5557`.

```shell
java -jar selenium-server-<version>.jar event-bus --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --port 5557
```

2. **New Session Queue**: adiciona novos pedidos de sessão a uma queue, que serão consultadas pelo Distributor

A porta por omissão é `5559`.

```shell
java -jar selenium-server-<version>.jar sessionqueue --port 5559
```

3. **Session Map**: estabelece um mapa entre id de sessão e o **Node** onde a sessão está a executar

A porta por omissão é `5556`. **Session Map** interage com o **Event Bus**.

```shell
java -jar selenium-server-<version>.jar sessions --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --port 5556
```

4. **Distributor**: consulta **New Session Queue** para novos pedidos de sessão, que entrega ao um **Node** quando encontra um capacidade correspondente. **Nodes** registam-se no **Distributor** da mesma forma como numa Grid do tipo **Hub/Node**.

A porta por omissão é `5553`. **Distributor** interage com **New Session Queue**, **Session Map**, **Event Bus**, e **Node(s)**.

```shell
java -jar selenium-server-<version>.jar distributor --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --sessions http://<sessions-ip>:5556 --sessionqueue http://<new-session-queue-ip>:5559 --port 5553 --bind-bus false
```

5. **Router**: redirecciona novos pedidos de sessão para a queue, e redirecciona pedidos de sessões para o **Node** que estiver a executar a sessão.

A porta por omissão é `4444`. **Router** interage com **New Session Queue**, **Session Map**, e **Distributor**.

```shell
java -jar selenium-server-<version>.jar router --sessions http://<sessions-ip>:5556 --distributor http://<distributor-ip>:5553 --sessionqueue http://<new-session-queue-ip>:5559 --port 4444
```

6. **Node(s)**

A porta por omissão é `5555`.

```shell
java -jar selenium-server-<version>.jar node --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443
```

## Adicionar Metadata nos testes

Adicione Metadata aos testes, através de [GraphQL](https://www.selenium.dev/pt-br/documentation/grid/advanced_features/graphql_support/) ou visualize parcialmente (como `se:name`) através da Selenium Grid UI.

Metadata pode ser adicionada como uma capacidade com o prefixo `se:`. Eis um pequeno exemplo em Java.

```java
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setCapability("browserVersion", "100");
chromeOptions.setCapability("platformName", "Windows");
// Mostrando na Grid UI o nome de um teste ao invés de uma session id
chromeOptions.setCapability("se:name", "My simple test"); 
// Outros tipos de metadara podem ser visualizados na Grid UI 
// ao clicar na informação de sessão ou via GraphQL
chromeOptions.setCapability("se:sampleMetadata", "Valor exemplo de Metadata"); 
WebDriver driver = new RemoteWebDriver(new URL("http://gridUrl:4444"), chromeOptions);
driver.get("http://www.google.com");
driver.quit();
```

```bash
java -Dwebdriver.http.factory=jdk-http-client -jar selenium-server-<version>.jar --ext selenium-http-jdk-client-<version>.jar standalone
```

Uma alternativa a baixar o ficheiro jar `selenium-http-jdk-client` é usar [Coursier](https://get-coursier.io/docs/cli-installation).

```bash
java -Dwebdriver.http.factory=jdk-http-client -jar selenium-server-<version>.jar --ext $(coursier fetch -p org.seleniumhq.selenium:selenium-http-jdk-client:<version>) standalone
```

Última modificação August 1, 2025: [\[deploy site\] fixing bug 2402, detectify link removal (#2407) (0b29bc6e614)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/0b29bc6e6148f4e99aab014c39ae33e5fefe7222)

----
url: https://www.selenium.dev/ja/documentation/grid/configuration/
----

# コンポーネントの構成

ここでは、各コンポーネントを、共通の設定とコンポーネント固有の設定で個別に設定する方法を確認できます。

***

##### [構成ヘルプ](/ja/documentation/grid/configuration/help/)

Gridの設定に利用可能なオプション

##### [Selenium GridのCLI オプション](/ja/documentation/grid/configuration/cli_options/)

全てのGridコンポーネントのCLIオプション詳細

##### [Toml オプション](/ja/documentation/grid/configuration/toml_options/)

Tomlファイルを使用したGridの設定例.

----
url: https://www.selenium.dev/ja/documentation/test_practices/encouraged/improved_reporting/
----

# 改善されたレポート

Seleniumは、実行されたテストケースのステータスをレポートするようには設計されていません。 単体テストフレームワークの組み込みのレポート機能を利用することは、良いスタートです。 ほとんどの単体テストフレームワークには、xUnitまたはHTML形式のレポートを生成できるレポートがあります。 xUnitレポートは、Jenkins、Travis、Bambooなどの継続的インテグレーション（CI）サーバーに結果をインポートするのに人気があります。 いくつかの言語のレポート出力に関する詳細情報へのリンクがあります。

[NUnit 3 Console Runner](//github.com/nunit/docs/wiki/Console-Runner)

[NUnit 3 Console Command Line](//github.com/nunit/docs/wiki/Console-Command-Line)

[xUnit getting test results in TeamCity](//xunit.net/docs/getting-test-results-in-teamcity)

[xUnit getting test results in CruiseControl.NET](//xunit.net/docs/getting-test-results-in-ccnet)

[xUnit getting test results in Azure DevOps](//xunit.net/docs/getting-test-results-in-azure-devops)

----
url: https://www.selenium.dev/documentation/webdriver/elements/finders/
----

# Finding web elements

Locating the elements based on the provided locator values.

One of the most fundamental aspects of using Selenium is obtaining element references to work with. Selenium offers a number of built-in [locator strategies](https://www.selenium.dev/documentation/webdriver/elements/locators/) to uniquely identify an element. There are many ways to use the locators in very advanced scenarios. For the purposes of this documentation, let’s consider this HTML snippet:

```html
<ol id="vegetables">
 <li class="potatoes">…
 <li class="onions">…
 <li class="tomatoes"><span>Tomato is a Vegetable</span>…
</ol>
<ul id="fruits">
  <li class="bananas">…
  <li class="apples">…
  <li class="tomatoes"><span>Tomato is a Fruit</span>…
</ul>
```

```java
WebElement vegetable = driver.findElement(By.className("tomatoes"));
  
```

```python
vegetable = driver.find_element(By.CLASS_NAME, "tomatoes")
  
```

```csharp
var vegetable = driver.FindElement(By.ClassName("tomatoes"));
  
```

```rb
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L14-L15)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const vegetable = await driver.findElement(By.className('tomatoes'));
  
```

```kotlin
val vegetable: WebElement = driver.findElement(By.className("tomatoes"))
  
```

```java
WebElement fruits = driver.findElement(By.id("fruits"));
WebElement fruit = fruits.findElement(By.className("tomatoes"));
  
```

```python
fruits = driver.find_element(By.ID, "fruits")
fruit = fruits.find_element(By.CLASS_NAME,"tomatoes")
  
```

```csharp
IWebElement fruits = driver.FindElement(By.Id("fruits"));
IWebElement fruit = fruits.FindElement(By.ClassName("tomatoes"));
  
```

```rb
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L14-L15)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const fruits = await driver.findElement(By.id('fruits'));
const fruit = fruits.findElement(By.className('tomatoes'));
  
```

```kotlin
val fruits = driver.findElement(By.id("fruits"))
val fruit = fruits.findElement(By.className("tomatoes"))
  
```

```java
WebElement shadowHost = driver.findElement(By.cssSelector("#shadow_host"));
SearchContext shadowRoot = shadowHost.getShadowRoot();
WebElement shadowContent = shadowRoot.findElement(By.cssSelector("#shadow_content"));
```

```python
shadow_host = driver.find_element(By.CSS_SELECTOR, '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(By.CSS_SELECTOR, '#shadow_content')
```

```csharp
var shadowHost = _driver.FindElement(By.CssSelector("#shadow_host"));
var shadowRoot = shadowHost.GetShadowRoot();
var shadowContent = shadowRoot.FindElement(By.CssSelector("#shadow_content"));
```

```ruby
shadow_host = @driver.find_element(css: '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(css: '#shadow_content')
```

```java
WebElement fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"));
  
```

```python
fruit = driver.find_element(By.CSS_SELECTOR,"#fruits .tomatoes")
  
```

```csharp
var fruit = driver.FindElement(By.CssSelector("#fruits .tomatoes"));
  
```

```rb
      driver.find_element(css: '#fruits .tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L19)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const fruit = await driver.findElement(By.css('#fruits .tomatoes'));
  
```

```kotlin
val fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"))
  
```

```java
List<WebElement> plants = driver.findElements(By.tagName("li"));
  
```

```python
plants = driver.find_elements(By.TAG_NAME, "li")
  
```

```csharp
IReadOnlyList<IWebElement> plants = driver.FindElements(By.TagName("li"));
  
```

```rb
      driver.find_elements(tag_name: 'li')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L23)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const plants = await driver.findElements(By.tagName('li'));
  
```

```kotlin
val plants: List<WebElement> = driver.findElements(By.tagName("li"))
  
```

```java
List<WebElement> elements = driver.findElements(By.tagName("li"));

for (WebElement element : elements) {
    System.out.println("Paragraph text:" + element.getText());
}
  
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Firefox()

    # Navigate to Url
driver.get("https://www.example.com")

    # Get all the elements available with tag name 'p'
elements = driver.find_elements(By.TAG_NAME, 'p')

for e in elements:
    print(e.text)
  
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using System.Collections.Generic;

namespace FindElementsExample {
 class FindElementsExample {
  public static void Main(string[] args) {
   IWebDriver driver = new FirefoxDriver();
   try {
    // Navigate to Url
    driver.Navigate().GoToUrl("https://example.com");

    // Get all the elements available with tag name 'p'
    IList < IWebElement > elements = driver.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }

   } finally {
    driver.Quit();
   }
  }
 }
}
  
```

```rb
      elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L27-L28)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
   
   require 'spec_helper'
   
   RSpec.describe 'Element Finders' do
     let(:driver) { start_session }
   
     context 'without executing finders', skip: 'these are just examples, not actual tests' do
       it 'finds the first matching element' do
         driver.find_element(class: 'tomatoes')
       end
   
       it 'uses a subset of the dom to find an element' do
         fruits = driver.find_element(id: 'fruits')
         fruits.find_element(class: 'tomatoes')
       end
   
       it 'uses an optimized locator' do
         driver.find_element(css: '#fruits .tomatoes')
       end
   
       it 'finds all matching elements' do
         driver.find_elements(tag_name: 'li')
       end
   
       it 'gets an element from a collection' do
         elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'finds element from element' do
         element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'find active element' do
         driver.find_element(css: '[name="q"]').send_keys('webElement')
         driver.switch_to.active_element.attribute('title')
       end
     end
   end
   
```

```javascript
const {Builder, By} = require('selenium-webdriver');
(async function example() {
    let driver = await new Builder().forBrowser('firefox').build();
    try {
        // Navigate to Url
        await driver.get('https://www.example.com');

        // Get all the elements available with tag 'p'
        let elements = await driver.findElements(By.css('p'));
        for(let e of elements) {
            console.log(await e.getText());
        }
    }
    finally {
        await driver.quit();
    }
})();
  
```

```kotlin
import org.openqa.selenium.By
import org.openqa.selenium.firefox.FirefoxDriver

fun main() {
    val driver = FirefoxDriver()
    try {
        driver.get("https://example.com")
        // Get all the elements available with tag name 'p'
        val elements = driver.findElements(By.tagName("p"))
        for (element in elements) {
            println("Paragraph text:" + element.text)
        }
    } finally {
        driver.quit()
    }
}
  
```

```java
  import org.openqa.selenium.By;
  import org.openqa.selenium.WebDriver;
  import org.openqa.selenium.WebElement;
  import org.openqa.selenium.chrome.ChromeDriver;
  import java.util.List;

  public class findElementsFromElement {
      public static void main(String[] args) {
          WebDriver driver = new ChromeDriver();
          try {
              driver.get("https://example.com");

              // Get element with tag name 'div'
              WebElement element = driver.findElement(By.tagName("div"));

              // Get all the elements available with tag name 'p'
              List<WebElement> elements = element.findElements(By.tagName("p"));
              for (WebElement e : elements) {
                  System.out.println(e.getText());
              }
          } finally {
              driver.quit();
          }
      }
  }
  
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://www.example.com")
##get elements from parent element using TAG_NAME

    # Get element with tag name 'div'
element = driver.find_element(By.TAG_NAME, 'div')

    # Get all the elements available with tag name 'p'
elements = element.find_elements(By.TAG_NAME, 'p')
for e in elements:
    print(e.text)

##get elements from parent element using XPATH
##NOTE: in order to utilize XPATH from current element, you must add "." to beginning of path

    # Get first element of tag 'ul'
element = driver.find_element(By.XPATH, '//ul')

    # get children of tag 'ul' with tag 'li'
elements  = element.find_elements(By.XPATH, './/li')
for e in elements:
    print(e.text)
  
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace FindElementsFromElement {
 class FindElementsFromElement {
  public static void Main(string[] args) {
   IWebDriver driver = new ChromeDriver();
   try {
    driver.Navigate().GoToUrl("https://example.com");

    // Get element with tag name 'div'
    IWebElement element = driver.FindElement(By.TagName("div"));

    // Get all the elements available with tag name 'p'
    IList < IWebElement > elements = element.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }
   } finally {
    driver.Quit();
   }
  }
 }
}
  
```

```rb
      element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L32-L34)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
   
   require 'spec_helper'
   
   RSpec.describe 'Element Finders' do
     let(:driver) { start_session }
   
     context 'without executing finders', skip: 'these are just examples, not actual tests' do
       it 'finds the first matching element' do
         driver.find_element(class: 'tomatoes')
       end
   
       it 'uses a subset of the dom to find an element' do
         fruits = driver.find_element(id: 'fruits')
         fruits.find_element(class: 'tomatoes')
       end
   
       it 'uses an optimized locator' do
         driver.find_element(css: '#fruits .tomatoes')
       end
   
       it 'finds all matching elements' do
         driver.find_elements(tag_name: 'li')
       end
   
       it 'gets an element from a collection' do
         elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'finds element from element' do
         element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'find active element' do
         driver.find_element(css: '[name="q"]').send_keys('webElement')
         driver.switch_to.active_element.attribute('title')
       end
     end
   end
   
```

```javascript
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = new Builder()
          .forBrowser('chrome')
          .build();

      await driver.get('https://www.example.com');

      // Get element with tag name 'div'
      let element = driver.findElement(By.css("div"));

      // Get all the elements available with tag name 'p'
      let elements = await element.findElements(By.css("p"));
      for(let e of elements) {
          console.log(await e.getText());
      }
  })();
  
```

```kotlin
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://example.com")

          // Get element with tag name 'div'
          val element = driver.findElement(By.tagName("div"))

          // Get all the elements available with tag name 'p'
          val elements = element.findElements(By.tagName("p"))
          for (e in elements) {
              println(e.text)
          }
      } finally {
          driver.quit()
      }
  }
  
```

```java
  import org.openqa.selenium.*;
  import org.openqa.selenium.chrome.ChromeDriver;

  public class activeElementTest {
    public static void main(String[] args) {
      WebDriver driver = new ChromeDriver();
      try {
        driver.get("http://www.google.com");
        driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement");

        // Get attribute of current active element
        String attr = driver.switchTo().activeElement().getAttribute("title");
        System.out.println(attr);
      } finally {
        driver.quit();
      }
    }
  }
  
```

```python
  from selenium import webdriver
  from selenium.webdriver.common.by import By

  driver = webdriver.Chrome()
  driver.get("https://www.google.com")
  driver.find_element(By.CSS_SELECTOR, '[name="q"]').send_keys("webElement")

    # Get attribute of current active element
  attr = driver.switch_to.active_element.get_attribute("title")
  print(attr)
  
```

```csharp
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;

    namespace ActiveElement {
     class ActiveElement {
      public static void Main(string[] args) {
       IWebDriver driver = new ChromeDriver();
       try {
        // Navigate to Url
        driver.Navigate().GoToUrl("https://www.google.com");
        driver.FindElement(By.CssSelector("[name='q']")).SendKeys("webElement");

        // Get attribute of current active element
        string attr = driver.SwitchTo().ActiveElement().GetAttribute("title");
        System.Console.WriteLine(attr);
       } finally {
        driver.Quit();
       }
      }
     }
    }
  
```

```rb
      driver.find_element(css: '[name="q"]').send_keys('webElement')
        driver.switch_to.active_element.attribute('title')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L38-L39)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
  
  require 'spec_helper'
  
  RSpec.describe 'Element Finders' do
    let(:driver) { start_session }
  
    context 'without executing finders', skip: 'these are just examples, not actual tests' do
      it 'finds the first matching element' do
        driver.find_element(class: 'tomatoes')
      end
  
      it 'uses a subset of the dom to find an element' do
        fruits = driver.find_element(id: 'fruits')
        fruits.find_element(class: 'tomatoes')
      end
  
      it 'uses an optimized locator' do
        driver.find_element(css: '#fruits .tomatoes')
      end
  
      it 'finds all matching elements' do
        driver.find_elements(tag_name: 'li')
      end
  
      it 'gets an element from a collection' do
        elements = driver.find_elements(:tag_name, 'p')
        elements.each { |e| puts e.text }
      end
  
      it 'finds element from element' do
        element = driver.find_element(:tag_name, 'div')
        elements = element.find_elements(:tag_name, 'p')
        elements.each { |e| puts e.text }
      end
  
      it 'find active element' do
        driver.find_element(css: '[name="q"]').send_keys('webElement')
        driver.switch_to.active_element.attribute('title')
      end
    end
  end
  
```

```javascript
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = await new Builder().forBrowser('chrome').build();
      await driver.get('https://www.google.com');
      await  driver.findElement(By.css('[name="q"]')).sendKeys("webElement");

      // Get attribute of current active element
      let attr = await driver.switchTo().activeElement().getAttribute("title");
      console.log(`${attr}`)
  })();
  
```

```kotlin
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://www.google.com")
          driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement")

          // Get attribute of current active element
          val attr = driver.switchTo().activeElement().getAttribute("title")
          print(attr)
      } finally {
          driver.quit()
      }
  }
  
```

Last modified September 6, 2025: [changed driver to element (#2471) (daea0ec2a80)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/daea0ec2a80e796aaed225697d8cb307cc68ca81)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/
----

# WebDriver

WebDriver manipula um navegador nativamente; aprenda mais sobre isso.

O WebDriver manipula um navegador nativamente, como um usuário faria, seja localmente ou em uma máquina remota usando o servidor Selenium, marca um salto em termos de automação do navegador.

Selenium WebDriver refere-se a ambas as ligações de linguagem e as implementações do código de controle do navegador individual. Isso é comumente referido como apenas *WebDriver*.

Selenium WebDriver é uma [recomendação W3C](https://www.w3.org/TR/webdriver1/)

* WebDriver é projetado como uma interface de programação simples e mais concisa.

* WebDriver é uma API compacta orientada a objetos.

* Ele manipula o navegador de forma eficaz.

***

##### [Começando](/pt-br/documentation/webdriver/getting_started/)

Se você é novo no Selenium, nós temos alguns recursos que podem te ajudar a se atualizar imediatamente.

##### [Sessões de Driver](/pt-br/documentation/webdriver/drivers/)

##### [Navegadores suportados](/pt-br/documentation/webdriver/browsers/)

##### [Esperas](/pt-br/documentation/webdriver/waits/)

##### [Elemento Web](/pt-br/documentation/webdriver/elements/)

Identificando e trabalhando com elementos no DOM.

##### [Browser interactions](/pt-br/documentation/webdriver/interactions/)

##### [Ações API](/pt-br/documentation/webdriver/actions_api/)

Uma interface de baixo nível para fornecer ações de entrada de dispositivo virtualizadas para o navegador da web..

##### [BiDirectional functionality](/pt-br/documentation/webdriver/bidi/)

##### [Recursos de suporte](/pt-br/documentation/webdriver/support_features/)

As classes de suporte fornecem características opcionais de nível superior.

##### [Troubleshooting Assistance](/pt-br/documentation/webdriver/troubleshooting/)

How to solve WebDriver problems.

Última modificação March 29, 2024: [fix grammer fixes #1647 \[deploy site\] (690cd94e738)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/690cd94e738dee759adbfecf05b02b8fe3f8ef36)

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/encouraged/domain_specific_language/
----

# Linguagem específica de domínio (DSL)

```java
/**
 * Recebe um username e password, prrenche os campos, e clica em "login".
 * @return Uma instância de AccountPage
 */
public AccountPage loginAsUser(String username, String password) {
  WebElement loginField = driver.findElement(By.id("loginField"));
  loginField.clear();
  loginField.sendKeys(username);

  // Preenche o campo password. O localizador que estamos usando é "By.id", e devemos
  // definí-lo em algum outro lugar dentro da Classe.
  WebElement passwordField = driver.findElement(By.id("password"));
  passwordField.clear();
  passwordField.sendKeys(password);

  // Clica o botão de login, que possui o id "submit".
  driver.findElement(By.id("submit")).click();

  // Cria e retorna uma nova instância de AccountPage (via o Selenium
  // PageFactory embutido).
  return PageFactory.newInstance(AccountPage.class);
}
```

Este método abstrai completamente os conceitos de campos de entrada, botões, cliques e até páginas do seu código de teste. Usando este abordagem, tudo o que o testador precisa fazer é chamar esse método. Isto dá uma vantagem de manutenção: se os campos de login mudaram, você teria apenas que alterar esse método - não seus testes.

```java
public void loginTest() {
    loginAsUser("cbrown", "cl0wn3");

    // Agora que estamos logados, fazemos alguma outra coisa--como usamos uma DSL para suportar
    // nossos testadores, é apenas escolher um dos métodos disponíveis.
    do.something();
    do.somethingElse();
    Assert.assertTrue("Algo deveria ter sido feito!", something.wasDone());

    // Note que ainda não nos referimos a nenhum botão ou web control nesse
    // script...
}
```

Vale a pena repetir: um de seus principais objetivos deve ser escrever um API que permite que seus testes resolvam **o problema em questão, e NÃO o problema da IU**. A IU é uma preocupação secundária para o seu usuários - eles não se importam com a interface do usuário, eles apenas querem fazer seu trabalho feito. Seus scripts de teste devem ser lidos como uma lista de itens sujos que o usuário deseja FAZER e as coisas que deseja SABER. Os testes não devem se preocupar com COMO a interface do usuário exige que você vá sobre isso.

----
url: https://www.selenium.dev/ja/documentation/webdriver/elements/file_upload/
----

```java
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/FileUploadTest.java#L17-L19)

##### /examples/java/src/test/java/dev/selenium/elements/FileUploadTest.java

```java
package dev.selenium.elements;

import dev.selenium.BaseChromeTest;
import java.io.File;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

public class FileUploadTest extends BaseChromeTest {

  @Test
  public void fileUploadTest() {
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }
}
```

```py
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_file_upload.py#L12-L14)

##### /examples/python/tests/elements/test\_file\_upload.py

```py
import os

from selenium import webdriver
from selenium.webdriver.common.by import By


def test_uploads(driver):
    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"
```

```cs
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/FileUploadTest.cs#L21-L23)

##### /examples/dotnet/SeleniumDocs/Elements/FileUploadTest.cs

```cs
using System;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;

namespace SeleniumDocs.Elements
{
    [TestClass]
    public class FileUploadTest : BaseChromeTest
    {
        [TestMethod]
        public void Uploads()
        {
            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }
    }
}
```

```rb
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/file_upload_spec.rb#L12-L14)

##### /examples/ruby/spec/elements/file\_upload\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'File Upload' do
  let(:driver) { start_session }

  it 'uploads' do
    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    file_name = driver.find_element(id: 'uploaded-files')
    expect(file_name.text).to eq 'selenium-snapshot.png'
  end
end
```

```js
    await driver.get('https://the-internet.herokuapp.com/upload');
    // Upload snapshot
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/fileUpload.spec.js#L24-L25)

##### /examples/javascript/test/elements/fileUpload.spec.js

```js

const {Browser, By, until, Builder} = require("selenium-webdriver");
const path = require("path");
const assert = require('node:assert');


describe('File Upload Test', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async() => await driver.quit());

  it('Should be able to upload a file successfully', async function() {
    const image = path.resolve('./test/resources/selenium-snapshot.png')

    await driver.manage().setTimeouts({implicit: 5000});

    // Navigate to URL
    await driver.get('https://the-internet.herokuapp.com/upload');
    // Upload snapshot
    await driver.findElement(By.id("file-upload")).sendKeys(image);
    await driver.findElement(By.id("file-submit")).submit();

    const revealed = await driver.findElement(By.id('uploaded-files'))
    await driver.wait(until.elementIsVisible(revealed), 2000);
    const data = await driver.findElement(By.css('h3'));

    assert.equal(await data.getText(), `File Uploaded!`);
  });
});
```

[Move Code](/documentation/about/contributing/#moving-examples)

\`\`\`java import org.openqa.selenium.By import org.openqa.selenium.chrome.ChromeDriver fun main() { val driver = ChromeDriver() driver.get("https\://the-internet.herokuapp.com/upload") driver.findElement(By.id("file-upload")).sendKeys("selenium-snapshot.jpg") driver.findElement(By.id("file-submit")).submit() if(driver.pageSource.contains("File Uploaded!")) { println("file uploaded") } else{ println("file not uploaded") } } \`\`\`

最終更新 October 30, 2025: [modified link weight for file upload to come in logical order for element (#2491) (f297c0685df)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/f297c0685df60e4c7aaebca746612ee8c659a886)

----
url: https://www.selenium.dev/ja/documentation/webdriver/interactions/windows/
----

# ウィンドウとタブの操作

```java
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L16-L20)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L16-L18)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L17-L21)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
driver.window_handle
```

```javascript
await driver.getWindowHandle();
```

```kotlin
driver.windowHandle
```

```java
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L22-L29)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L22-L32)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L23-L30)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
    #Store the ID of the original window
original_window = driver.window_handle

    #Check we don't have other windows open already
assert(driver.window_handles.length == 1, 'Expected one window')

    #Click the link which opens in a new window
driver.find_element(link: 'new window').click

    #Wait for the new window or tab
wait.until { driver.window_handles.length == 2 }

    #Loop through until we find a new window handle
driver.window_handles.each do |handle|
    if handle != original_window
        driver.switch_to.window handle
        break
    end
end

    #Wait for the new tab to finish loading content
wait.until { driver.title == 'Selenium documentation'}
  
```

```javascript
//Store the ID of the original window
const originalWindow = await driver.getWindowHandle();

//Check we don't have other windows open already
assert((await driver.getAllWindowHandles()).length === 1);

//Click the link which opens in a new window
await driver.findElement(By.linkText('new window')).click();

//Wait for the new window or tab
await driver.wait(
    async () => (await driver.getAllWindowHandles()).length === 2,
    10000
  );

//Loop through until we find a new window handle
const windows = await driver.getAllWindowHandles();
windows.forEach(async handle => {
  if (handle !== originalWindow) {
    await driver.switchTo().window(handle);
  }
});

//Wait for the new tab to finish loading content
await driver.wait(until.titleIs('Selenium documentation'), 10000);
  
```

```kotlin
//Store the ID of the original window
val originalWindow = driver.getWindowHandle()

//Check we don't have other windows open already
assert(driver.getWindowHandles().size() === 1)

//Click the link which opens in a new window
driver.findElement(By.linkText("new window")).click()

//Wait for the new window or tab
wait.until(numberOfWindowsToBe(2))

//Loop through until we find a new window handle
for (windowHandle in driver.getWindowHandles()) {
    if (!originalWindow.contentEquals(windowHandle)) {
        driver.switchTo().window(windowHandle)
        break
    }
}

//Wait for the new tab to finish loading content
wait.until(titleIs("Selenium documentation"))

  
```

```java
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L31-L34)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L46-L46)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L32-L35)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
    #Close the tab or window
driver.close

    #Switch back to the old tab or window
driver.switch_to.window original_window
  
```

```javascript
//Close the tab or window
await driver.close();

//Switch back to the old tab or window
await driver.switchTo().window(originalWindow);
  
```

```kotlin
//Close the tab or window
driver.close()

//Switch back to the old tab or window
driver.switchTo().window(originalWindow)

  
```

```java
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L36-L42)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L53-L58)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L37-L43)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

Opens a new tab and switches to new tab

```rb
    driver.switch_to.new_window(:tab)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/windows_spec.rb#L9)

##### /examples/ruby/spec/interactions/windows\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Windows' do
  let(:driver) { start_session }

  it 'opens new tab' do
    driver.switch_to.new_window(:tab)

    expect(driver.window_handles.size).to eq 2
  end

  it 'opens new window' do
    driver.switch_to.new_window(:window)

    expect(driver.window_handles.size).to eq 2
  end
end
```

Opens a new window and switches to new window

```rb
    driver.switch_to.new_window(:window)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/windows_spec.rb#L15)

##### /examples/ruby/spec/interactions/windows\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Windows' do
  let(:driver) { start_session }

  it 'opens new tab' do
    driver.switch_to.new_window(:tab)

    expect(driver.window_handles.size).to eq 2
  end

  it 'opens new window' do
    driver.switch_to.new_window(:window)

    expect(driver.window_handles.size).to eq 2
  end
end
```

Opens a new tab and switches to new tab

```js
    await driver.switchTo().newWindow('tab');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L70)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

Opens a new window and switches to new window:

```js
    await driver.switchTo().newWindow('window');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L75)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Opens a new tab and switches to new tab
driver.switchTo().newWindow(WindowType.TAB)

// Opens a new window and switches to new window
driver.switchTo().newWindow(WindowType.WINDOW)
  
```

```java
        //quitting driver
        driver.quit(); //close all windows
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L44-L45)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L13-L13)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //quitting driver
              driver.Quit(); //close all windows
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L45-L46)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
driver.quit
```

```javascript
await driver.quit();
```

```kotlin
driver.quit()
```

```java
/**
 * Example using JUnit
 * https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
 */
@AfterAll
public static void tearDown() {
    driver.quit();
}
  
```

```python
    # unittest teardown
    # https://docs.python.org/3/library/unittest.html?highlight=teardown#unittest.TestCase.tearDown
def tearDown(self):
    self.driver.quit()
  
```

```csharp
/*
    Example using Visual Studio's UnitTesting
    https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.aspx
*/
[TestCleanup]
public void TearDown()
{
    driver.Quit();
}
  
```

```ruby
    # UnitTest Teardown
    # https://www.rubydoc.info/github/test-unit/test-unit/Test/Unit/TestCase
def teardown
    @driver.quit
end
  
```

```javascript
/**
 * Example using Mocha
 * https://mochajs.org/#hooks
 */
after('Tear down', async function () {
  await driver.quit();
});
  
```

```kotlin
/**
 * Example using JUnit
 * https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
 */
@AfterAll
fun tearDown() {
    driver.quit()
}
  
```

```java
try {
    //WebDriver code here...
} finally {
    driver.quit();
}
  
```

```python
try:
    #WebDriver code here...
finally:
    driver.quit()
  
```

```csharp
try {
    //WebDriver code here...
} finally {
    driver.Quit();
}
  
```

```ruby
begin
    #WebDriver code here...
ensure
    driver.quit
end
  
```

```javascript
try {
    //WebDriver code here...
} finally {
    await driver.quit();
}
  
```

```kotlin
try {
    //WebDriver code here...
} finally {
    driver.quit()
}
  
```

PythonのWebDriverは、pythonコンテキストマネージャーをサポートするようになりました。 withキーワードを使用すると、実行終了時にドライバーを自動的に終了できます。

```python
with webdriver.Firefox() as driver:
  # WebDriver code here...

# WebDriver will automatically quit after indentation
```

```java
//Access each dimension individually
int width = driver.manage().window().getSize().getWidth();
int height = driver.manage().window().getSize().getHeight();

//Or store the dimensions and query them later
Dimension size = driver.manage().window().getSize();
int width1 = size.getWidth();
int height1 = size.getHeight();
  
```

```python
    # Access each dimension individually
width = driver.get_window_size().get("width")
height = driver.get_window_size().get("height")

    # Or store the dimensions and query them later
size = driver.get_window_size()
width1 = size.get("width")
height1 = size.get("height")
  
```

```csharp
//Access each dimension individually
int width = driver.Manage().Window.Size.Width;
int height = driver.Manage().Window.Size.Height;

//Or store the dimensions and query them later
System.Drawing.Size size = driver.Manage().Window.Size;
int width1 = size.Width;
int height1 = size.Height;
  
```

```ruby
    # Access each dimension individually
width = driver.manage.window.size.width
height = driver.manage.window.size.height

    # Or store the dimensions and query them later
size = driver.manage.window.size
width1 = size.width
height1 = size.height
  
```

Access each dimension individually

```js
    const { width, height } = await driver.manage().window().getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L93)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

(or) store the dimensions and query them later

```js
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L96-L98)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
//Access each dimension individually
val width = driver.manage().window().size.width
val height = driver.manage().window().size.height

//Or store the dimensions and query them later
val size = driver.manage().window().size
val width1 = size.width
val height1 = size.height
  
```

```java
driver.manage().window().setSize(new Dimension(1024, 768));
```

```python
driver.set_window_size(1024, 768)
```

```csharp
driver.Manage().Window.Size = new Size(1024, 768);
```

```ruby
driver.manage.window.resize_to(1024,768)
```

```javascript
await driver.manage().window().setRect({ width: 1024, height: 768 });
```

```kotlin
driver.manage().window().size = Dimension(1024, 768)
```

```java
// Access each dimension individually
int x = driver.manage().window().getPosition().getX();
int y = driver.manage().window().getPosition().getY();

// Or store the dimensions and query them later
Point position = driver.manage().window().getPosition();
int x1 = position.getX();
int y1 = position.getY();
  
```

```python
    # Access each dimension individually
x = driver.get_window_position().get('x')
y = driver.get_window_position().get('y')

    # Or store the dimensions and query them later
position = driver.get_window_position()
x1 = position.get('x')
y1 = position.get('y')
  
```

```csharp
//Access each dimension individually
int x = driver.Manage().Window.Position.X;
int y = driver.Manage().Window.Position.Y;

//Or store the dimensions and query them later
Point position = driver.Manage().Window.Position;
int x1 = position.X;
int y1 = position.Y;
  
```

```ruby
    #Access each dimension individually
x = driver.manage.window.position.x
y = driver.manage.window.position.y

    # Or store the dimensions and query them later
rect  = driver.manage.window.rect
x1 = rect.x
y1 = rect.y
  
```

Access each dimension individually

```js
    const { x, y } = await driver.manage().window().getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L108)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

(or) store the dimensions and query them later

```js
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L111-L113)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Access each dimension individually
val x = driver.manage().window().position.x
val y = driver.manage().window().position.y

// Or store the dimensions and query them later
val position = driver.manage().window().position
val x1 = position.x
val y1 = position.y

  
```

```
## ウィンドウの位置設定
```

```java
// Move the window to the top left of the primary monitor
driver.manage().window().setPosition(new Point(0, 0));
  
```

```python
    # Move the window to the top left of the primary monitor
driver.set_window_position(0, 0)
  
```

```csharp
// Move the window to the top left of the primary monitor
driver.Manage().Window.Position = new Point(0, 0);
  
```

```ruby
driver.manage.window.move_to(0,0)
  
```

```javascript
// Move the window to the top left of the primary monitor
await driver.manage().window().setRect({ x: 0, y: 0 });
  
```

```kotlin
// Move the window to the top left of the primary monitor
driver.manage().window().position = Point(0,0)
    
```

```java
driver.manage().window().maximize();
```

```python
driver.maximize_window()
```

```csharp
driver.Manage().Window.Maximize();
```

```ruby
driver.manage.window.maximize
```

```javascript
await driver.manage().window().maximize();
```

```kotlin
driver.manage().window().maximize()
```

```java
driver.manage().window().minimize();
```

```python
driver.minimize_window()
```

```csharp
driver.Manage().Window.Minimize();
```

```ruby
driver.manage.window.minimize
```

```javascript
await driver.manage().window().minimize();
```

```kotlin
driver.manage().window().minimize()
```

```java
driver.manage().window().fullscreen();
```

```python
driver.fullscreen_window()
```

```csharp
driver.Manage().Window.FullScreen();
```

```ruby
driver.manage.window.full_screen
```

```javascript
await driver.manage().window().fullscreen();
```

```kotlin
driver.manage().window().fullscreen()
```

```java
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.*;
import org.openqa.selenium.*;

public class SeleniumTakeScreenshot {
    public static void main(String args[]) throws IOException {
        WebDriver driver = new ChromeDriver();
        driver.get("http://www.example.com");
        File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(scrFile, new File("./image.png"));
        driver.quit();
    }
}
  
```

```python
from selenium import webdriver

driver = webdriver.Chrome()

    # Navigate to url
driver.get("http://www.example.com")

    # Returns and base64 encoded string into image
driver.save_screenshot('./image.png')

driver.quit()
```

```csharp
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using OpenQA.Selenium.Support.UI;

  var driver = new ChromeDriver();
  driver.Navigate().GoToUrl("http://www.example.com");
  Screenshot screenshot = (driver as ITakesScreenshot).GetScreenshot();
  screenshot.SaveAsFile("screenshot.png", ScreenshotImageFormat.Png); // Format values are Bmp, Gif, Jpeg, Png, Tiff
  
```

```ruby
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://example.com/'

    # Takes and Stores the screenshot in specified path
  driver.save_screenshot('./image.png')

end
  
```

```js
    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L56-L59)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
import com.oracle.tools.packager.IOUtils.copyFile
import org.openqa.selenium.*
import org.openqa.selenium.chrome.ChromeDriver
import java.io.File

fun main(){
    val driver =  ChromeDriver()
    driver.get("https://www.example.com")
    val scrFile = (driver as TakesScreenshot).getScreenshotAs<File>(OutputType.FILE)
    copyFile(scrFile, File("./image.png"))
    driver.quit()
}
  
```

```java
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.File;
import java.io.IOException;

public class SeleniumelementTakeScreenshot {
  public static void main(String args[]) throws IOException {
    WebDriver driver = new ChromeDriver();
    driver.get("https://www.example.com");
    WebElement element = driver.findElement(By.cssSelector("h1"));
    File scrFile = element.getScreenshotAs(OutputType.FILE);
    FileUtils.copyFile(scrFile, new File("./image.png"));
    driver.quit();
  }
}
 
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

    # Navigate to url
driver.get("http://www.example.com")

ele = driver.find_element(By.CSS_SELECTOR, 'h1')

    # Returns and base64 encoded string into image
ele.screenshot('./image.png')

driver.quit()
  
```

```csharp
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;
    using OpenQA.Selenium.Support.UI;

    // Webdriver
    var driver = new ChromeDriver();
    driver.Navigate().GoToUrl("http://www.example.com");

    // Fetch element using FindElement
    var webElement = driver.FindElement(By.CssSelector("h1"));

    // Screenshot for the element
    var elementScreenshot = (webElement as ITakesScreenshot).GetScreenshot();
    elementScreenshot.SaveAsFile("screenshot_of_element.png");
  
```

```ruby
    # Works with Selenium4-alpha7 Ruby bindings and above
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://example.com/'
  ele = driver.find_element(:css, 'h1')

    # Takes and Stores the element screenshot in specified path
  ele.save_screenshot('./image.jpg')
end
  
```

```js
    let header = await driver.findElement(By.css('h1'));
      // Captures the element screenshot
      let encodedString = await header.takeScreenshot(true);
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
  
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L44-L48)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
  const chrome = require('selenium-webdriver/chrome');
  const assert = require("node:assert");
  let opts = new chrome.Options();
  opts.addArguments('--headless');
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let imgMagicNumber = 'iVBOR'
  let base64Code
  
  describe('Interactions - Windows', function () {
    let driver;
    before(async function () {
      driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
    });
  
    after(async () => await driver.quit());
  
    it('Should be able to print page to pdf', async function () {
  
      await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
      let base64 = await driver.printPage({pageRanges: ["1-2"]});
      // page can be saved as a PDF as below
      // await fs.writeFileSync('./test.pdf', base64, 'base64');
  
      base64Code = base64.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, pdfMagicNumber)
    });
  
    it('Should be able to get text using executeScript', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
      // Stores the header element
      let header = await driver.findElement(By.css('h1'));
  
      // Executing JavaScript to capture innerText of header element
      let text = await driver.executeScript('return arguments[0].innerText', header);
      assert.strictEqual(text, `Type Stuff`)
    });
  
    it('Should be able to take Element Screenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      let header = await driver.findElement(By.css('h1'));
      // Captures the element screenshot
      let encodedString = await header.takeScreenshot(true);
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to takeScreenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      // Captures the screenshot
      let encodedString = await driver.takeScreenshot();
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to switch to newWindow and newTab and close', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
      const initialWindow = await driver.getAllWindowHandles();
      assert.strictEqual(initialWindow.length, 1)
  
      // Opens a new tab and switches to new tab
      await driver.switchTo().newWindow('tab');
      const browserTabs = await driver.getAllWindowHandles();
      assert.strictEqual(browserTabs.length, 2)
  
      // Opens a new window and switches to new window
      await driver.switchTo().newWindow('window');
      const windows = await driver.getAllWindowHandles();
      assert.strictEqual(windows.length, 3)
  
      //Close the tab or window
      await driver.close();
  
      //Switch back to the old tab or window
      await driver.switchTo().window(windows[1]);
  
      const windowsAfterClose = await driver.getAllWindowHandles();
      assert.strictEqual(windowsAfterClose.length, 2);
    });
  
    it('Should be able to getWindow Size', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { width, height } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const windowWidth = rect.width;
      const windowHeight = rect.height;
  
      assert.ok(windowWidth>0);
      assert.ok(windowHeight>0);
    });
  
    it('Should be able to getWindow position', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { x, y } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const x1 = rect.x;
      const y1 = rect.y;
  
      assert.ok(x1>=0);
      assert.ok(y1>=0);
    });
  });
```

```kotlin
import org.apache.commons.io.FileUtils
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.*
import java.io.File

fun main() {
    val driver = ChromeDriver()
    driver.get("https://www.example.com")
    val element = driver.findElement(By.cssSelector("h1"))
    val scrFile: File = element.getScreenshotAs(OutputType.FILE)
    FileUtils.copyFile(scrFile, File("./image.png"))
    driver.quit()
}
  
```

```java
    //Creating the JavascriptExecutor interface object by Type casting
      JavascriptExecutor js = (JavascriptExecutor)driver;
    //Button Element
      WebElement button =driver.findElement(By.name("btnLogin"));
    //Executing JavaScript to click on element
      js.executeScript("arguments[0].click();", button);
    //Get return value from script
      String text = (String) js.executeScript("return arguments[0].innerText", button);
    //Executing JavaScript directly
      js.executeScript("console.log('hello world')");
  
```

```python
    # Stores the header element
header = driver.find_element(By.CSS_SELECTOR, "h1")

    # Executing JavaScript to capture innerText of header element
driver.execute_script('return arguments[0].innerText', header)
  
```

```csharp
    //creating Chromedriver instance
	IWebDriver driver = new ChromeDriver();
	//Creating the JavascriptExecutor interface object by Type casting
	IJavaScriptExecutor js = (IJavaScriptExecutor) driver;
	//Button Element
	IWebElement button = driver.FindElement(By.Name("btnLogin"));
	//Executing JavaScript to click on element
	js.ExecuteScript("arguments[0].click();", button);
	//Get return value from script
	String text = (String)js.ExecuteScript("return arguments[0].innerText", button);
	//Executing JavaScript directly
	js.ExecuteScript("console.log('hello world')");
  
```

```ruby
    # Stores the header element
header = driver.find_element(css: 'h1')

    # Get return value from script
result = driver.execute_script("return arguments[0].innerText", header)

    # Executing JavaScript directly
driver.execute_script("alert('hello world')")
  
```

```js
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L33-L37)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Stores the header element
val header = driver.findElement(By.cssSelector("h1"))

// Get return value from script
val result = driver.executeScript("return arguments[0].innerText", header)

// Executing JavaScript directly
driver.executeScript("alert('hello world')")
  
```

```java
    import org.openqa.selenium.print.PrintOptions;

    driver.get("https://www.selenium.dev");
    printer = (PrintsPage) driver;

    PrintOptions printOptions = new PrintOptions();
    printOptions.setPageRanges("1-2");

    Pdf pdf = printer.print(printOptions);
    String content = pdf.getContent();
  
```

```python
    from selenium.webdriver.common.print_page_options import PrintOptions

    print_options = PrintOptions()
    print_options.page_ranges = ['1-2']

    driver.get("printPage.html")

    base64code = driver.print_page(print_options)
  
```

```csharp
    // code sample not available please raise a PR
  
```

```ruby
    driver.navigate_to 'https://www.selenium.dev'

    base64encodedContent = driver.print_page(orientation: 'landscape')
  
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
      let base64 = await driver.printPage({pageRanges: ["1-2"]});
      // page can be saved as a PDF as below
      // await fs.writeFileSync('./test.pdf', base64, 'base64');
  
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L22-L25)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
  const chrome = require('selenium-webdriver/chrome');
  const assert = require("node:assert");
  let opts = new chrome.Options();
  opts.addArguments('--headless');
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let imgMagicNumber = 'iVBOR'
  let base64Code
  
  describe('Interactions - Windows', function () {
    let driver;
    before(async function () {
      driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
    });
  
    after(async () => await driver.quit());
  
    it('Should be able to print page to pdf', async function () {
  
      await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
      let base64 = await driver.printPage({pageRanges: ["1-2"]});
      // page can be saved as a PDF as below
      // await fs.writeFileSync('./test.pdf', base64, 'base64');
  
      base64Code = base64.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, pdfMagicNumber)
    });
  
    it('Should be able to get text using executeScript', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
      // Stores the header element
      let header = await driver.findElement(By.css('h1'));
  
      // Executing JavaScript to capture innerText of header element
      let text = await driver.executeScript('return arguments[0].innerText', header);
      assert.strictEqual(text, `Type Stuff`)
    });
  
    it('Should be able to take Element Screenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      let header = await driver.findElement(By.css('h1'));
      // Captures the element screenshot
      let encodedString = await header.takeScreenshot(true);
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to takeScreenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      // Captures the screenshot
      let encodedString = await driver.takeScreenshot();
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to switch to newWindow and newTab and close', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
      const initialWindow = await driver.getAllWindowHandles();
      assert.strictEqual(initialWindow.length, 1)
  
      // Opens a new tab and switches to new tab
      await driver.switchTo().newWindow('tab');
      const browserTabs = await driver.getAllWindowHandles();
      assert.strictEqual(browserTabs.length, 2)
  
      // Opens a new window and switches to new window
      await driver.switchTo().newWindow('window');
      const windows = await driver.getAllWindowHandles();
      assert.strictEqual(windows.length, 3)
  
      //Close the tab or window
      await driver.close();
  
      //Switch back to the old tab or window
      await driver.switchTo().window(windows[1]);
  
      const windowsAfterClose = await driver.getAllWindowHandles();
      assert.strictEqual(windowsAfterClose.length, 2);
    });
  
    it('Should be able to getWindow Size', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { width, height } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const windowWidth = rect.width;
      const windowHeight = rect.height;
  
      assert.ok(windowWidth>0);
      assert.ok(windowHeight>0);
    });
  
    it('Should be able to getWindow position', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { x, y } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const x1 = rect.x;
      const y1 = rect.y;
  
      assert.ok(x1>=0);
      assert.ok(y1>=0);
    });
  });
```

```kotlin
    driver.get("https://www.selenium.dev")
    val printer = driver as PrintsPage

    val printOptions = PrintOptions()
    printOptions.setPageRanges("1-2")
    
    val pdf: Pdf = printer.print(printOptions)
    val content = pdf.content
  
```

最終更新 May 11, 2026: [Move Python examples in Windows interactions docs (#2629) (d368a9324d6)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/d368a9324d6aa6bb62c016bb5572d28966a7f091)

----
url: https://www.selenium.dev/pt-br/documentation/legacy/selenium_2/remote_server/
----

# Servidor do WebDriver remoto

O servidor sempre será executado na máquina com o navegador que você deseja testar. O servidor pode ser usado a partir da linha de comando ou por meio de configuração de código.

## Iniciando o servidor a partir da linha de comando

Depois de fazer o download do `selenium-server-standalone-{VERSION}.jar`, coloque-o no computador com o navegador que deseja testar. Então, a partir do diretório com o jar, execute o seguinte:

```shell
java -jar selenium-server-standalone-{VERSION}.jar
```

## Considerações para executar o servidor

O chamador deve encerrar cada sessão adequadamente, chamando ou `Selenium#stop()` ou `WebDriver#quit`.

O selenium-server mantém registros na memória para cada sessão em andamento, que são apagados quando `Selenium#stop()` ou `WebDriver#quit` é chamado. E se você se esquecer de encerrar essas sessões, seu servidor pode vazar memória. E se você mantém sessões de duração extremamente longa, você provavelmente precisará parar / sair de vez em quando (ou aumentar a memória com a opção -Xmx jvm).

## Timeouts (a partir da versão 2.21)

O servidor tem dois timeouts diferentes, que podem ser definidos da seguinte forma:

```shell
java -jar selenium-server-standalone-{VERSION}.jar -timeout=20 -browserTimeout=60
```

```java
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.security.SslSocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;

import javax.servlet.Servlet;
import java.io.File;

import org.openqa.selenium.remote.server.DriverServlet;

public class AppServer {
  private Server server = new Server();

  public AppServer() throws Exception {
    WebAppContext context = new WebAppContext();
    context.setContextPath("");
    context.setWar(new File("."));
    server.addHandler(context);

    context.addServlet(DriverServlet.class, "/wd/*");

    SelectChannelConnector connector = new SelectChannelConnector();
    connector.setPort(3001);
    server.addConnector(connector);

    server.start();
  }
}
```

----
url: https://www.selenium.dev/zh-cn/_print/documentation/webdriver/bidi/w3c/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/webdriver/bidi/w3c/).

# BiDirectional API (W3C compliant)

* 1: [Browsing Context](#pg-18a4f1bf24146bb6dc64ec60fc16e5e0)
* 2: [Browsing Context](#pg-1c9206c324004d2907d65b20a62e06b7)
* 3: [Network](#pg-825ec0dbc6d0e573bacd5a04afa9a202)
* 4: [Script](#pg-7df649634fdcb94f736cad7082db1142)
* 5: [BiDirectional API (W3C compliant)](#pg-7508e216293ced7d22773d89cd4363fc)

The following list of APIs will be growing as the [WebDriver BiDirectional Protocol](https://w3c.github.io/webdriver-bidi/) 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](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=\&template=feature.md).

# 1 - Browsing Context

```java
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L44-L47)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L33-L35)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

    @Test
    void testNavigateToAUrl() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L58-L61)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L48-L50)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L37-L41)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L25-L28)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L50-L55)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L40-L43)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        Assertions.assertNotNull(browsingContext.getId());
        Assertions.assertNotNull(info.getNavigationId());
        Assertions.assertTrue(info.getUrl().contains("/bidi/logEntryAdded.html"));
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L64-L69)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L55-L58)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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"));
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L72-L80)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L67)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L83-L92)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L79-L82)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        Assertions.assertTrue(info.getChildren().get(0).getUrl().contains("formPage.html"));
    }

    @Test
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L95-L108)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    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()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L90-L96)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    }

    @Test
    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());
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L111-L123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L103-L109)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window2.close();

        Assertions.assertThrows(BiDiException.class, window2::getTree);
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L126-L133)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.20.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.20.0.0)

```js
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L426-L431)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext tab2 = new BrowsingContext(driver, WindowType.TAB);

        tab2.close();

        Assertions.assertThrows(BiDiException.class, tab2::getTree);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L136-L153)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L115-L118)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L157-L161)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L192-L194)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```js
    await window1.activate()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L204)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L169-L173)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.reload(undefined, 'complete')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L351)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    @Test
    void testDismissUserPromptWithText() {
        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";
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L220-L228)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.handleUserPrompt(true, userText)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L301)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        driver.get("https://www.selenium.dev/selenium/web/coordinates_tests/simple_page.html");

        WebElement element = driver.findElement(By.id("box"));
        Rectangle elementRectangle = element.getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L248-L252)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const response = await browsingContext.captureScreenshot()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L362)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    }

    @Test
    void textCaptureElementScreenshot() {
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L259-L268)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L165-L169)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L275-L280)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const response = await browsingContext.captureElementScreenshot(elementId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L184)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L304-L307)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.setViewport(250, 300)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L335)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L317-L322)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    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'],
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L145-L157)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        wait.until(visibilityOfElementLocated(By.id("imageButton"))).submit();
        wait.until(titleIs("We Arrive Here"));

        browsingContext.back();
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L330-L336)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.back()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L396)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L342-L352)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.forward()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L420)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L359-L365)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.traverseHistory(-1)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L378)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L34-L41)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L23-L28)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L54-L63)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L53-L62)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L81-88)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L70-L78)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L97-104)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L113-123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L86-L97)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L113-123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L150-163)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L170-L181)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0.0)

```js
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L105-L113)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

[Add Example](/documentation/about/contributing/#creating-examples)

# 2 - Browsing Context

```java
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ActionsTest.java#L41-L44)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ActionsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Input;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.interactions.Actions;

class ActionsTest extends BaseTest {
    private Input input;

    private String windowHandle;

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        windowHandle = driver.getWindowHandle();
        input = new Input(driver);
    }

    @Test
    void canPerformInputActions() {
        driver.get("https://www.selenium.dev/selenium/web/formSelectionPage.html");

        List<WebElement> options = driver.findElements(By.tagName("option"));

        Actions actions = new Actions(driver);
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());

        WebElement showButton = driver.findElement(By.name("showselected"));
        showButton.click();

        WebElement resultElement = driver.findElement(By.id("result"));
        Assertions.assertTrue(resultElement.getText().contains("roquefort parmigiano cheddar"));
        }

    @Test
    void canPerformReleaseAction() {
        driver.get("https://www.selenium.dev/selenium/web/bidi/release_action.html");

        WebElement inputTextBox = driver.findElement(By.id("keys"));

        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);

        List<Map<String, Object>> events =
                (List<Map<String, Object>>)
                        ((JavascriptExecutor) driver).executeScript("return allEvents.events");
        Assertions.assertEquals("KeyB", events.get(0).get("code"));
        Assertions.assertEquals("KeyA", events.get(1).get("code"));
        }
    }
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/input.spec.js#L27-L29)

##### /examples/javascript/test/bidirectional/input.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, Key, Builder} = require("selenium-webdriver")
const Input = require('selenium-webdriver/bidi/input')

describe('Input module', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can perform input action', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/formSelectionPage.html')

    let options = await driver.findElements(By.tagName('option'))

    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)

    let showButton = await driver.findElement(By.name('showselected'))
    showButton.click()

    let resultElement = await driver.findElement(By.id('result'))
    await resultElement.getText().then(function (text) {
      assert(text.includes('oquefort parmigiano cheddar'), `text is: ${text}`)
    })
  })

  it('can execute release in browsing context', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/bidi/release_action.html')

    let inputTextBox = await driver.findElement(By.id('keys'))

    await driver.executeScript('arguments[0].focus()', inputTextBox)

    const actions = driver.actions().keyDown('a').keyDown('b').getSequences()

    await input.perform(browsingContextId, actions)

    await driver.executeScript('resetEvents()')

    await input.release(browsingContextId)

    const events = await driver.executeScript('return allEvents.events')

    assert.strictEqual(events[0].code, 'KeyB')
    assert.strictEqual(events[1].code, 'KeyA')
  })
})
```

```java
        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ActionsTest.java#L59-L65)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ActionsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Input;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.interactions.Actions;

class ActionsTest extends BaseTest {
    private Input input;

    private String windowHandle;

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        windowHandle = driver.getWindowHandle();
        input = new Input(driver);
    }

    @Test
    void canPerformInputActions() {
        driver.get("https://www.selenium.dev/selenium/web/formSelectionPage.html");

        List<WebElement> options = driver.findElements(By.tagName("option"));

        Actions actions = new Actions(driver);
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());

        WebElement showButton = driver.findElement(By.name("showselected"));
        showButton.click();

        WebElement resultElement = driver.findElement(By.id("result"));
        Assertions.assertTrue(resultElement.getText().contains("roquefort parmigiano cheddar"));
        }

    @Test
    void canPerformReleaseAction() {
        driver.get("https://www.selenium.dev/selenium/web/bidi/release_action.html");

        WebElement inputTextBox = driver.findElement(By.id("keys"));

        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);

        List<Map<String, Object>> events =
                (List<Map<String, Object>>)
                        ((JavascriptExecutor) driver).executeScript("return allEvents.events");
        Assertions.assertEquals("KeyB", events.get(0).get("code"));
        Assertions.assertEquals("KeyA", events.get(1).get("code"));
        }
    }
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await input.release(browsingContextId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/input.spec.js#L55)

##### /examples/javascript/test/bidirectional/input.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, Key, Builder} = require("selenium-webdriver")
const Input = require('selenium-webdriver/bidi/input')

describe('Input module', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can perform input action', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/formSelectionPage.html')

    let options = await driver.findElements(By.tagName('option'))

    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)

    let showButton = await driver.findElement(By.name('showselected'))
    showButton.click()

    let resultElement = await driver.findElement(By.id('result'))
    await resultElement.getText().then(function (text) {
      assert(text.includes('oquefort parmigiano cheddar'), `text is: ${text}`)
    })
  })

  it('can execute release in browsing context', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/bidi/release_action.html')

    let inputTextBox = await driver.findElement(By.id('keys'))

    await driver.executeScript('arguments[0].focus()', inputTextBox)

    const actions = driver.actions().keyDown('a').keyDown('b').getSequences()

    await input.perform(browsingContextId, actions)

    await driver.executeScript('resetEvents()')

    await input.release(browsingContextId)

    const events = await driver.executeScript('return allEvents.events')

    assert.strictEqual(events[0].code, 'KeyB')
    assert.strictEqual(events[1].code, 'KeyA')
  })
})
```

[Add Example](/documentation/about/contributing/#creating-examples)

# 3 - Network

```java
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L36-L38)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    assert.notEqual(intercept, null)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L29)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L46-L50)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L34-L35)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                    responseDetails ->
                            network.continueWithAuth(
                                    responseDetails.getRequest().getRequestId(),
                                    new UsernameAndPassword("admin", "admin")));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L57-L64)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L42-L46)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                            // Does not handle the alert
                            network.continueWithAuthNoCredentials(responseDetails.getRequest().getRequestId()));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L74-L80)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L56-L60)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                            network.cancelAuth(responseDetails.getRequest().getRequestId()));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L90-L96)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L71-L75)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
            }
    }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L104-L108)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L30-L35)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L23-L29)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L45-L51)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L82-L88)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L62-L68)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L96-L102)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L101-L106)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

# 4 - Script

```java
        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));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L52-L75)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L32-L53)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L201-L210)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L202-L204)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L219-L229)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L222-L227)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L239-L242)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L237-L239)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L280-L283)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L279-L283)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L293-L299)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L292-L299)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            script.disownBrowsingContextScript(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L322-L322)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    await manager.disownBrowsingContextScript(id, boxId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L330-L330)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            script.disownRealmScript(realmId, List.of(boxId));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L375-L375)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    await manager.disownRealmScript(realmId, boxId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L372-L372)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L391-L392)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L383-L385)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L401-402)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L393-L395)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L411-412)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L403-L405)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L422-423)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L416-L416)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L463-463)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L424-L426)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
                script.removePreloadScript(id);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L486-486)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    await manager.removePreloadScript(scriptId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L471-L471)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L37-L51)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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,
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L26-L43)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L58-L68)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L52-L65)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L75-L85)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.19](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.19.0)

```js
    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()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L73-L86)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

[Add Example](/documentation/about/contributing/#creating-examples)

# 5 - BiDirectional API (W3C compliant)

```java
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L33-L39)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/logInspector.spec.js#L23-37)

##### /examples/javascript/test/bidirectional/logInspector.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const LogInspector = require('selenium-webdriver/bidi/logInspector');
const {Builder} = require("selenium-webdriver");


describe('Log Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test listen to console log', async function () {
    let logEntry = null
    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)

    await inspector.close()
  })

  it('test listen to javascript error log', async function () {
    let logEntry = null
    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')

    await inspector.close()
  })

  it('test retrieve stack trace for a log', async function () {
    let logEntry = null
    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()

    const stackTrace = logEntry.stackTrace
    assert.notEqual(stackTrace, null)
    assert.equal(stackTrace.callFrames.length, 3)

    await inspector.close()
  })

  it('test listen to logs with multiple consumers', async function () {
    let logEntry1 = null
    let logEntry2 = null
    const inspector = await LogInspector(driver)
    await inspector.onJavascriptException(function (log) {
      logEntry1 = log
    })
    await inspector.onJavascriptException(function (log) {
      logEntry2 = log
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    await driver.findElement({id: 'jsException'}).click()

    assert.equal(logEntry1.text, 'Error: Not working')
    assert.equal(logEntry1.type, 'javascript')
    assert.equal(logEntry1.level, 'error')

    assert.equal(logEntry2.text, 'Error: Not working')
    assert.equal(logEntry2.type, 'javascript')
    assert.equal(logEntry2.level, 'error')

    await inspector.close()
  })
})
```

```java
            logInspector.onJavaScriptException(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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L73-L78)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/logInspector.spec.js#L44-54)

##### /examples/javascript/test/bidirectional/logInspector.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const LogInspector = require('selenium-webdriver/bidi/logInspector');
const {Builder} = require("selenium-webdriver");


describe('Log Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test listen to console log', async function () {
    let logEntry = null
    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)

    await inspector.close()
  })

  it('test listen to javascript error log', async function () {
    let logEntry = null
    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')

    await inspector.close()
  })

  it('test retrieve stack trace for a log', async function () {
    let logEntry = null
    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()

    const stackTrace = logEntry.stackTrace
    assert.notEqual(stackTrace, null)
    assert.equal(stackTrace.callFrames.length, 3)

    await inspector.close()
  })

  it('test listen to logs with multiple consumers', async function () {
    let logEntry1 = null
    let logEntry2 = null
    const inspector = await LogInspector(driver)
    await inspector.onJavascriptException(function (log) {
      logEntry1 = log
    })
    await inspector.onJavascriptException(function (log) {
      logEntry2 = log
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    await driver.findElement({id: 'jsException'}).click()

    assert.equal(logEntry1.text, 'Error: Not working')
    assert.equal(logEntry1.type, 'javascript')
    assert.equal(logEntry1.level, 'error')

    assert.equal(logEntry2.text, 'Error: Not working')
    assert.equal(logEntry2.type, 'javascript')
    assert.equal(logEntry2.level, 'error')

    await inspector.close()
  })
})
```

```java
            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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L55-L60)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

----
url: https://www.selenium.dev/documentation/test_practices/encouraged/consider_using_a_fluent_api/
----

# Consider using a fluent API

Martin Fowler coined the term [“Fluent API”](//www.martinfowler.com/bliki/FluentInterface.html). Selenium already implements something like this in their `FluentWait` class, which is meant as an alternative to the standard `Wait` class. You could enable the Fluent API design pattern in your page object and then query the Google search page with a code snippet like this one:

```java
driver.get( "http://www.google.com/webhp?hl=en&amp;tab=ww" );
GoogleSearchPage gsp = new GoogleSearchPage(driver);
gsp.setSearchString().clickSearchButton();
```

The Google page object class with this fluent behavior might look like this:

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

public class GoogleSearchPage extends BasePage {
    public GoogleSearchPage(WebDriver driver) {
        super(driver);
        // Generally do not assert within pages or components.
        // Effectively throws an exception if the lambda condition is not met.
        new WebDriverWait(driver, Duration.ofSeconds(3)).until(d -> d.findElement(By.id("logo")));
    }

    public GoogleSearchPage setSearchString(String sstr) {
        driver.findElement(By.id("gbqfq")).sendKeys(sstr);
        return this;
    }

    public void clickSearchButton() {
        driver.findElement(By.id("gbqfb")).click();
    }
}
```

Last modified May 17, 2023: [Consider Using a Fluent API - Fix usage (#1378) (332da70d909)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/332da70d90970623288d2e98fbcff098b7812995)

----
url: https://www.selenium.dev/pt-br/documentation/legacy/selenium_3/
----

# Selenium 3

Selenium 3 was the implementation of WebDriver without the Selenium RC Code. It has since been replaced with Selenium 4, which implements the W3C WebDriver specification.

***

##### [Grid 3](/pt-br/documentation/legacy/selenium_3/grid_3/)

Selenium Grid 3 supported WebDriver without Selenium RC code. Grid 3 was completely rewritten for the new Grid 4.

##### [Configurando a sua](/pt-br/documentation/legacy/selenium_3/grid_setup/)

Quick start guide for setting up Grid 3.

##### [Componentes](/pt-br/documentation/legacy/selenium_3/grid_components/)

Description of Hub and Nodes for Grid 3.

----
url: https://www.selenium.dev/documentation/legacy/developers/buck/
----

# Buck Build Tool

Buck is a build tool from Facebook that we were working with to replace Crazy fun. We have since replaced it with [Bazel](https://bazel.build/).

This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/Buck)\
You can read the documentation for the legacy [Crazy Fun Build tool](https://www.selenium.dev/documentation/legacy/developers/crazy_fun_build/).

## Building Selenium with Buck

The easiest thing to do is to just run “./go”. The build process will download the right version of Buck for you so long as there’s no `.nobuckcheck` file in the root of the project. The download ends up in `buck-out/crazy-fun/HASH/buck.pex` where `HASH` is the value of the current buck version (given in the `.buckversion` file in the root of the project.

If you’d like to build and run our fork of Buck, then:

```
git clone https://github.com/SeleniumHQ/buck.git
cd buck && ant
export PATH=`pwd`/bin:$PATH
cd ~/src/selenium 
buck build chrome firefox htmlunit remote leg-rc
buck test --all
```

## Updating the `buck.pex`

Should you need to update the version of Buck that is downloaded:

* Checkout the source to Buck and build the PEX: `buck build --show-output buck`
* Figure out the git hash of the version you’ve just built. Normally that’ll be the HEAD of master. Put that full hash into the `.buckversion` of the main selenium project.
* Put the md5 hash of the PEX into the `.buckhash` file in the main selenium project.
* Create a new release of SeleniumHQ’s Buck fork on GitHub. The name is `buck-release-$VERSION`, where $VERSION is whatever’s in `.buckversion` in the main selenium project.
* Upload the PEX to the release, and make the release public.
* Commit the changes to the main selenium project and push them.

----
url: https://www.selenium.dev/ja/documentation/overview/components/
----

# コンポーネントを理解する

最終更新 October 29, 2025: [Robotium does not support natural language features. Robot Framework … (#2508) (9667de56d4f)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/9667de56d4f85dfa29d81741893570c0b7ae4cdd)

----
url: https://www.selenium.dev/ja/documentation/about/contributing/
----

# Seleniumのサイトとドキュメントに貢献する

Seleniumのドキュメントとコード例を改善するための情報

Seleniumは大きなソフトウェアプロジェクトであり、そのサイトとドキュメントは、物事の仕組みを理解し、その可能性を活用する効果的な方法を学ぶための鍵となります。

このプロジェクトには、Seleniumのサイトとドキュメントの両方が含まれています。これは、Seleniumを効果的に使用する方法、Seleniumに参加する方法、およびSeleniumに貢献する方法に関する最新情報を提供するための継続的な取り組みです（特定のリリースを対象としていません）。

サイトおよびドキュメントへの貢献は、以下のセクションで説明されているプロセスに従います。

***

```
    {{< tab header="Ruby" >}}
    {{< gh-codeblock path="/examples/ruby/spec/browsers/chrome_spec.rb#L8-L9" >}}
    {{< /tab >}}
```

```shell
% git clone git@github.com:seleniumhq/seleniumhq.github.io.git
% cd seleniumhq.github.io
```

#### 依存関係: Hugo

[Hugo](https://gohugo.io/)と[Docsyテーマ](https://www.docsy.dev/)を使用してサイトの構築とレンダリングをしています。このサイトの作業をするには、Hugoバイナリの“拡張”Sass/SCSSバージョンが必要です。Hugo 0.148.2の使用を推奨します。

[Docsyのインストール手順](https://www.docsy.dev/docs/getting-started/#install-hugo)に従ってください。

### ステップ 2: ブランチの作成

フィーチャーブランチを作成し、ハックを開始します。:

```shell
% git checkout -b my-feature-branch
```

我々はHEADベースの開発を行っています。つまり、全ての変更はtrunkブランチ上に直接適用されます。

### ステップ 3: 変更を加える

リポジトリにはサイトとドキュメントが含まれています。 変更を加える前に、submoduleを初期化し、必要な依存関係をインストールしてください（以下のコマンドを参照）。サイトに変更を加えるには、`website_and_docs` ディレクトリで作業してください。変更のライブプレビューを確認するには、サイトのルートディレクトリで `hugo server`を実行してください。

```shell
% git submodule update --init --recursive
% cd website_and_docs
% hugo server
```

寄稿に関する規約の詳細については、 [スタイルガイド](https://www.selenium.dev/ja/documentation/about/style/) をご覧ください。

### ステップ 4: コミット

まず、gitがあなたの名前とメールアドレスを知っていることを確認してください:

```shell
% git config --global user.name 'Santa Claus'
% git config --global user.email 'santa@example.com'
```

\*\*適切なコミットメッセージを書くことは重要です。\*\*コミットメッセージには、変更された内容、理由、修正されたイシューへの参照（ある場合）を記述する必要があります。作成するときは、次のガイドラインに従ってください。:

1. 最初の行は約50文字以下で、変更の簡単な説明を含める必要があります。
2. 2行目は空白のままにします。
3. 他のすべての行を72列で折り返します。
4. `Fixes #N`を含めてください。ここでは *N* がこのコミットで修正したイシュー番号です（存在する場合）。

適切なコミットメッセージは次のようになります:

```text
explain commit normatively in one line

Body of commit message is a few lines of text, explaining things
in more detail, possibly giving some background about the issue
being fixed, etc.

The body of the commit message can be several paragraphs, and
please do proper word-wrap and keep columns shorter than about
72 characters or so. That way `git log` will show things
nicely even when it is indented.

Fixes #141
```

最初の行は`git shortlog`や`git log --oneline`を実行した際に他人が最初に目にするため、意味のあるものでなければなりません。

### ステップ 5: リベース

あなたの作業を同期するため、(`git merge`ではなく)`git rebase`を時々実行してください。

```shell
% git fetch origin
% git rebase origin/trunk
```

### ステップ 6: テスト

あなたの変更が何も問題を起こしていないことを確認するため、常に忘れずに[ローカルサーバーの実行](https://gohugo.io/getting-started/usage/#livereload)を行ってください。

### ステップ 7: プッシュ

```shell
% git push origin my-feature-branch
```

<https://github.com/yourusername/seleniumhq.github.io.git> を開き、\_Pull Request\_を押し、フォームを入力してください。 **CLAに署名したことを示してください** (ステップ7を参照)

プルリクエストは通常数日以内にレビューされます。対応すべきコメントがある場合は、新しく(できれば [fixups](http://git-scm.com/docs/git-commit)で)コミットし、同じブランチにプッシュしてください。

### ステップ 8: 統合

コードレビューが完了すると、コミッターがPRを取得し、リポジトリのtrunkブランチに統合します。 マスターブランチで履歴を線形に保持するのが好きなので、通常はブランチの履歴をスカッシュしてリベースします。

## コミュニケーション

プロジェクトのコントリビューターおよびコミュニティ全体と交流する方法については、全て <https://selenium.dev/support> で詳細が記載されています。

最終更新 November 4, 2025: [added information about web examples for english document (#2492) (4dc5f22359d)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/4dc5f22359dfceb83b43afb473ca2ef7882abd19)

----
url: https://www.selenium.dev/ja/documentation/webdriver/actions_api/keyboard/
----

# Keyboard actions

```java
        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L17-L20)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L10-L13)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L13-L16)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L17-L20)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L19-L22)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L30-L35)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L21-L26)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L30-L35)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L25-L30)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L32-L37)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L32-L37)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .sendKeys("abc")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L45-L47)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L34-L36)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs

            new Actions(driver)
                .SendKeys("abc")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L45-L47)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .send_keys('abc')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L39-L41)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .sendKeys('abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L48-L50)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .sendKeys("abc")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L47-L49)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L59-L62)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L45-L48)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L58-L61)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L51-L54)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L59-L63)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L60-L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L70-L84)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L56-L67)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L72-L82)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L64-L74)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L73-L85)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L74-L86)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

----
url: https://www.selenium.dev/ja/documentation/webdriver/bidi/
----

# 双方向機能

BiDirectional means that communication is happening in two directions simultaneously. The traditional WebDriver model involves strict request/response commands which only allows for communication to happen in one direction at any given time. In most cases this is what you want; it ensures that the browser is doing the expected things in the right order, but there are a number of interesting things that can be done with asynchronous interactions.

This functionality is currently available in a limited fashion with the \[Chrome DevTools Protocol] (CDP), but to address some of its drawbacks, the Selenium team, along with the major browser vendors, have worked to create the new [WebDriver BiDi Protocol](https://w3c.github.io/webdriver-bidi/). This specification aims to create a stable, cross-browser API that leverages bidirectional communication for enhanced browser automation and testing functionality, including streaming events from the user agent to the controlling software via WebSockets. Users will be able to listen for and record or manipulate events as they happen during the course of a Selenium session.

### Enabling BiDi in Selenium

In order to use WebDriver BiDi, setting the capability in the browser options will enable the required functionality:

*
*
*
*
*
*

```java
options.setCapability("webSocketUrl", true);
```

```python
options.enable_bidi = True
```

```csharp
UseWebSocketUrl = true,
```

```ruby
options.web_socket_url = true
```

```javascript
Options().enableBidi();
```

```kotlin
options.setCapability("webSocketUrl", true);
```

This enables the WebSocket connection for bidirectional communication, unlocking the full potential of the WebDriver BiDi protocol.

Note that Selenium is updating its entire implementation from WebDriver Classic to WebDriver BiDi (while maintaining backwards compatibility as much as possible), but this section of documentation focuses on the new functionality that bidirectional communication allows. The low-level BiDi domains will be accessible in the code to the end user, but the goal is to provide high-level APIs that are straightforward methods of real-world use cases. As such, the low-level components will not be documented, and this section will focus only on the user-friendly features that we encourage users to take advantage of.

If there is additional functionality you’d like to see, please raise a [feature request](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=\&template=feature.md).

***

##### [WebDriver BiDi Logging Features](/ja/documentation/webdriver/bidi/logging/)

These features are related to logging. Because “logging” can refer to so many different things, these methods are made available via a “script” namespace.

##### [WebDriver BiDi Network Features](/ja/documentation/webdriver/bidi/network/)

These features are related to networking, and are made available via a “network” namespace.

##### [WebDriver BiDi Script Features](/ja/documentation/webdriver/bidi/script/)

These features are related to scripts, and are made available via a “script” namespace.

##### [Chrome DevTools Protocol](/ja/documentation/webdriver/bidi/cdp/)

Examples of working with Chrome DevTools Protocol in Selenium. CDP support is temporary until WebDriver BiDi has been implemented.

##### [BiDirectional API (W3C compliant)](/ja/documentation/webdriver/bidi/w3c/)

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/encouraged/page_object_models/
----

# PO设计模式

```java
/***
 * Tests login feature
 */
public class Login {

  public void testLogin() {
    // fill login data on sign-in page
    driver.findElement(By.name("user_name")).sendKeys("userName");
    driver.findElement(By.name("password")).sendKeys("my supersecret password");
    driver.findElement(By.name("sign-in")).click();

    // verify h1 tag is "Hello userName" after login
    driver.findElement(By.tagName("h1")).isDisplayed();
    assertThat(driver.findElement(By.tagName("h1")).getText(), is("Hello userName"));
  }
}
```

There are two problems with this approach.

* There is no separation between the test method and the AUT’s locators (IDs in this example); both are intertwined in a single method. If the AUT’s UI changes its identifiers, layout, or how a login is input and processed, the test itself must change.
* The ID-locators would be spread in multiple tests, in all tests that had to use this login page.

Applying the page object model, this example could be rewritten like this in the following example of a page object for a Sign-in page.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Sign-in page.
 */
public class SignInPage {
  protected WebDriver driver;

  // <input name="user_name" type="text" value="">
  private By usernameBy = By.name("user_name");
  // <input name="password" type="password" value="">
  private By passwordBy = By.name("password");
  // <input name="sign_in" type="submit" value="SignIn">
  private By signinBy = By.name("sign_in");

  public SignInPage(WebDriver driver){
    this.driver = driver;
     if (!driver.getTitle().equals("Sign In Page")) {
      throw new IllegalStateException("This is not Sign In Page," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Login as valid user
    *
    * @param userName
    * @param password
    * @return HomePage object
    */
  public HomePage loginValidUser(String userName, String password) {
    driver.findElement(usernameBy).sendKeys(userName);
    driver.findElement(passwordBy).sendKeys(password);
    driver.findElement(signinBy).click();
    return new HomePage(driver);
  }
}
```

and page object for a Home page could look like this.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Home Page
 */
public class HomePage {
  protected WebDriver driver;

  // <h1>Hello userName</h1>
  private By messageBy = By.tagName("h1");

  public HomePage(WebDriver driver){
    this.driver = driver;
    if (!driver.getTitle().equals("Home Page of logged in user")) {
      throw new IllegalStateException("This is not Home Page of logged in user," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Get message (h1 tag)
    *
    * @return String message text
    */
  public String getMessageText() {
    return driver.findElement(messageBy).getText();
  }

  public HomePage manageProfile() {
    // Page encapsulation to manage profile functionality
    return new HomePage(driver);
  }
  /* More methods offering the services represented by Home Page
  of Logged User. These methods in turn might return more Page Objects
  for example click on Compose mail button could return ComposeMail class object */
}
```

So now, the login test would use these two page objects as follows.

```java
/***
 * Tests login feature
 */
public class TestLogin {

  @Test
  public void testLogin() {
    SignInPage signInPage = new SignInPage(driver);
    HomePage homePage = signInPage.loginValidUser("userName", "password");
    assertThat(homePage.getMessageText(), is("Hello userName"));
  }

}
```

```html
<!-- Products Page -->
<div class="header_container">
    <span class="title">Products</span>
</div>

<div class="inventory_list">
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
</div>
```

Each product is a component of the Products page.

```html
<!-- Inventory Item -->
<div class="inventory_item">
    <div class="inventory_item_name">Backpack</div>
    <div class="pricebar">
        <div class="inventory_item_price">$29.99</div>
        <button id="add-to-cart-backpack">Add to cart</button>
    </div>
</div>
```

The Products page HAS-A list of products. This object relationship is called Composition. In simpler terms, something is *composed of* another thing.

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

// Page Object
public class ProductsPage extends BasePage {
    public ProductsPage(WebDriver driver) {
        super(driver);
        // No assertions, throws an exception if the element is not loaded
        new WebDriverWait(driver, Duration.ofSeconds(3))
            .until(d -> d.findElement(By.className​("header_container")));
    }

    // Returning a list of products is a service of the page
    public List<Product> getProducts() {
        return driver.findElements(By.className​("inventory_item"))
            .stream()
            .map(e -> new Product(e)) // Map WebElement to a product component
            .toList();
    }

    // Return a specific product using a boolean-valued function (predicate)
    // This is the behavioral Strategy Pattern from GoF
    public Product getProduct(Predicate<Product> condition) {
        return getProducts()
            .stream()
            .filter(condition) // Filter by product name or price
            .findFirst()
            .orElseThrow(() -> new RuntimeException("Product not found")); // Error thrown during actual test run
    }
}
```

The Product component object is used inside the Products page object.

```java
public abstract class BaseComponent {
    protected WebElement root;

    public BaseComponent(WebElement root) {
        this.root = root;
    }
}

// Page Component Object
public class Product extends BaseComponent {
    // The root element contains the entire component
    public Product(WebElement root) {
        super(root); // inventory_item
    }

    public String getName() {
        // Locating an element begins at the root of the component
        return root.findElement(By.className("inventory_item_name")).getText();
    }

    public BigDecimal getPrice() {
        return new BigDecimal(
                root.findElement(By.className("inventory_item_price"))
                    .getText()
                    .replace("$", "")
            ).setScale(2, RoundingMode.UNNECESSARY); // Sanitation and formatting
    }

    public void addToCart() {
        root.findElement(By.id("add-to-cart-backpack")).click();
    }
}
```

So now, the products test would use the page object and the page component object as follows.

```java
public class ProductsTest {
    @Test
    public void testProductInventory() {
        var productsPage = new ProductsPage(driver); // page object
        var products = productsPage.getProducts();
        assertEquals(6, products.size()); // expected, actual
    }
    
    @Test
    public void testProductPrices() {
        var productsPage = new ProductsPage(driver);

        // Pass a lambda expression (predicate) to filter the list of products
        // The predicate or "strategy" is the behavior passed as parameter
        var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); // page component object
        var bikeLight = productsPage.getProduct(p -> p.getName().equals("Bike Light"));

        assertEquals(new BigDecimal("29.99"), backpack.getPrice());
        assertEquals(new BigDecimal("9.99"), bikeLight.getPrice());
    }
}
```

```java
public class LoginPage {
    public HomePage loginAs(String username, String password) {
        // ... clever magic happens here
    }
    
    public LoginPage loginAsExpectingError(String username, String password) {
        //  ... failed login here, maybe because one or both of the username and password are wrong
    }
    
    public String getErrorMessage() {
        // So we can verify that the correct error is shown
    }
}
```

The code presented above shows an important point: the tests, not the Page Objects, should be responsible for making assertions about the state of a page. For example:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    inbox.assertMessageWithSubjectIsUnread("I like cheese");
    inbox.assertMessageWithSubjectIsNotUnread("I'm not fond of tofu");
}
```

could be re-written as:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    assertTrue(inbox.isMessageWithSubjectIsUnread("I like cheese"));
    assertFalse(inbox.isMessageWithSubjectIsUnread("I'm not fond of tofu"));
}
```

```java
public class LoginPage {
    private final WebDriver driver;

    public LoginPage(WebDriver driver) {
        this.driver = driver;

        // Check that we're on the right page.
        if (!"Login".equals(driver.getTitle())) {
            // Alternatively, we could navigate to the login page, perhaps logging out first
            throw new IllegalStateException("This is not the login page");
        }
    }

    // The login page contains several HTML elements that will be represented as WebElements.
    // The locators for these elements should only be defined once.
        By usernameLocator = By.id("username");
        By passwordLocator = By.id("passwd");
        By loginButtonLocator = By.id("login");

    // The login page allows the user to type their username into the username field
    public LoginPage typeUsername(String username) {
        // This is the only place that "knows" how to enter a username
        driver.findElement(usernameLocator).sendKeys(username);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to type their password into the password field
    public LoginPage typePassword(String password) {
        // This is the only place that "knows" how to enter a password
        driver.findElement(passwordLocator).sendKeys(password);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to submit the login form
    public HomePage submitLogin() {
        // This is the only place that submits the login form and expects the destination to be the home page.
        // A seperate method should be created for the instance of clicking login whilst expecting a login failure. 
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the login page ever
        // go somewhere else (for example, a legal disclaimer) then changing the method signature
        // for this method will mean that all tests that rely on this behaviour won't compile.
        return new HomePage(driver);	
    }

    // The login page allows the user to submit the login form knowing that an invalid username and / or password were entered
    public LoginPage submitLoginExpectingFailure() {
        // This is the only place that submits the login form and expects the destination to be the login page due to login failure.
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the user ever be navigated to the home page after submiting a login with credentials 
        // expected to fail login, the script will fail when it attempts to instantiate the LoginPage PageObject.
        return new LoginPage(driver);	
    }

    // Conceptually, the login page offers the user the service of being able to "log into"
    // the application using a user name and password. 
    public HomePage loginAs(String username, String password) {
        // The PageObject methods that enter username, password & submit login have already defined and should not be repeated here.
        typeUsername(username);
        typePassword(password);
        return submitLogin();
    }
}
```

最后修改 October 30, 2025: [docs: improve consistency and readability of the guide (#2168) (708f32f0c58)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/708f32f0c58c2386be472aec8b74801183f6743a)

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/encouraged/fresh_browser_per_test/
----

# Navegador novo por teste

Comece cada teste a partir de um estado limpo conhecido. Idealmente, ligue uma nova máquina virtual para cada teste. Se ligar uma nova máquina virtual não for prático, pelo menos inicie um novo WebDriver para cada teste. Most browser drivers like GeckoDriver and ChromeDriver will start with a clean known state with a new user profile, by default.

```java
WebDriver driver = new FirefoxDriver();
```

Última modificação July 28, 2022: [Fixes #927 (#1090) (e9323eb4d1e)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e9323eb4d1ea06146209479a8e1126da5487f651)

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/discouraged/
----

# Piores práticas

Temas a evitar quando automatizar navegadores com Selenium.

***

##### [Captchas](/pt-br/documentation/test_practices/discouraged/captchas/)

##### [Downloads de arquivo](/pt-br/documentation/test_practices/discouraged/file_downloads/)

##### [Códigos de respostas HTTP](/pt-br/documentation/test_practices/discouraged/http_response_codes/)

##### [Login via Gmail, email e Facebook](/pt-br/documentation/test_practices/discouraged/gmail_email_and_facebook_logins/)

##### [Dependência entre testes](/pt-br/documentation/test_practices/discouraged/test_dependency/)

##### [Teste de performance/desempenho](/pt-br/documentation/test_practices/discouraged/performance_testing/)

##### [Navegação por links](/pt-br/documentation/test_practices/discouraged/link_spidering/)

##### [Autenticação de Dois Fatores (2FA)](/pt-br/documentation/test_practices/discouraged/two_factor_authentication/)

----
url: https://www.selenium.dev/ja/documentation/webdriver/bidi/cdp/network/
----

```java
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L41-L43)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
        credentials = base64.b64encode("admin:admin".encode()).decode()
        auth = {'authorization': 'Basic ' + credentials}
        await connection.session.execute(connection.devtools.network.set_extra_http_headers(Headers(auth)))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L13-15)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L25-L32)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L9-L11)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      HttpResponse res = next.execute(req);
                      contentType.add(res.getHeader("Content-Type"));
                      return res;
                    })) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L56-L65)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L46-L51)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L20-L24)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    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!"))))) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L75-L85)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L62-L73)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L31-L35)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L97-L110)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L85-L97)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    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
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L42-L46)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L125-L126)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    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())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L26-L28)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L114-L118)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L56-L57)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    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()));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L142-L157)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L37-L44)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L136-L143)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L68-L71)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    devTools.send(
            Browser.setDownloadBehavior(
                    Browser.SetDownloadBehaviorBehavior.ALLOWANDNAME,
                    Optional.empty(),
                    Optional.of(""),
                    Optional.of(true)));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L171-L176)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    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
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L82-L88)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/discouraged/test_dependency/
----

# Dependência entre testes

Uma ideia comum e um equívoco sobre o teste automatizado é sobre uma ordem de testes específica. Seus testes devem ser executados em **qualquer** ordem, e não depender da conclusão de outros testes para ter sucesso.

----
url: https://www.selenium.dev/zh-cn/documentation/grid/advanced_features/endpoints/
----

# Grid端点

## Grid

### Grid 状态

Grid状态提供Grid的当前状态. 它包含每个注册节点的详细信息. 对于每个节点, 状态包括有关节点可用性、会话和插槽的信息.

```shell
curl --request GET 'http://localhost:4444/status'
```

### 删除会话

删除会话会终止 WebDriver 会话、退出驱动程序并将其从活动会话映射中删除。任何使用删除的会话标识或重新使用驱动程序实例的请求都会出错。

```shell
curl --request DELETE 'http://localhost:4444/session/<session-id>'
```

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret> '
```

在完全分布式模式下, URL是分发器的地址。

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

如果在设置Grid时未配置注册密码, 则使用

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET;'
```

### 释放节点

节点释放命令用于优雅地关闭节点。在所有正在进行的会话结束后，会停止该节点。并且，它不会接受任何新的会话请求。

在 Standalone 模式下，分发器 URL 是独立服务器地址。

在 Hub-Node 模式下, 分发器 URL 是 Hub 服务器的地址。

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret> '
```

在完全分布式模式下, URL是分发服务器的地址。

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

如果在设置Grid时未配置注册密码, 则使用

```shell
curl --request POST 'http://<Router-URL>/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET;'
```

## 节点

本节中的端点适用于 Hub-Node 模式和节点独立运行的完全分布式网格模式。在一个节点的情况下, 默认节点的URL为 http\://localhost:5555 。 如果有多个节点,请使用 [Grid 状态](/zh-cn/documentation/grid/advanced_features/endpoints/#grid-%e7%8a%b6%e6%80%81) 获取所有节点的详细信息并查找节点地址。

### 状态

节点状态本质上是节点的健康检查。分发程序会定期 ping 节点状态，并相应地更新 Grid 模型。状态包括有关可用性、会话和插槽的信息。

```shell
curl --request GET 'http://localhost:5555/status'
```

### 释放

分发器将 [释放](/zh-cn/documentation/grid/advanced_features/endpoints/#%e9%87%8a%e6%94%be%e8%8a%82%e7%82%b9) 命令传递给由node-id标识的相应节点。要直接释放节点,请使用下面列出的curl命令。 两个端点都有效并产生相同的结果。释放会等待持续中的会话完成后才停止节点。

```shell
curl --request POST 'http://localhost:5555/se/grid/node/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

如果在设置Grid时未配置注册密码,则使用

```shell
curl --request POST 'http://<node-URL>/se/grid/node/drain' --header 'X-REGISTRATION-SECRET;'
```

### 检查会话所有者

要检查会话是否属于某一节点, 请使用下面列出的curl命令.

```shell
curl --request GET 'http://localhost:5555/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

如果在设置Grid时未配置注册密码, 则使用

```shell
curl --request GET 'http://<node-URL>/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

如果会话属于该节点, 则返回true, 否则返回false。

### 删除会话

删除会话会终止 WebDriver 会话、退出驱动程序并将其从活动会话映射中删除。任何使用删除的会话标识或重新使用驱动程序实例的请求都会出错。

```shell
curl --request DELETE 'http://localhost:5555/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

如果在设置Grid时未配置注册密码, 则使用

```shell
curl --request DELETE 'http://<node-URL>/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

## 新会话队列

### 清除新会话队列

新会话请求队列保存新会话请求。要清除队列，请使用下面列出的 curl 命令。清除队列会拒绝队列中的所有请求。对于每个此类请求，服务器都会向相应的客户端返回错误响应。清除命令的结果是被删除请求的总数。

在 Standalone 模式下, 队列URL是独立服务器的地址。 在 Hub-Node 模式下, 队列URL是集线器服务器的地址。

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

在完全分布式模式下, 队列URL是新会话队列服务器的地址。

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

如果在设置Grid时未配置注册密码, 则使用

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET;'
```

### 获取新会话队列请求

新会话请求队列保存新会话请求。 要获取队列中的当前请求, 请使用下面列出的curl命令。 响应会返回队列中的请求总数以及请求内容。

在 Standalone 模式下, 队列URL是独立服务器的地址。 在 Hub-Node 模式下, 队列URL是集线器服务器的地址。

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

在完全分布式模式下, 队列URL是新会话队列服务器的地址。

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

----
url: https://www.selenium.dev/ja/documentation/test_practices/
----

# テストの実践

Seleniumプロジェクトからのテストに関するいくつかのガイドラインと推奨事項

「ベストプラクティス」に関するメモ：このドキュメントでは、“ベストプラクティス"というフレーズを意図的に避けています。 すべての状況に有効なアプローチはありません。 “ガイドラインとレコメンデーション"というアイデアを好みます。 これらを一通り読み、特定の環境でどのアプローチが効果的かを慎重に決定することをお勧めします。

機能テストは、多くの理由で適切に行うのが困難です。 まるでアプリケーションの状態、複雑さ、および依存関係が、テストを十分に難しくしないと思えるほど、ブラウザ（特にクロスブラウザの非互換性）を扱うのは、良いテストの作成を難しくします。

Seleniumは、機能的なユーザーインタラクションを簡単にするツールを提供しますが、適切に設計されたテストスイートの作成には役立ちません。 この章では、機能的なWebページの自動化に取り組む方法に関するアドバイス、ガイドライン、および推奨事項を提供します。

この章では、長年にわたって成功を収めてきたSeleniumの多くのユーザーの間で人気のあるソフトウェア設計パターンを記録します。

***

##### [デザインパターンと開発戦略](/ja/documentation/test_practices/design_strategies/)

##### [テスト自動化について](/ja/documentation/test_practices/overview/)

##### [テストの種類](/ja/documentation/test_practices/testing_types/)

##### [推奨された行動](/ja/documentation/test_practices/encouraged/)

Seleniumプロジェクトからのテストに関するいくつかのガイドラインと推奨事項

##### [推奨されない行動](/ja/documentation/test_practices/discouraged/)

Seleniumでブラウザを自動化するときに避けるべきこと。

----
url: https://www.selenium.dev/pt-br/_print/documentation/grid/configuration/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/grid/configuration/).

# Configurando componentes

Leia aqui como pode configurar cada um dos componentes Grid com base em valores comuns ou específicos para o componente.

* 1: [Ajuda de configuração](#pg-87c07f7cc7b198a46952084fd2e170cb)
* 2: [Opções CLI](#pg-fb1445fa9df303a9961b39fa99116b7a)
* 3: [Toml Options](#pg-b112688e72f40f34b417d747cee9d825)

# 1 - Ajuda de configuração

```shell
java -jar selenium-server-<version>.jar info config
```

### Segurança

Para obter detalhes em como configurar os servidores Grid para comunicação segura e para o registo de **Nodes**:

```shell
java -jar selenium-server-<version>.jar info security
```

### Configuração Session Map

Por omissão, a Grid usa um `local session map` para armazenar informação de sessões. A Grid permite armazenamento opcional em Redis ou bancos de dados JDBC SQL. Para obter informação de como usar, use o seguinte comando:

```shell
java -jar selenium-server-<version>.jar info sessionmap
```

### Traceamento com OpenTelemetry e Jaeger

Por omissao, traceamento está activo. Para exportar e visualizar através de Jaeger, use o comando seguinte para instruções de como o efectuar:

```shell
java -jar selenium-server-<version>.jar info tracing
```

## Lista de comandos Selenium Grid

Irá mostrar todos os comandos disponíveis e também a descrição de cada um.

```shell
java -jar selenium-server-<version>.jar --config-help
```

## Comandos de ajuda para componente

Adicione `--help` após o Selenium role para obter informação específica de configuração do componente.

### Standalone

```shell
java -jar selenium-server-<version>.jar standalone --help
```

### Hub

```shell
java -jar selenium-server-<version>.jar hub --help
```

### Sessions

```shell
java -jar selenium-server-<version>.jar sessions --help
```

### New Session Queue

```shell
java -jar selenium-server-<version>.jar sessionqueue --help
```

### Distributor

```shell
java -jar selenium-server-<version>.jar distributor --help
```

### Router

```shell
java -jar selenium-server-<version>.jar router --help
```

### Node

```shell
java -jar selenium-server-<version>.jar node --help
```

# 2 - Opções CLI

Todas os detalhes das opções CLI de cada componente Grid.

Diferentes secções estão disponíveis para configurar uma Grid. Cada secção tem opções que podem ser configuradas através de opções CLI.

Pode ver abaixo um mapeamento entre o componente e a secção respectiva.

Note que esta documentação pode estar desactualizada se uma opção foi adicionada ou modificada, mas ainda não ter havido oportunidade de actualizar a documentação. Caso depare com esta situação, verifique a secção [“ajuda de configuração”](https://www.selenium.dev/pt-br/documentation/grid/configuration/help/) e esteja à vontade para nos enviar um pull request com alterações a esta página.

## Secções

|                               | Standalone | Hub | Node | Distributor | Router | Sessions | SessionQueue |
| ----------------------------- | ---------- | --- | ---- | ----------- | ------ | -------- | ------------ |
| [Distributor](#distributor)   | **         | **  |      | **          | **     |          |              |
| [Docker](#docker)             | **         |     | **   |             |        |          |              |
| [Events](#events)             |            | **  | **   | **          |        | **       | **           |
| [Logging](#logging)           | **         | **  | **   | **          | **     | **       | **           |
| [Network](#network)           | **         | **  |      |             | **     |          |              |
| [Node](#node)                 | **         |     | **   |             |        |          |              |
| [Router](#router)             | **         | **  |      |             | **     |          |              |
| [Relay](#relay)               | **         |     | **   |             |        |          |              |
| [Server](#server)             | **         | **  | **   | **          | **     | **       | **           |
| [SessionQueue](#sessionqueue) | **         | **  |      | **          | **     |          | **           |
| [Sessions](#sessions)         |            |     |      | **          | **     | **       |              |

### Distributor

| Opção                          | Tipo    | Valor/Exemplo                                                       | Descrição                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ------------------------------ | ------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--healthcheck-interval`       | int     | `120`                                                               | Tempo em segundos em que se verifica o estado dos Nodes. Isto garante que o servidor consecontactar cada um dos Nodes com sucesso.                                                                                                                                                                                                                                                                                                                  |
| `--distributor`                | uri     | `http://localhost:5553`                                             | Url do Distributor.                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `--distributor-host`           | string  | `localhost`                                                         | Host onde o Distributor está à escuta.                                                                                                                                                                                                                                                                                                                                                                                                              |
| `--distributor-implementation` | string  | `org.openqa.selenium.grid.distributor.local.LocalDistributor`       | Nome completo da class para uma implementação não padrão do Distributor.                                                                                                                                                                                                                                                                                                                                                                            |
| `--distributor-port`           | int     | `5553`                                                              | Porta onde o Distributor está à escuta.                                                                                                                                                                                                                                                                                                                                                                                                             |
| `--reject-unsupported-caps`    | boolean | `false`                                                             | Permitir que o Distributor rejeite imediatamente um pedido de sessão se a Grid não suportar a capacidade pedida. Esta configuração é a ideal para Grid que não inicie Nodes a pedido.                                                                                                                                                                                                                                                               |
| `--slot-matcher`               | string  | `org.openqa.selenium.grid.data.DefaultSlotMatcher`                  | Nome completo da class para uma implementação não padrão do comparador de slots. Isto é usado para determinar se um Node pode suportar uma sessão em particular.                                                                                                                                                                                                                                                                                    |
| `--slot-selector`              | string  | `org.openqa.selenium.grid.distributor.selector.DefaultSlotSelector` | Nome completo da class para uma implementação não padrão do selector de slots. Isto é usado para selecionar um slot no Node caso tenha sido “matched”.                                                                                                                                                                                                                                                                                              |
| `--newsession-threadpool-size` | int     | `24`                                                                | The Distributor uses a fixed-sized thread pool to create new sessions as it consumes new session requests from the queue. This allows configuring the size of the thread pool. The default value is no. of available processors \* 3. Note: If the no. of threads is way greater than the available processors it will not always increase the performance. A high number of threads causes more context switching which is an expensive operation. |
| `--purge-nodes-interval`       | int     | `30`                                                                | How often, in seconds, will the Distributor purge Nodes that have been down for a while. This is calculated based on the heartbeat received from a particular node.                                                                                                                                                                                                                                                                                 |

### Docker

| Opção                       | Tipo      | Valor/Exemplo                                                     | Descrição                                                                                                                                                                                                                                                                                   |
| --------------------------- | --------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--docker-assets-path`      | string    | `/opt/selenium/assets`                                            | Absolute path where assets will be stored                                                                                                                                                                                                                                                   |
| `--docker-`                 | string\[] | `selenium/standalone-firefox:latest '{"browserName": "firefox"}'` | Docker configs which map image name to stereotype capabilities (example \`-D selenium/standalone-firefox:latest ‘{“browserName”: “firefox”}’)                                                                                                                                               |
| `--docker-devices`          | string\[] | `/dev/kvm:/dev/kvm`                                               | Exposes devices to a container. Each device mapping declaration must have at least the path of the device in both host and container separated by a colon like in this example: /device/path/in/host:/device/path/in/container                                                              |
| `--docker-host`             | string    | `localhost`                                                       | Host name where the Docker daemon is running                                                                                                                                                                                                                                                |
| `--docker-port`             | int       | `2375`                                                            | Port where the Docker daemon is running                                                                                                                                                                                                                                                     |
| `--docker-url`              | string    | `http://localhost:2375`                                           | URL for connecting to the Docker daemon                                                                                                                                                                                                                                                     |
| `--docker-video-image`      | string    | `selenium/video:latest`                                           | Docker image to be used when video recording is enabled                                                                                                                                                                                                                                     |
| `--docker-host-config-keys` | string\[] | `Dns DnsOptions DnsSearch ExtraHosts Binds`                       | Specify which docker host configuration keys should be passed to browser containers. Keys name can be found in the Docker API [documentation](https://docs.docker.com/engine/api/v1.41/#tag/Container/operation/ContainerCreate), or by running `docker inspect` the node-docker container. |

### Events

| Opção                     | Tipo    | Valor/Exemplo                                      | Descrição                                                                                                                                                                                                                                                                           |
| ------------------------- | ------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--bind-bus`              | boolean | `false`                                            | Whether the connection string should be bound or connected. When true, the component will be bound to the Event Bus (as in the Event Bus will also be started by the component, typically by the Distributor and the Hub). When false, the component will connect to the Event Bus. |
| `--events-implementation` | string  | `org.openqa.selenium.events.zeromq.ZeroMqEventBus` | Full class name of non-default event bus implementation                                                                                                                                                                                                                             |
| `--publish-events`        | string  | `tcp://*:4442`                                     | Connection string for publishing events to the event bus                                                                                                                                                                                                                            |
| `--subscribe-events`      | string  | `tcp://*:4443`                                     | Connection string for subscribing to events from the event bus                                                                                                                                                                                                                      |

### Logging

| Opção                    | Tipo    | Valor/Exemplo                                                                                                                                              | Descrição                                                                                                                                                              |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--http-logs`            | boolean | `false`                                                                                                                                                    | Enable http logging. Tracing should be enabled to log http logs.                                                                                                       |
| `--log-encoding`         | string  | `UTF-8`                                                                                                                                                    | Log encoding                                                                                                                                                           |
| `--log`                  | string  | Windows path example : `'\path\to\file\gridlog.log'` or `'C:\path\path\to\file\gridlog.log'` Linux/Unix/MacOS path example : `'/path/to/file/gridlog.log'` | File to write out logs. Ensure the file path is compatible with the operating system’s file path.                                                                      |
| `--log-level`            | string  | `“INFO”`                                                                                                                                                   | Log level. Default logging level is INFO. Log levels are described here <https://docs.oracle.com/en/java/javase/11/docs/api/java.logging/java/util/logging/Level.html> |
| `--plain-logs`           | boolean | `true`                                                                                                                                                     | Use plain log lines                                                                                                                                                    |
| `--structured-logs`      | boolean | `false`                                                                                                                                                    | Use structured logs                                                                                                                                                    |
| `--tracing`              | boolean | `true`                                                                                                                                                     | Enable trace collection                                                                                                                                                |
| `--log-timestamp-format` | string  | `HH:mm:ss.SSS`                                                                                                                                             | Allows the configure log timestamp format                                                                                                                              |

### Network

| Opção            | Tipo    | Valor/Exemplo | Descrição                                                                                                            |
| ---------------- | ------- | ------------- | -------------------------------------------------------------------------------------------------------------------- |
| `--relax-checks` | boolean | `false`       | Relax checks on origin header and content type of incoming requests, in contravention of strict W3C spec compliance. |

### Node

| Opção                            | Tipo      | Valor/Exemplo                                                                                                                                                                                                                                                              | Descrição                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |   |
| -------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - |
| `--detect-drivers`               | boolean   | `true`                                                                                                                                                                                                                                                                     | Autodetect which drivers are available on the current system, and add them to the Node.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |   |
| `--driver-configuration`         | string\[] | `display-name="Firefox Nightly" max-sessions=2 webdriver-path="/usr/local/bin/geckodriver" stereotype="{\"browserName\": \"firefox\", \"browserVersion\": \"86\", \"moz:firefoxOptions\": {\"binary\":\"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"` | List of configured drivers a Node supports. It is recommended to provide this type of configuration through a toml config file to improve readability                                                                                                                                                                                                                                                                                                                                                                                                                                                   |   |
| `--driver-factory`               | string\[] | `org.openqa.selenium.example.LynxDriverFactory '{"browserName": "lynx"}'`                                                                                                                                                                                                  | Mapping of fully qualified class name to a browser configuration that this matches against.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |   |
| `--driver-implementation`        | string\[] | `"firefox"`                                                                                                                                                                                                                                                                | Drivers that should be checked. If specified, will skip autoconfiguration.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |   |
| `--node-implementation`          | string    | `"org.openqa.selenium.grid.node.local.LocalNodeFactory"`                                                                                                                                                                                                                   | Full classname of non-default Node implementation. This is used to manage a session’s lifecycle.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |   |
| `--grid-url`                     | string    | `https://grid.example.com`                                                                                                                                                                                                                                                 | Public URL of the Grid as a whole (typically the address of the Hub or the Router)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |   |
| `--heartbeat-period`             | int       | `60`                                                                                                                                                                                                                                                                       | How often, in seconds, will the Node send heartbeat events to the Distributor to inform it that the Node is up.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |   |
| `--max-sessions`                 | int       | `8`                                                                                                                                                                                                                                                                        | Maximum number of concurrent sessions. Default value is the number of available processors.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |   |
| `--override-max-sessions`        | boolean   | `false`                                                                                                                                                                                                                                                                    | The # of available processors is the recommended max sessions value (1 browser session per processor). Setting this flag to true allows the recommended max value to be overwritten. Session stability and reliability might suffer as the host could run out of resources.                                                                                                                                                                                                                                                                                                                             |   |
| `--register-cycle`               | int       | `10`                                                                                                                                                                                                                                                                       | How often, in seconds, the Node will try to register itself for the first time to the Distributor.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |   |
| `--register-period`              | int       | `120`                                                                                                                                                                                                                                                                      | How long, in seconds, will the Node try to register to the Distributor for the first time. After this period is completed, the Node will not attempt to register again.                                                                                                                                                                                                                                                                                                                                                                                                                                 |   |
| `--session-timeout`              | int       | `300`                                                                                                                                                                                                                                                                      | Let X be the session-timeout in seconds. The Node will automatically kill a session that has not had any activity in the last X seconds. This will release the slot for other tests.                                                                                                                                                                                                                                                                                                                                                                                                                    |   |
| `--vnc-env-var`                  | string\[] | `SE_START_XVFB SE_START_VNC SE_START_NO_VNC`                                                                                                                                                                                                                               | Environment variable to check in order to determine if a vnc stream is available or not.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |   |
| `--no-vnc-port`                  | int       | `7900`                                                                                                                                                                                                                                                                     | If VNC is available, sets the port where the local noVNC stream can be obtained                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |   |
| `--drain-after-session-count`    | int       | `1`                                                                                                                                                                                                                                                                        | Drain and shutdown the Node after X sessions have been executed. Useful for environments like Kubernetes. A value higher than zero enables this feature.                                                                                                                                                                                                                                                                                                                                                                                                                                                |   |
| `--hub`                          | string    | `http://localhost:4444`                                                                                                                                                                                                                                                    | The address of the Hub in a Hub-and-Node configuration. Can be a hostname or IP address (`hostname`), in which case the Hub will be assumed to be `http://hostname:4444`, the `--grid-url` will be the same `--publish-events` will be `tcp://hostname:4442` and `--subscribe-events` will be `tcp://hostname:4443`. If `hostname` contains a port number, that will be used for `--grid-url` but the URIs for the event bus will remain the same. Any of these default values may be overridden but setting the correct flags. If the hostname has a protocol (such as `https`) that will be used too. |   |
| `--enable-cdp`                   | boolean   | `true`                                                                                                                                                                                                                                                                     | Enable CDP proxying in Grid. A Grid admin can disable CDP if the network does not allow websockets. True by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |   |
| `--enable-managed-downloads`     | boolean   | `false`                                                                                                                                                                                                                                                                    | This causes the Node to auto manage files downloaded for a given session on the Node.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |   |
| `--selenium-manager`             | boolean   | `false`                                                                                                                                                                                                                                                                    | When drivers are not available on the current system, use Selenium Manager. False by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |   |
| `--connection-limit-per-session` | int       | `10`                                                                                                                                                                                                                                                                       | Let X be the maximum number of websocket connections per session.This will ensure one session is not able to exhaust the connection limit of the host.                                                                                                                                                                                                                                                                                                                                                                                                                                                  |   |

### Relay

| Opção                        | Tipo      | Valor/Exemplo                                                                                                     | Descrição                                                                                                                                                                |
| ---------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--service-url`              | string    | `http://localhost:4723`                                                                                           | URL for connecting to the service that supports WebDriver commands like an Appium server or a cloud service.                                                             |
| `--service-host`             | string    | `localhost`                                                                                                       | Host name where the service that supports WebDriver commands is running                                                                                                  |
| `--service-port`             | int       | `4723`                                                                                                            | Port where the service that supports WebDriver commands is running                                                                                                       |
| `--service-status-endpoint`  | string    | `/status`                                                                                                         | Optional, endpoint to query the WebDriver service status, an HTTP 200 response is expected                                                                               |
| `--service-protocol-version` | string    | `HTTP/1.1`                                                                                                        | Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status                                                          |
| `--service-configuration`    | string\[] | `max-sessions=2 stereotype='{"browserName": "safari", "platformName": "iOS", "appium:platformVersion": "14.5"}}'` | Configuration for the service where calls will be relayed to. It is recommended to provide this type of configuration through a toml config file to improve readability. |

### Router

| Opção          | Tipo    | Valor/Exemplo              | Descrição                                                                                                           |
| -------------- | ------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `--password`   | string  | `myStrongPassword`         | Password clients must use to connect to the server. Both this and the username need to be set in order to be used.  |
| `--username`   | string  | `admin`                    | User name clients must use to connect to the server. Both this and the password need to be set in order to be used. |
| `--sub-path`   | string  | `my_company/selenium_grid` | A sub-path that should be considered for all user facing routes on the Hub/Router/Standalone.                       |
| `--disable-ui` | boolean | `true`                     | Disable the Grid UI.                                                                                                |

### Server

| Opção                 | Tipo    | Valor/Exemplo        | Descrição                                                                                                                                                                                                                                                                             |
| --------------------- | ------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--allow-cors`        | boolean | `true`               | Whether the Selenium server should allow web browser connections from any host                                                                                                                                                                                                        |
| `--host`              | string  | `localhost`          | Server IP or hostname: usually determined automatically.                                                                                                                                                                                                                              |
| `--bind-host`         | boolean | `true`               | Whether the server should bind to the host address/name, or only use it to" report its reachable url. Helpful in complex network topologies where the server cannot report itself with the current IP/hostname but rather an external IP or hostname (e.g. inside a Docker container) |
| `--https-certificate` | path    | `/path/to/cert.pem`  | Server certificate for https. Get more detailed information by running “java -jar selenium-server.jar info security”                                                                                                                                                                  |
| `--https-private-key` | path    | `/path/to/key.pkcs8` | Private key for https. Get more detailed information by running “java -jar selenium-server.jar info security”                                                                                                                                                                         |
| `--max-threads`       | int     | `24`                 | Maximum number of listener threads. Default value is: (available processors) \* 3.                                                                                                                                                                                                    |
| `--port`              | int     | `4444`               | Port to listen on. There is no default as this parameter is used by different components, for example, Router/Hub/Standalone will use 4444 and Node will use 5555.                                                                                                                    |

### SessionQueue

| Opção                       | Tipo   | Valor/Exemplo           | Descrição                                                                                                                                                 |
| --------------------------- | ------ | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--sessionqueue`            | uri    | `http://localhost:1237` | Address of the session queue server.                                                                                                                      |
| `-sessionqueue-host`        | string | `localhost`             | Host on which the session queue server is listening.                                                                                                      |
| `--sessionqueue-port`       | int    | `1234`                  | Port on which the session queue server is listening.                                                                                                      |
| `--session-request-timeout` | int    | `300`                   | Timeout in seconds. A new incoming session request is added to the queue. Requests sitting in the queue for longer than the configured time will timeout. |
| `--session-retry-interval`  | int    | `5`                     | Retry interval in seconds. If all slots are busy, new session request will be retried after the given interval.                                           |
| `--maximum-response-delay`  | int    | `8`                     | How often, in seconds, will the the SessionQueue response in case there is no data, to reduce the http requests while polling for new session requests.   |

### Sessions

| Opção             | Tipo   | Valor/Exemplo           | Descrição                                          |
| ----------------- | ------ | ----------------------- | -------------------------------------------------- |
| `--sessions`      | uri    | `http://localhost:1234` | Address of the session map server.                 |
| `--sessions-host` | string | `localhost`             | Host on which the session map server is listening. |
| `--sessions-port` | int    | `1234`                  | Port on which the session map server is listening. |

## Configuration examples

All the options mentioned above can be used when starting the Grid components. They are a good way of exploring the Grid options, and trying out values to find a suitable configuration.

We recommend the use of [Toml files](https://www.selenium.dev/pt-br/documentation/grid/configuration/toml_options/) to configure a Grid. Configuration files improve readability, and you can also check them in source control.

When needed, you can combine a Toml file configuration with CLI arguments.

### Command-line flags

To pass config options as command-line flags, identify the valid options for the component and follow the template below.

```
java -jar selenium-server-<version>.jar <component> --<option> value
```

#### Standalone, setting max sessions and main port

```
java -jar selenium-server-<version>.jar standalone --max-sessions 4 --port 4444
```

#### Hub, setting a new session request timeout, a main port, and disabling tracing

```
java -jar selenium-server-<version>.jar hub --session-request-timeout 500 --port 3333 --tracing false
```

#### Node, with 4 max sessions, with debug(fine) log, 7777 as port, and only with Firefox and Edge

```
java -jar selenium-server-<version>.jar node --max-sessions 4 --log-level "fine" --port 7777 --driver-implementation "firefox" --driver-implementation "edge"
```

#### Distributor, setting Session Map server url, Session Queue server url, and disabling bus

```
java -jar selenium-server-<version>.jar distributor --sessions http://localhost:5556 --sessionqueue http://localhost:5559 --bind-bus false
```

#### Setting custom capabilities for matching specific Nodes

**Important:** Custom capabilities need to be set in the configuration in all Nodes. They also need to be included always in every session request.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node A with custom cap set to `true`

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":true}' --port 6161
```

##### Start the Node B with custom cap set to `false`

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":false}' --port 6262
```

##### Matching Node A

```java
ChromeOptions options = new ChromeOptions();
options.setCapability("gsg:customcap", true);
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

Set the custom capability to `false` in order to match the Node B.

#### Enabling Managed downloads by the Node

At times a test may need to access files that were downloaded by it on the Node. To retrieve such files, following can be done.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node with manage downloads enabled

```
java -jar selenium-server-<version>.jar node --enable-managed-downloads true
```

##### Set the capability at the test level

Tests that want to use this feature should set the capability `"se:downloadsEnabled"`to `true`

```java
options.setCapability("se:downloadsEnabled", true);
```

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

In the response the list of file names appear under the key `names`.

##### Dowloading a file:

* The endpoint to `POST` from is `/session/<sessionId>/se/files` with a payload of the form `{"name": "fileNameGoesHere}`
* The session needs to be active in order for the command to work.
* The raw response looks like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "Base64EncodedStringContentsOfDownloadedFileAsZipGoesHere"
  }
}
```

* The response blob contains two keys,

  * `filename` - The file name that was downloaded.
  * `contents` - Base64 encoded zipped contents of the file.

* The file contents are Base64 encoded and they need to be unzipped.

##### List files that can be downloaded

The below mentioned `curl` example can be used to list all the files that were downloaded by the current session in the Node, and which can be retrieved locally.

```bash
curl -X GET "http://localhost:4444/session/90c0149a-2e75-424d-857a-e78734943d4c/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

##### Retrieve a downloaded file

Assuming the downloaded file is named `Red-blue-green-channel.jpg`, and using `curl`, the file could be downloaded with the following command:

```bash
curl -H "Accept: application/json" \
-H "Content-Type: application/json; charset=utf-8" \
-X POST -d '{"name":"Red-blue-green-channel.jpg"}' \
"http://localhost:4444/session/18033434-fa4f-4d11-a7df-9e6d75920e19/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "UEsDBBQACAgIAJpagVYAAAAAAAAAAAAAAAAaAAAAUmVkLWJsAAAAAAAAAAAAUmVkLWJsdWUtZ3JlZW4tY2hhbm5lbC5qcGdQSwUGAAAAAAEAAQBIAAAAcNkAAAAA"
  }
}
```

##### Complete sample code in Java

Below is an example in Java that does the following:

* Sets the capability to indicate that the test requires automatic managing of downloaded files.
* Triggers a file download via a browser.
* Lists the files that are available for retrieval from the remote node (These are essentially files that were downloaded in the current session)
* Picks one file and downloads the file from the remote node to the local machine.

```java
import com.google.common.collect.ImmutableMap;

import org.openqa.selenium.By;
import org.openqa.selenium.io.Zip;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.io.File;
import java.net.URL;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import static org.openqa.selenium.remote.http.Contents.asJson;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.HttpMethod.GET;
import static org.openqa.selenium.remote.http.HttpMethod.POST;

public class DownloadsSample {

  public static void main(String[] args) throws Exception {
    // Assuming the Grid is running locally.
    URL gridUrl = new URL("http://localhost:4444");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("se:downloadsEnabled", true);
    RemoteWebDriver driver = new RemoteWebDriver(gridUrl, options);
    try {
      demoFileDownloads(driver, gridUrl);
    } finally {
      driver.quit();
    }
  }

	private static void demoFileDownloads(RemoteWebDriver driver, URL gridUrl) throws Exception {
		driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
		// Download the two available files on the page
		driver.findElement(By.id("file-1")).click();
		driver.findElement(By.id("file-2")).click();

		// The download happens in a remote Node, which makes it difficult to know when the file
		// has been completely downloaded. For demonstration purposes, this example uses a
		// 10-second sleep which should be enough time for a file to be downloaded.
		// We strongly recommend to avoid hardcoded sleeps, and ideally, to modify your
		// application under test, so it offers a way to know when the file has been completely
		// downloaded.
		TimeUnit.SECONDS.sleep(10);

		//This is the endpoint which will provide us with list of files to download and also to
		//let us download a specific file.
		String downloadsEndpoint = String.format("/session/%s/se/files", driver.getSessionId());

		String fileToDownload;

		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To list all files that are were downloaded on the remote node for the current session
			// we trigger GET request.
			HttpRequest request = new HttpRequest(GET, downloadsEndpoint);
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			@SuppressWarnings("unchecked")
			List<String> names = (List<String>) value.get("names");
			// Let's say there were "n" files downloaded for the current session, we would like
			// to retrieve ONLY the first file.
			fileToDownload = names.get(0);
		}

		// Now, let's download the file
		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To retrieve a specific file from one or more files that were downloaded by the current session
			// on a remote node, we use a POST request.
			HttpRequest request = new HttpRequest(POST, downloadsEndpoint);
			request.setContent(asJson(ImmutableMap.of("name", fileToDownload)));
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			// The returned map would contain 2 keys,
			// filename - This represents the name of the file (same as what was provided by the test)
			// contents - Base64 encoded String which contains the zipped file.
			String zippedContents = value.get("contents").toString();
			// The file contents would always be a zip file and has to be unzipped.
			File downloadDir = Zip.unzipToTempDir(zippedContents, "download", "");
			// Read the file contents
			File downloadedFile = Optional.ofNullable(downloadDir.listFiles()).orElse(new File[]{})[0];
			String fileContent = String.join("", Files.readAllLines(downloadedFile.toPath()));
			System.out.println("The file which was "
					+ "downloaded in the node is now available in the directory: "
					+ downloadDir.getAbsolutePath() + " and has the contents: " + fileContent);
		}
	}


}
```

# 3 - Toml Options

```toml
[section1]
option1="value"

[section2]
option2=["value1","value2"]
option3=true
```

Below are some examples of Grid components configured with a Toml file, the component can be started in the following way:

```
java -jar selenium-server-<version>.jar <component> --config /path/to/file/<file-name>.toml
```

### Standalone

A Standalone server, running on port 4449, and a new session request timeout of 500 seconds.

```toml
[server]
port = 4449

[sessionqueue]
session-request-timeout = 500
```

### Specific browsers and a limit of max sessions

A Standalone server or a Node which only has Firefox and Chrome enabled by default.

```toml
[node]
drivers = ["chrome", "firefox"]
max-sessions = 3
```

### Configuring and customising drivers

Standalone or Node server with customised drivers, which allows things like having Firefox Beta or Nightly, and having different browser versions.

```toml
[node]
detect-drivers = false
[[node.driver-configuration]]
max-sessions = 100
display-name = "Firefox Nightly"
stereotype = "{\"browserName\": \"firefox\", \"browserVersion\": \"93\", \"platformName\": \"MAC\", \"moz:firefoxOptions\": {\"binary\": \"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"
[[node.driver-configuration]]
display-name = "Chrome Beta"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"94\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta\"}}"
[[node.driver-configuration]]
display-name = "Chrome Dev"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"95\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev\"}}"
webdriver-executable = '/path/to/chromedriver/95/chromedriver'
```

### Standalone or Node with Docker

A Standalone or Node server that is able to run each new session in a Docker container. Disabling drivers detection, having maximum 2 concurrent sessions. Stereotypes configured need to be mapped to a Docker image, and the Docker daemon needs to be exposed via http/tcp. In addition, it is possible to define which device files, accessible on the host, will be available in containers through the `devices` property. Refer to the [docker](https://docs.docker.com/engine/reference/commandline/run/#add-host-device-to-container---device) documentation for more information about how docker device mapping works.

```toml
[node]
detect-drivers = false
max-sessions = 2

[docker]
configs = [
    "selenium/standalone-chrome:93.0", "{\"browserName\": \"chrome\", \"browserVersion\": \"91\"}", 
    "selenium/standalone-firefox:92.0", "{\"browserName\": \"firefox\", \"browserVersion\": \"92\"}"
]
#Optionally define all device files that should be mapped to docker containers
#devices = [
#    "/dev/kvm:/dev/kvm"
#]
url = "http://localhost:2375"
video-image = "selenium/video:latest"
```

### Relaying commands to a service endpoint that supports WebDriver

It is useful to connect an external service that supports WebDriver to Selenium Grid. An example of such service could be a cloud provider or an Appium server. In this way, Grid can enable more coverage to platforms and versions not present locally.

The following is an en example of connecting an Appium server to Grid.

```toml
[node]
detect-drivers = false

[relay]
# Default Appium/Cloud server endpoint
url = "http://localhost:4723/wd/hub"
status-endpoint = "/status"
# Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status (e.g. HTTP/1.1, HTTP/2)
protocol-version = "HTTP/1.1"
# Stereotypes supported by the service. The initial number is "max-sessions", and will allocate 
# that many test slots to that particular configuration
configs = [
  "5", "{\"browserName\": \"chrome\", \"platformName\": \"android\", \"appium:platformVersion\": \"11\"}"
]
```

### Basic auth enabled

It is possible to protect a Grid with basic auth by configuring the Router/Hub/Standalone with a username and password. This user/password combination will be needed when loading the Grid UI or starting a new session.

```toml
[router]
username = "admin"
password = "myStrongPassword"
```

Here is a Java example showing how to start a session using the configured user and password.

```java
ClientConfig clientConfig = ClientConfig.defaultConfig()
  .baseUrl(new URL("http://localhost:4444"))
  .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"));
HttpCommandExecutor executor = new HttpCommandExecutor(clientConfig);
RemoteWebDriver driver = new RemoteWebDriver(executor, new ChromeOptions());
```

In other languages, you can use the URL http\://admin:myStrongPassword\@localhost:4444

### Setting custom capabilities for matching specific Nodes

**Important:** Custom capabilities need to be set in the configuration in all Nodes. They also need to be included always in every session request.

```toml
[node]
detect-drivers = false

[[node.driver-configuration]]
display-name = "firefox"
stereotype = '{"browserName": "firefox", "platformName": "macOS", "browserVersion":"96", "networkname:applicationName":"node_1", "nodename:applicationName":"app_1" }'
max-sessions = 5
```

Here is a Java example showing how to match that Node

```java
FirefoxOptions options = new FirefoxOptions();
options.setCapability("networkname:applicationName", "node_1");
options.setCapability("nodename:applicationName", "app_1");
options.setBrowserVersion("96");
options.setPlatformName("macOS");
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

### Enabling Managed downloads by the Node.

The Node can be instructed to manage downloads automatically. This will cause the Node to save all files that were downloaded for a particular session into a temp directory, which can later be retrieved from the node. To turn this capability on, use the below configuration:

```toml
[node]
enable-managed-downloads = true
```

Refer to the [CLI section](https://www.selenium.dev/pt-br/documentation/grid/configuration/cli_options/#enabling-managed-downloads-by-the-node) for a complete example.

----
url: https://www.selenium.dev/ja/documentation/webdriver/interactions/navigation/
----

# ブラウザー ナビゲーション

```java
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L14-L18)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.get("https://www.selenium.dev/selenium/web/index.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L6)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Convenient
            driver.Url = "https://selenium.dev";
            //Longer
            driver.Navigate().GoToUrl("https://selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class NavigationTest
    {
        [TestMethod]
        public void TestNavigationCommands()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            //Convenient
            driver.Url = "https://selenium.dev";
            //Longer
            driver.Navigate().GoToUrl("https://selenium.dev");
            var title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Back
            driver.Navigate().Back();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Forward
            driver.Navigate().Forward();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Refresh
            driver.Navigate().Refresh();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Quit the browser
            driver.Quit();
        }
    }
}
```

```rb

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L7-L9)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L16-L20)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
//Convenient
driver.get("https://selenium.dev")

//Longer way
driver.navigate().to("https://selenium.dev")
  
```

```java
        //Back
        driver.navigate().back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L22-L23)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.back()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L11)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Back
             driver.Navigate().Back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L24-L25)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
    driver.navigate.to 'https://www.selenium.dev/'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L15)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Back
    await driver.navigate().back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L24-L25)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().back() 
```

```java
        //Forward
        driver.navigate().forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L27-L28)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.forward()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L15)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Forward
             driver.Navigate().Forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L29-L30)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L23)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Forward
    await driver.navigate().forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L29-L30)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().forward()
```

```java
        //Refresh
        driver.navigate().refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L32-L33)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.refresh()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L19)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Refresh
             driver.Navigate().Refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L34-L35)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
  it 'refreshes the page' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L29)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Refresh
    await driver.navigate().refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L34-L35)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().refresh()
```

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/elements/interactions/
----

# Interacting with web elements

```java
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L18-L22)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L12-L17)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L17-L21)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'color_input').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L11)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
    await submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L20)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
  const assert = require("assert");
  
  (async function firstTest() {
    let driver;
    
    try {
      driver = await new Builder().forBrowser(Browser.CHROME).build();
      await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
    
      let title = await driver.getTitle();
      assert.equal("Web form", title);
    
      await driver.manage().setTimeouts({implicit: 500});
    
      let textBox = await driver.findElement(By.name('my-text'));
      let submitButton = await driver.findElement(By.css('button'));
    
      await textBox.sendKeys('Selenium');
      await submitButton.click();
    
      let message = await driver.findElement(By.id('message'));
      let value = await message.getText();
      assert.equal("Received!", value);
    } catch (e) {
      console.log(e)
    } finally {
      await driver.quit();
    }
  }())
  
```

```kotlin
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    // Click the element
    driver.findElement(By.name("color_input")).click();
  
  
```

```java
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L27-L32)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L22-L27)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L27-L33)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L16)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
      let inputField = await driver.findElement(By.name('no_type'));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/interactions.spec.js#L21)

##### /examples/javascript/test/elements/interactions.spec.js

```js

  const {By, Browser, Builder} = require('selenium-webdriver');
  const assert = require("node:assert");
  
  
  describe('Element Interactions', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('should Clear input and send keys into input field', async function () {
  
      try {
        await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
        let inputField = await driver.findElement(By.name('no_type'));
        await inputField.clear();
        await inputField.sendKeys('Selenium');
        const text = await inputField.getAttribute('value');
        assert.strictEqual(text, "Selenium");
      } catch (e) {
        console.log(e)
      }
    });
  });
```

```kotlin
  
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

	//Clear field to empty it from any previous data
	driver.findElement(By.name("email_input")).clear()
	
    // Enter text 
    driver.findElement(By.name("email_input")).sendKeys("admin@localhost.dev")
  
  
```

```java
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L38-L40)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    email_input.clear()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L34)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L40-L43)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'email_input').clear
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L15)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
      await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/interactions.spec.js#L20)

##### /examples/javascript/test/elements/interactions.spec.js

```js

  const {By, Browser, Builder} = require('selenium-webdriver');
  const assert = require("node:assert");
  
  
  describe('Element Interactions', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('should Clear input and send keys into input field', async function () {
  
      try {
        await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
        let inputField = await driver.findElement(By.name('no_type'));
        await inputField.clear();
        await inputField.sendKeys('Selenium');
        const text = await inputField.getAttribute('value');
        assert.strictEqual(text, "Selenium");
      } catch (e) {
        console.log(e)
      }
    });
  });
```

```kotlin
  
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

	//Clear field to empty it from any previous data
	driver.findElement(By.name("email_input")).clear()
	
  
  
```

## Submit

In Selenium 4 this is no longer implemented with a separate endpoint and functions by executing a script. As such, it is recommended not to use this method and to click the applicable form submission button instead.

Última modificação September 6, 2025: [changed editable to keyboard interactable as per W3C doc (#2472) (5e333fc2769)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/5e333fc2769a9e0ca541477eb2bfc5220da04951)

----
url: https://www.selenium.dev/pt-br/documentation/legacy/selenium_2/
----

# Selenium 2

Selenium 2 was a rewrite of Selenium 1 that was implemented with WebDriver code.

***

##### [Migrando do RC para WebDriver](/pt-br/documentation/legacy/selenium_2/upgrading/)

##### [Servidor do WebDriver remoto](/pt-br/documentation/legacy/selenium_2/remote_server/)

----
url: https://www.selenium.dev/ja/_print/documentation/webdriver/drivers/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/webdriver/drivers/).

# ドライバーセッション

* 1: [ブラウザーオプション](#pg-789eb6f85cd53260f517387cc09d1662)
* 2: [HTTPクライアントの設定](#pg-92f112230ed72f85d2142e9432aeab27)
* 3: [ドライバーサービスクラス](#pg-c1ef9c8732437a8b3f796fb859767948)
* 4: [リモートWebDriver](#pg-c7bd0677c4be3e0aefbd3092913da6dc)

```java
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L23)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L9)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            driver = new ChromeDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BaseTest.cs#L48)

##### /examples/dotnet/SeleniumDocs/BaseTest.cs

```cs
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs
{
    public class BaseTest
    {
        protected IWebDriver driver;
        protected Uri GridUrl;
        private Process _webserverProcess;
        private const string ServerJarName = "selenium-server-4.44.0.jar";
        private static readonly string BaseDirectory = AppContext.BaseDirectory;
        private const string RelativePathToGrid = "../../../../../";
        private readonly string _examplesDirectory = Path.GetFullPath(Path.Combine(BaseDirectory, RelativePathToGrid));

        [TestCleanup]
        public void Cleanup()
        {
            driver?.Quit();

            if (_webserverProcess != null)
            {
                StopServer();
            }
        }

        protected void StartDriver(string browserVersion = null)
        {
            ChromeOptions options = new ChromeOptions();
            if (browserVersion != null)
            {
                options.BrowserVersion = browserVersion;
                string userDataDir = System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetRandomFileName());
                System.IO.Directory.CreateDirectory(userDataDir);
                options.AddArgument($"--user-data-dir={userDataDir}");
                options.AddArgument("--no-sandbox");
                options.AddArgument("--disable-dev-shm-usage");
            }
            driver = new ChromeDriver(options);
        }

        protected async Task StartServer()
        {
            if (_webserverProcess == null || _webserverProcess.HasExited)
            {
                _webserverProcess = new Process();
                _webserverProcess.StartInfo.FileName =
                    RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "java.exe" : "java";
                string port = GetFreeTcpPort().ToString();
                GridUrl = new Uri("http://localhost:" + port + "/wd/hub");
                _webserverProcess.StartInfo.Arguments = " -jar " + ServerJarName +
                                                        " standalone --port " + port +
                                                        " --selenium-manager true --enable-managed-downloads true";
                _webserverProcess.StartInfo.WorkingDirectory = _examplesDirectory;
                _webserverProcess.Start();
                await EnsureGridIsRunningAsync();
            }
        }

        private void StopServer()
        {
            if (_webserverProcess != null && !_webserverProcess.HasExited)
            {
                _webserverProcess.Kill();
                _webserverProcess.Dispose();
                _webserverProcess = null;
            }
        }

        private static int GetFreeTcpPort()
        {
            TcpListener l = new TcpListener(IPAddress.Loopback, 0);
            l.Start();
            int port = ((IPEndPoint)l.LocalEndpoint).Port;
            l.Stop();
            return port;
        }

        private async Task EnsureGridIsRunningAsync()
        {
            DateTime timeout = DateTime.Now.Add(TimeSpan.FromSeconds(240));
            bool isRunning = false;
            HttpClient client = new HttpClient();

            while (!isRunning && DateTime.Now < timeout)
            {
                try
                {
                    HttpResponseMessage response = await client.GetAsync(GridUrl + "/status");
                    if (response.IsSuccessStatusCode)
                    {
                        isRunning = true;
                    }
                    else
                    {
                        await Task.Delay(1000);
                    }
                }
                catch (HttpRequestException)
                {
                    await Task.Delay(1000);
                }
            }

            if (!isRunning)
            {
                throw new TimeoutException("Could not confirm the remote selenium server is running within 30 seconds");
            }
        }
    }
}
```

```rb
      driver = Selenium::WebDriver.for :chrome, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L14)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options)
      .setChromeService(service)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/drivers/service.spec.js#L46-L50)

##### /examples/javascript/test/drivers/service.spec.js

```js
const fs = require('fs');
const os = require('os');
const path = require('path');
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const {getBinaryPaths} = require("selenium-webdriver/common/driverFinder");

describe('Service Test', function () {
  let driver;
  let userDataDir;
  let service;
  let options;

  afterEach(async function () {
    if (driver) {
      await driver.quit();
      driver = null;
    }
    if (userDataDir) {
      fs.rmSync(userDataDir, { recursive: true, force: true });
      userDataDir = null;
    }
  });

  it('Default service', async function () {
    service = new Chrome.ServiceBuilder();
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });

  it('Set Driver Location', async function () {
    options = new Chrome.Options();
    options.setBrowserVersion("stable");
    let paths = getBinaryPaths(options);
    let driverPath = paths.driverPath;
    let browserPath = paths.browserPath;
    options.setChromeBinaryPath(browserPath);
    userDataDir = fs.mkdtempSync(path.join(os.tmpdir(), 'chrome-profile-'));
    options.addArguments(`--user-data-dir=${userDataDir}`);
    options.addArguments('--no-sandbox');
    options.addArguments('--disable-dev-shm-usage');
    service = new Chrome.ServiceBuilder(driverPath);
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });

  it('Set port', async function () {
    service = new Chrome.ServiceBuilder().setPort(1234);
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
        driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L11)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L28)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L16)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L28)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L35)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

# 1 - ブラウザーオプション

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L73-74)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L79-80)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L11)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L80-82)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L86-88)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options.browser_version = 'latest'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L40)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## pageLoadStrategy

3種類のページ読み込み戦略を利用できます。

ページ読み込み戦略は、次の表で説明しています。

| 戦略     | 準備完了状態      | 注釈                                              |
| ------ | ----------- | ----------------------------------------------- |
| normal | complete    | デフォルトで使用され、すべてのリソースをダウンロードするのを待ちます              |
| eager  | interactive | DOM アクセスの準備は整っていますが、画像などの他のリソースはまだロード中の可能性があります |
| none   | Any         | WebDriver をまったくブロックしません                         |

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L21-L23)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L7-9)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L13-14)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L11-L12)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L28-L34)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L34-L36)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L15-L17)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L29-30)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L20-L21)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L8-L14)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L47-L49)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L23-L25)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
        public void SetPageLoadStrategyNone()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L41-42)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L29-L30)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L18-L24)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L88-L90)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L94-96)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L38-L39)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L60-L61)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L101-103)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L51-L52)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L38-L41)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L96-L98)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L30-32)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L114-L115)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L111-L113)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L37-39)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L105-L106)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L126-L128)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L44-46)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L96-L97)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L141-L142)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L51-53)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L60-L61)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L151-L152)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L58-60)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L69-L70)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L163-L164)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L65-67)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L78-L79)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class ProxyTest {
  public static void main(String[] args) {
    Proxy proxy = new Proxy();
    proxy.setHttpProxy("<HOST:PORT>");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("proxy", proxy);
    WebDriver driver = new ChromeDriver(options);
    driver.get("https://www.google.com/");
    driver.manage().window().maximize();
    driver.quit();
  }
}
```

```py
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L72-74)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

public class ProxyTest{
public static void Main() {
ChromeOptions options = new ChromeOptions();
Proxy proxy = new Proxy();
proxy.Kind = ProxyKind.Manual;
proxy.IsAutoDetect = false;
proxy.SslProxy = "<HOST:PORT>";
options.Proxy = proxy;
options.AddArgument("ignore-certificate-errors");
IWebDriver driver = new ChromeDriver(options);
driver.Navigate().GoToUrl("https://www.selenium.dev/");
}
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L87-L88)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```javascript
let webdriver = require('selenium-webdriver');
let chrome = require('selenium-webdriver/chrome');
let proxy = require('selenium-webdriver/proxy');
let opts = new chrome.Options();

(async function example() {
opts.setProxy(proxy.manual({http: '<HOST:PORT>'}));
let driver = new webdriver.Builder()
.forBrowser('chrome')
.setChromeOptions(opts)
.build();
try {
await driver.get("https://selenium.dev");
}
finally {
await driver.quit();
}
}());
```

```kotlin
import org.openqa.selenium.Proxy
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

class proxyTest {
fun main() {

        val proxy = Proxy()
        proxy.setHttpProxy("<HOST:PORT>")
        val options = ChromeOptions()
        options.setCapability("proxy", proxy)
        val driver: WebDriver = ChromeDriver(options)
        driver["https://www.google.com/"]
        driver.manage().window().maximize()
        driver.quit()
    }
}
```

# 2 - HTTPクライアントの設定

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import org.openqa.selenium.remote.http.ClientConfig;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import java.io.FileInputStream;
import java.net.URL;
import java.nio.file.Path;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.time.Duration;

import org.openqa.selenium.UsernameAndPassword;

import static java.net.http.HttpClient.Version.HTTP_1_1;

public class HttpClientTest extends BaseTest {
    URL gridUrl;

    @BeforeEach
    public void startGrid() {
        gridUrl = startStandaloneGridAdvanced();
    }

    @Test
    public void remoteWebDriverWithClientConfig() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createSSLContextWithCA(Path.of("src/test/resources/tls.crt").toAbsolutePath().toString()))
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
    }

    @Test
    public void remoteWebDriverIgnoreSSL() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createIgnoreSSLContext())
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
    }

    @Test
    public void remoteWebDriverWithEmbedAuthUrl() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createSSLContextWithCA(Path.of("src/test/resources/tls.crt").toAbsolutePath().toString()))
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(embedAuthToUrl(gridUrl, "admin", "myStrongPassword"))
                .config(clientConfig)
                .build();
    }

    private URL embedAuthToUrl(URL url, String username, String password) throws Exception {
        String userInfo = username + ":" + password;
        String urlWithAuth = url.getProtocol() + "://" + userInfo + "@" + url.getHost() + ":" + url.getPort() + url.getPath();
        return new URL(urlWithAuth);
    }

    public static SSLContext createSSLContextWithCA(String caCertPath) throws Exception {
        FileInputStream fis = new FileInputStream(caCertPath);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate caCert = (X509Certificate) cf.generateCertificate(fis);
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, null);
        keyStore.setCertificateEntry("caCert", caCert);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(keyStore);
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);
        return sslContext;
    }

    public static SSLContext createIgnoreSSLContext() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    }
                }
        };
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
        return sslContext;
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/HttpClientTest.java)

```py
import os
import pytest
import sys
from urllib3.util import Retry, Timeout
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType
from selenium.webdriver.remote.client_config import ClientConfig


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_with_client_config(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    retries = Retry(connect=2, read=2, redirect=2)
    timeout = Timeout(connect=300, read=3600)
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 init_args_for_pool_manager={
                                     "init_args_for_pool_manager": {"retries": retries, "timeout": timeout}},
                                 ca_certs=_get_resource_path("tls.crt"),
                                 username="admin", password="myStrongPassword")
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_ignore_certs(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 timeout=3600,
                                 ignore_certificates=True,
                                 username="admin", password="myStrongPassword")
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


def _get_resource_path(file_name: str):
    if os.path.abspath("").endswith("tests"):
        path = os.path.abspath(f"resources/{file_name}")
    else:
        path = os.path.abspath(f"tests/resources/{file_name}")
    return path

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_http_client.py)

[Add Example](/documentation/about/contributing/#creating-examples)

```rb

  it 'sets client configuration' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/http_client_spec.rb#L7-L8)

##### /examples/ruby/spec/drivers/http\_client\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'HTTP Client' do
  let(:url) { 'https://www.selenium.dev/selenium/web/' }

  it 'sets client configuration' do
    client = Selenium::WebDriver::Remote::Http::Default.new(open_timeout: 30, read_timeout: 30)
    expect(client.open_timeout).to eq 30
  end

  it 'uses the custom http client' do
    client = Selenium::WebDriver::Remote::Http::Default.new
    driver = Selenium::WebDriver.for :chrome, http_client: client
    driver.get(url)
    driver.quit
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

# 3 - ドライバーサービスクラス

```java
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L15-L16)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L5-L6)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L14-L15)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

```rb
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L14-L15)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

```java
    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L25-L26)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(executable_path=chromedriver_bin)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L15)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```cs
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L23)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
    service.executable_path = driver_path
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L26)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

```java
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L33)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(port=1234)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L23)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            service.Port = 1234;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L32)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
    service.port = 1234
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L33)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```


# 4 - リモートWebDriver

```java
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L38-L39)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L13-L14)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L28-L29)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L20-L21)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L49-L52)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

Pythonでは、リモートWebDriverインスタンスにデフォルトでローカルファイルディテクターが追加されますが、独自のクラスを作成することも可能です。

```py
    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#LL29-L32)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

.NETでは、リモートWebDriverインスタンスにデフォルトでローカルファイルディテクターが追加されますが、独自のクラスを作成することも可能です。

```cs
            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L47-L50)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

Rubyでは、リモートWebDriverインスタンスにデフォルトでローカルファイルディテクターが追加されますが、独自のラムダを作成することも可能です。

```rb
    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L33-L36)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## ダウンロード

Chrome、Edge、およびFirefoxでは、それぞれダウンロードディレクトリの場所を設定できます。 ただし、リモートコンピュータでこれを行う場合、その場所はリモートコンピュータのローカルファイルシステム上にあります。Seleniumを使用すると、クライアントコンピュータにこれらのファイルをダウンロードできるように設定することが可能です。

### グリッドでのダウンロードを有効化

クライアントに関係なく、ノードまたはスタンドアロンモードでグリッドを起動する際には、次のフラグを追加する必要があります:

```
--enable-managed-downloads true
```

```java
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L60-L62)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L42-L44)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L59-L64)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L43-L44)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    List<String> files = ((HasDownloads) driver).getDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L73)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    files = driver.get_downloadable_files()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L52)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L72)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    files = driver.downloadable_files
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L52)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L83)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    driver.download_file(downloadable_file, target_directory)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L58)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L79)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    driver.download_file(downloadable_file, target_directory)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L57)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((HasDownloads) driver).deleteDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L88)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    driver.delete_downloadable_files()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L64)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ((RemoteWebDriver)driver).DeleteDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L84)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    driver.delete_downloadable_files
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L62)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    driver = new Augmenter().augment(driver);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L98)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

興味深いことに、RemoteWebDriverBuilderを使用すると、ドライバーが自動的に拡張されるため、デフォルトで全ての機能を取得するのに最適な方法です。

```java
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L106-L111)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

.NETでは、リモートドライバーで指定されたブラウザに対して有効なコマンドを実行するために、カスタムコマンドエグゼキュータを使用します。

```cs
            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L96-L100)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```xml
  <dependency>
      <groupId>io.opentelemetry</groupId>
      <artifactId>opentelemetry-exporter-jaeger</artifactId>
      <version>1.0.0</version>
    </dependency>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-netty</artifactId>
      <version>1.35.0</version>
    </dependency>
```

### クライアントの実行中に必要なシステムプロパティを追加/渡す

*

```java
System.setProperty("otel.traces.exporter", "jaeger");
System.setProperty("otel.exporter.jaeger.endpoint", "http://localhost:14250");
System.setProperty("otel.resource.attributes", "service.name=selenium-java-client");

ImmutableCapabilities capabilities = new ImmutableCapabilities("browserName", "chrome");

WebDriver driver = new RemoteWebDriver(new URL("http://www.example.com"), capabilities);

driver.get("http://www.google.com");

driver.quit();

  
```

ご希望のSeleniumのバージョンに必要な外部依存関係のバージョンの詳細については、 [トレースのセットアップ](https://github.com/SeleniumHQ/selenium/blob/selenium-4.0.0-beta-1/java/server/src/org/openqa/selenium/grid/commands/tracing.txt) を参照してください。

詳細については、下記URLを参照してください。

* OpenTelemetry: <https://opentelemetry.io>
* OpenTelemetryの構成:: <https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure>
* Jaeger: <https://www.jaegertracing.io>
* [Selenium Grid 可観測性](https://www.selenium.dev/ja/documentation/grid/advanced_features/observability/)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/elements/finders/
----

# Encontrando Elementos Web

Localizando elementos com base nos valores providenciados pelo localizador.

Um dos aspectos mais fundamentais do uso do Selenium é obter referências de elementos para trabalhar. O Selenium oferece várias [estratégias de localizador](https://www.selenium.dev/pt-br/documentation/webdriver/elements/locators/) para identificar exclusivamente um elemento. Há muitas maneiras de usar os localizadores em cenários complexos. Para os propósitos desta documentação, vamos considerar este trecho de HTML:

```html
<ol id="vegetables">
 <li class="potatoes">…
 <li class="onions">…
 <li class="tomatoes"><span>O tomate é um vegetal</span>…
</ol>
<ul id="fruits">
  <li class="bananas">…
  <li class="apples">…
  <li class="tomatoes"><span>O tomate é uma fruta</span>…
</ul>
```

```java
WebElement vegetable = driver.findElement(By.className("tomatoes"));
  
```

```python
vegetable = driver.find_element(By.CLASS_NAME, "tomatoes")
  
```

```csharp
var vegetable = driver.FindElement(By.ClassName("tomatoes"));
  
```

```rb
      driver.find_element(class: 'tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L10)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const vegetable = await driver.findElement(By.className('tomatoes'));
  
```

```kotlin
val vegetable: WebElement = driver.findElement(By.className("tomatoes"))
  
```

```java
WebElement fruits = driver.findElement(By.id("fruits"));
WebElement fruit = fruits.findElement(By.className("tomatoes"));
  
```

```python
fruits = driver.find_element(By.ID, "fruits")
fruit = fruits.find_element(By.CLASS_NAME,"tomatoes")
  
```

```csharp
IWebElement fruits = driver.FindElement(By.Id("fruits"));
IWebElement fruit = fruits.FindElement(By.ClassName("tomatoes"));
  
```

```rb
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L14-L15)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const fruits = await driver.findElement(By.id('fruits'));
const fruit = fruits.findElement(By.className('tomatoes'));
  
```

```kotlin
val fruits = driver.findElement(By.id("fruits"))
val fruit = fruits.findElement(By.className("tomatoes"))
  
```

```java
WebElement shadowHost = driver.findElement(By.cssSelector("#shadow_host"));
SearchContext shadowRoot = shadowHost.getShadowRoot();
WebElement shadowContent = shadowRoot.findElement(By.cssSelector("#shadow_content"));
```

```python
shadow_host = driver.find_element(By.CSS_SELECTOR, '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(By.CSS_SELECTOR, '#shadow_content')
```

```csharp
var shadowHost = _driver.FindElement(By.CssSelector("#shadow_host"));
var shadowRoot = shadowHost.GetShadowRoot();
var shadowContent = shadowRoot.FindElement(By.CssSelector("#shadow_content"));
```

```ruby
shadow_host = @driver.find_element(css: '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(css: '#shadow_content')
```

```java
WebElement fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"));
  
```

```python
fruit = driver.find_element(By.CSS_SELECTOR,"#fruits .tomatoes")
  
```

```csharp
var fruit = driver.FindElement(By.CssSelector("#fruits .tomatoes"));
  
```

```rb
      driver.find_element(css: '#fruits .tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L19)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const fruit = await driver.findElement(By.css('#fruits .tomatoes'));
  
```

```kotlin
val fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"))
  
```

```java
List<WebElement> plants = driver.findElements(By.tagName("li"));
  
```

```python
plants = driver.find_elements(By.TAG_NAME, "li")
  
```

```csharp
IReadOnlyList<IWebElement> plants = driver.FindElements(By.TagName("li"));
  
```

```rb
      driver.find_elements(tag_name: 'li')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L23)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const plants = await driver.findElements(By.tagName('li'));
  
```

```kotlin
val plants: List<WebElement> = driver.findElements(By.tagName("li"))
  
```

```java
List<WebElement> elements = driver.findElements(By.tagName("li"));

for (WebElement element : elements) {
    System.out.println("Paragraph text:" + element.getText());
}
  
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Firefox()

    # Navegar até a URL
driver.get("https://www.example.com")

    # Obtém todos os elementos disponiveis com o nome da tag 'p'
elements = driver.find_elements(By.TAG_NAME, 'p')

for e in elements:
    print(e.text)
  
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using System.Collections.Generic;

namespace FindElementsExample {
 class FindElementsExample {
  public static void Main(string[] args) {
   IWebDriver driver = new FirefoxDriver();
   try {
    // Navegar até a URL
    driver.Navigate().GoToUrl("https://example.com");

    // Obtém todos os elementos disponiveis com o nome da tag 'p'
    IList < IWebElement > elements = driver.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }

   } finally {
    driver.Quit();
   }
  }
 }
}
  
```

```rb
      elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L27-L28)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
   
   require 'spec_helper'
   
   RSpec.describe 'Element Finders' do
     let(:driver) { start_session }
   
     context 'without executing finders', skip: 'these are just examples, not actual tests' do
       it 'finds the first matching element' do
         driver.find_element(class: 'tomatoes')
       end
   
       it 'uses a subset of the dom to find an element' do
         fruits = driver.find_element(id: 'fruits')
         fruits.find_element(class: 'tomatoes')
       end
   
       it 'uses an optimized locator' do
         driver.find_element(css: '#fruits .tomatoes')
       end
   
       it 'finds all matching elements' do
         driver.find_elements(tag_name: 'li')
       end
   
       it 'gets an element from a collection' do
         elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'finds element from element' do
         element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'find active element' do
         driver.find_element(css: '[name="q"]').send_keys('webElement')
         driver.switch_to.active_element.attribute('title')
       end
     end
   end
   
```

```javascript
const {Builder, By} = require('selenium-webdriver');
(async function example() {
    let driver = await new Builder().forBrowser('firefox').build();
    try {
        // Navegar até a URL
        await driver.get('https://www.example.com');

        // Obtém todos os elementos disponiveis com o nome da tag 'p'
        let elements = await driver.findElements(By.css('p'));
        for(let e of elements) {
            console.log(await e.getText());
        }
    }
    finally {
        await driver.quit();
    }
})();
  
```

```kotlin
import org.openqa.selenium.By
import org.openqa.selenium.firefox.FirefoxDriver

fun main() {
    val driver = FirefoxDriver()
    try {
        driver.get("https://example.com")
        // Obtém todos os elementos disponiveis com o nome da tag 'p'
        val elements = driver.findElements(By.tagName("p"))
        for (element in elements) {
            println("Paragraph text:" + element.text)
        }
    } finally {
        driver.quit()
    }
}
  
```

```java
  import org.openqa.selenium.By;
  import org.openqa.selenium.WebDriver;
  import org.openqa.selenium.WebElement;
  import org.openqa.selenium.chrome.ChromeDriver;
  import java.util.List;

  public class findElementsFromElement {
      public static void main(String[] args) {
          WebDriver driver = new ChromeDriver();
          try {
              driver.get("https://example.com");

              // Obtém o elemento com o nome da tag 'div'
              WebElement element = driver.findElement(By.tagName("div"));

              // Obtém todos os elementos disponiveis com o nome da tag 'p'
              List<WebElement> elements = element.findElements(By.tagName("p"));
              for (WebElement e : elements) {
                  System.out.println(e.getText());
              }
          } finally {
              driver.quit();
          }
      }
  }
  
```

```python
##get elements from parent element using TAG_NAME

    # Obtém o elemento com o nome da tag 'div'
element = driver.find_element(By.TAG_NAME, 'div')

    # Obtém todos os elementos disponíveis com o nome da tag 'p'
elements = element.find_elements(By.TAG_NAME, 'p')
for e in elements:
    print(e.text)

##get elements from parent element using XPATH
##NOTE: in order to utilize XPATH from current element, you must add "." to beginning of path

    # Get first element of tag 'ul'
element = driver.find_element(By.XPATH, '//ul')

    # get children of tag 'ul' with tag 'li'
elements  = element.find_elements(By.XPATH, './/li')
for e in elements:
    print(e.text)
  
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace FindElementsFromElement {
 class FindElementsFromElement {
  public static void Main(string[] args) {
   IWebDriver driver = new ChromeDriver();
   try {
    driver.Navigate().GoToUrl("https://example.com");

    // Obtém o elemento com o nome da tag 'div'
    IWebElement element = driver.FindElement(By.TagName("div"));

    // Obtém todos os elementos disponíveis com o nome da tag 'p'
    IList < IWebElement > elements = element.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }
   } finally {
    driver.Quit();
   }
  }
 }
}
  
```

```rb
      element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L32-L34)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
   
   require 'spec_helper'
   
   RSpec.describe 'Element Finders' do
     let(:driver) { start_session }
   
     context 'without executing finders', skip: 'these are just examples, not actual tests' do
       it 'finds the first matching element' do
         driver.find_element(class: 'tomatoes')
       end
   
       it 'uses a subset of the dom to find an element' do
         fruits = driver.find_element(id: 'fruits')
         fruits.find_element(class: 'tomatoes')
       end
   
       it 'uses an optimized locator' do
         driver.find_element(css: '#fruits .tomatoes')
       end
   
       it 'finds all matching elements' do
         driver.find_elements(tag_name: 'li')
       end
   
       it 'gets an element from a collection' do
         elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'finds element from element' do
         element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'find active element' do
         driver.find_element(css: '[name="q"]').send_keys('webElement')
         driver.switch_to.active_element.attribute('title')
       end
     end
   end
   
```

```javascript
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = new Builder()
          .forBrowser('chrome')
          .build();

      await driver.get('https://www.example.com');

      //  Obtém o elemento com o nome da tag 'div'
      let element = driver.findElement(By.css("div"));

      // Obtém todos os elementos disponíveis com o nome da tag 'p'
      let elements = await element.findElements(By.css("p"));
      for(let e of elements) {
          console.log(await e.getText());
      }
  })();
  
```

```kotlin
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://example.com")

           // Obtém o elemento com o nome da tag 'div'
          val element = driver.findElement(By.tagName("div"))

          // Obtém todos os elementos disponíveis com o nome da tag 'p'
          val elements = element.findElements(By.tagName("p"))
          for (e in elements) {
              println(e.text)
          }
      } finally {
          driver.quit()
      }
  }
  
```

```java
  import org.openqa.selenium.*;
  import org.openqa.selenium.chrome.ChromeDriver;

  public class activeElementTest {
    public static void main(String[] args) {
      WebDriver driver = new ChromeDriver();
      try {
        driver.get("http://www.google.com");
        driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement");

        // Obter atributo do elemento atualmente ativo
        String attr = driver.switchTo().activeElement().getAttribute("title");
        System.out.println(attr);
      } finally {
        driver.quit();
      }
    }
  }
  
```

```python
  from selenium import webdriver
  from selenium.webdriver.common.by import By

  driver = webdriver.Chrome()
  driver.get("https://www.google.com")
  driver.find_element(By.CSS_SELECTOR, '[name="q"]').send_keys("webElement")

    # Obter atributo do elemento atualmente ativo
  attr = driver.switch_to.active_element.get_attribute("title")
  print(attr)
  
```

```csharp
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;

    namespace ActiveElement {
     class ActiveElement {
      public static void Main(string[] args) {
       IWebDriver driver = new ChromeDriver();
       try {
        // Navegar até a URL
        driver.Navigate().GoToUrl("https://www.google.com");
        driver.FindElement(By.CssSelector("[name='q']")).SendKeys("webElement");

        // Obter atributo do elemento atualmente ativo
        string attr = driver.SwitchTo().ActiveElement().GetAttribute("title");
        System.Console.WriteLine(attr);
       } finally {
        driver.Quit();
       }
      }
     }
    }
  
```

```rb
      driver.find_element(css: '[name="q"]').send_keys('webElement')
        driver.switch_to.active_element.attribute('title')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L38-L39)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
  
  require 'spec_helper'
  
  RSpec.describe 'Element Finders' do
    let(:driver) { start_session }
  
    context 'without executing finders', skip: 'these are just examples, not actual tests' do
      it 'finds the first matching element' do
        driver.find_element(class: 'tomatoes')
      end
  
      it 'uses a subset of the dom to find an element' do
        fruits = driver.find_element(id: 'fruits')
        fruits.find_element(class: 'tomatoes')
      end
  
      it 'uses an optimized locator' do
        driver.find_element(css: '#fruits .tomatoes')
      end
  
      it 'finds all matching elements' do
        driver.find_elements(tag_name: 'li')
      end
  
      it 'gets an element from a collection' do
        elements = driver.find_elements(:tag_name, 'p')
        elements.each { |e| puts e.text }
      end
  
      it 'finds element from element' do
        element = driver.find_element(:tag_name, 'div')
        elements = element.find_elements(:tag_name, 'p')
        elements.each { |e| puts e.text }
      end
  
      it 'find active element' do
        driver.find_element(css: '[name="q"]').send_keys('webElement')
        driver.switch_to.active_element.attribute('title')
      end
    end
  end
  
```

```javascript
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = await new Builder().forBrowser('chrome').build();
      await driver.get('https://www.google.com');
      await  driver.findElement(By.css('[name="q"]')).sendKeys("webElement");

      // Obter atributo do elemento atualmente ativo
      let attr = await driver.switchTo().activeElement().getAttribute("title");
      console.log(`${attr}`)
  })();
  
```

```kotlin
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://www.google.com")
          driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement")

          // Obter atributo do elemento atualmente ativo
          val attr = driver.switchTo().activeElement().getAttribute("title")
          print(attr)
      } finally {
          driver.quit()
      }
  }
  
```

Última modificação September 6, 2025: [changed driver to element (#2471) (daea0ec2a80)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/daea0ec2a80e796aaed225697d8cb307cc68ca81)

----
url: https://www.selenium.dev/pt-br/documentation/ie_driver_server/internals/
----

Última modificação January 10, 2022: [More wiki (#907) \[deploy site\] (adcf706a1ad)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/adcf706a1ad907d028dc57d10201a265972432af)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/waits/
----

# Esperas

Perhaps the most common challenge for browser automation is ensuring that the web application is in a state to execute a particular Selenium command as desired. The processes often end up in a *race condition* where sometimes the browser gets into the right state first (things work as intended) and sometimes the Selenium code executes first (things do not work as intended). This is one of the primary causes of *flaky tests*.

All navigation commands wait for a specific `readyState` value based on the [page load strategy](https://www.selenium.dev/pt-br/documentation/webdriver/drivers/options/#pageloadstrategy) (the default value to wait for is `"complete"`) before the driver returns control to the code. The `readyState` only concerns itself with loading assets defined in the HTML, but loaded JavaScript assets often result in changes to the site, and elements that need to be interacted with may not yet be on the page when the code is ready to execute the next Selenium command.

Similarly, in a lot of single page applications, elements get dynamically added to a page or change visibility based on a click. An element must be both present and [displayed](https://www.selenium.dev/pt-br/documentation/webdriver/elements/information/#is-displayed) on the page in order for Selenium to interact with it.

Take this page for example: <https://www.selenium.dev/selenium/web/dynamic.html> When the “Add a box!” button is clicked, a “div” element that does not exist is created. When the “Reveal a new input” button is clicked, a hidden text field element is displayed. In both cases the transition takes a couple seconds. If the Selenium code is to click one of these buttons and interact with the resulting element, it will do so before that element is ready and fail.

The first solution many people turn to is adding a sleep statement to pause the code execution for a set period of time. Because the code can’t know exactly how long it needs to wait, this can fail when it doesn’t sleep long enough. Alternately, if the value is set too high and a sleep statement is added in every place it is needed, the duration of the session can become prohibitive.

Selenium provides two different mechanisms for synchronization that are better.

## Implicit waits

Selenium has a built-in way to automatically wait for elements called an *implicit wait*. An implicit wait value can be set either with the [timeouts](https://www.selenium.dev/pt-br/documentation/webdriver/drivers/options/#timeouts) capability in the browser options, or with a driver method (as shown below).

```java
    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L50)

##### /examples/java/src/test/java/dev/selenium/waits/WaitsTest.java

```java
package dev.selenium.waits;

import dev.selenium.BaseTest;
import java.time.Duration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.ElementNotInteractableException;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

public class WaitsTest extends BaseTest {
  @Test
  public void fails() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Assertions.assertThrows(
        NoSuchElementException.class,
        () -> {
          driver.findElement(By.id("box0"));
        });
  }

  @Test
  public void sleep() throws InterruptedException {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Thread.sleep(1000);

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void implicit() {
    startChromeDriver(new ChromeOptions());

    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void explicit() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    wait.until(d -> revealed.isDisplayed());

    revealed.sendKeys("Displayed");
    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }

  @Test
  public void explicitWithOptions() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait =
        new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(2))
            .pollingEvery(Duration.ofMillis(300))
            .ignoring(ElementNotInteractableException.class);

    wait.until(
        d -> {
          revealed.sendKeys("Displayed");
          return true;
        });

    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }
}
```

```py
    driver.implicitly_wait(2)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/waits/test_waits.py#L27)

##### /examples/python/tests/waits/test\_waits.py

```py
import pytest
import time
from selenium.common import NoSuchElementException, ElementNotInteractableException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


def test_fails(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    with pytest.raises(NoSuchElementException):
        driver.find_element(By.ID, 'box0')


def test_sleep(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    time.sleep(2)
    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_implicit(driver):
    driver.implicitly_wait(2)
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_explicit(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(lambda _ : revealed.is_displayed())

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"


def test_explicit_options(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    errors = [NoSuchElementException, ElementNotInteractableException]
    wait = WebDriverWait(driver, timeout=2, poll_frequency=.2, ignored_exceptions=errors)
    wait.until(lambda _ : revealed.send_keys("Displayed") or True)

    assert revealed.get_property("value") == "Displayed"
```

```cs
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L39)

##### /examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs

```cs
using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Waits
{
    [TestClass]
    public class WaitsTest : BaseChromeTest
    {
        [TestMethod]
        public void Fails()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Assert.ThrowsException<NoSuchElementException>(
                () => driver.FindElement(By.Id("box0"))
            );
        }

        [TestMethod]
        public void Sleep()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Thread.Sleep(1000);

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Implicit()
        {
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
            
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Explicit()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2));
            wait.Until(d => revealed.Displayed);

            revealed.SendKeys("Displayed");
            Assert.AreEqual("Displayed", revealed.GetDomProperty("value"));
        }

        [TestMethod]
        public void ExplicitOptions()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2))
            {
                PollingInterval = TimeSpan.FromMilliseconds(300),
            };
            wait.IgnoreExceptionTypes(typeof(ElementNotInteractableException));

            wait.Until(d => {
                revealed.SendKeys("Displayed");
                return true;
            });

            Assert.AreEqual("input", revealed.TagName);
        }
    }
}
```

```rb
    driver.manage.timeouts.implicit_wait = 2
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/waits/waits_spec.rb#L28)

##### /examples/ruby/spec/waits/waits\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Waits' do
  let(:driver) { start_session }

  it 'fails' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    expect {
      driver.find_element(id: 'box0')
    }.to raise_error(Selenium::WebDriver::Error::NoSuchElementError)
  end

  it 'sleeps' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    sleep 1
    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'implicit' do
    driver.manage.timeouts.implicit_wait = 2
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    wait = Selenium::WebDriver::Wait.new
    wait.until { revealed.displayed? }

    revealed.send_keys('Displayed')
    expect(revealed.property(:value)).to eq('Displayed')
  end

  it 'options with explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    errors = [Selenium::WebDriver::Error::NoSuchElementError,
              Selenium::WebDriver::Error::ElementNotInteractableError]
    wait = Selenium::WebDriver::Wait.new(timeout: 2,
                                         interval: 0.3,
                                         ignore: errors)

    wait.until { revealed.send_keys('Displayed') || true }

    expect(revealed.property(:value)).to eq('Displayed')
  end
end
```

```js
        await driver.manage().setTimeouts({ implicit: 2000 });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/waits/waits.spec.js#L39)

##### /examples/javascript/test/waits/waits.spec.js

```js

const { By, Browser, until, Builder} = require('selenium-webdriver');
const assert = require("node:assert");


describe('Waits', function () {
    let driver;

    before(async function () {
        driver = new Builder()
          .forBrowser(Browser.CHROME)
          .build();
    });

    after(async () => await driver.quit());

    it('fail', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        await assert.rejects(async () => {
              await driver.findElement(By.id("box0"))
          },
          Error
        )
    });

    it('sleep', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        await driver.sleep(2000);
        let added = await driver.findElement(By.id("box0"));

        assert.equal(await added.getAttribute('class'), "redbox")
    });

    it('implicit', async function () {
        await driver.manage().setTimeouts({ implicit: 2000 });
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        let added = await driver.findElement(By.id("box0"));

        assert.equal(await added.getAttribute('class'), "redbox")
    });

    it('explicit', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        let revealed = await driver.findElement(By.id("revealed"));
        await driver.findElement(By.id("reveal")).click();
        await driver.wait(until.elementIsVisible(revealed), 2000);
        await revealed.sendKeys("Displayed");
        assert.equal(await revealed.getAttribute("value"), "Displayed")
    })
});
```

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk/examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt#L19)

##### examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt

```kt
```

This example shows the condition being waited for as a *lambda*. Java also supports [Expected Conditions](https://www.selenium.dev/pt-br/documentation/webdriver/support_features/expected_conditions/)

```java
    Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    wait.until(d -> revealed.isDisplayed());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L67-L68)

##### /examples/java/src/test/java/dev/selenium/waits/WaitsTest.java

```java
package dev.selenium.waits;

import dev.selenium.BaseTest;
import java.time.Duration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.ElementNotInteractableException;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

public class WaitsTest extends BaseTest {
  @Test
  public void fails() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Assertions.assertThrows(
        NoSuchElementException.class,
        () -> {
          driver.findElement(By.id("box0"));
        });
  }

  @Test
  public void sleep() throws InterruptedException {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Thread.sleep(1000);

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void implicit() {
    startChromeDriver(new ChromeOptions());

    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void explicit() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    wait.until(d -> revealed.isDisplayed());

    revealed.sendKeys("Displayed");
    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }

  @Test
  public void explicitWithOptions() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait =
        new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(2))
            .pollingEvery(Duration.ofMillis(300))
            .ignoring(ElementNotInteractableException.class);

    wait.until(
        d -> {
          revealed.sendKeys("Displayed");
          return true;
        });

    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }
}
```

This example shows the condition being waited for as a *lambda*. Python also supports [Expected Conditions](https://www.selenium.dev/pt-br/documentation/webdriver/support_features/expected_conditions/)

```py
    wait = WebDriverWait(driver, timeout=2)
    wait.until(lambda _ : revealed.is_displayed())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/waits/test_waits.py#L41-L42)

##### /examples/python/tests/waits/test\_waits.py

```py
import pytest
import time
from selenium.common import NoSuchElementException, ElementNotInteractableException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


def test_fails(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    with pytest.raises(NoSuchElementException):
        driver.find_element(By.ID, 'box0')


def test_sleep(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    time.sleep(2)
    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_implicit(driver):
    driver.implicitly_wait(2)
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_explicit(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(lambda _ : revealed.is_displayed())

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"


def test_explicit_options(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    errors = [NoSuchElementException, ElementNotInteractableException]
    wait = WebDriverWait(driver, timeout=2, poll_frequency=.2, ignored_exceptions=errors)
    wait.until(lambda _ : revealed.send_keys("Displayed") or True)

    assert revealed.get_property("value") == "Displayed"
```

```cs
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2));
            wait.Until(d => revealed.Displayed);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L56-L57)

##### /examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs

```cs
using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Waits
{
    [TestClass]
    public class WaitsTest : BaseChromeTest
    {
        [TestMethod]
        public void Fails()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Assert.ThrowsException<NoSuchElementException>(
                () => driver.FindElement(By.Id("box0"))
            );
        }

        [TestMethod]
        public void Sleep()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Thread.Sleep(1000);

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Implicit()
        {
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
            
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Explicit()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2));
            wait.Until(d => revealed.Displayed);

            revealed.SendKeys("Displayed");
            Assert.AreEqual("Displayed", revealed.GetDomProperty("value"));
        }

        [TestMethod]
        public void ExplicitOptions()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2))
            {
                PollingInterval = TimeSpan.FromMilliseconds(300),
            };
            wait.IgnoreExceptionTypes(typeof(ElementNotInteractableException));

            wait.Until(d => {
                revealed.SendKeys("Displayed");
                return true;
            });

            Assert.AreEqual("input", revealed.TagName);
        }
    }
}
```

```rb
    wait = Selenium::WebDriver::Wait.new
    wait.until { revealed.displayed? }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/waits/waits_spec.rb#L42-L43)

##### /examples/ruby/spec/waits/waits\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Waits' do
  let(:driver) { start_session }

  it 'fails' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    expect {
      driver.find_element(id: 'box0')
    }.to raise_error(Selenium::WebDriver::Error::NoSuchElementError)
  end

  it 'sleeps' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    sleep 1
    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'implicit' do
    driver.manage.timeouts.implicit_wait = 2
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    wait = Selenium::WebDriver::Wait.new
    wait.until { revealed.displayed? }

    revealed.send_keys('Displayed')
    expect(revealed.property(:value)).to eq('Displayed')
  end

  it 'options with explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    errors = [Selenium::WebDriver::Error::NoSuchElementError,
              Selenium::WebDriver::Error::ElementNotInteractableError]
    wait = Selenium::WebDriver::Wait.new(timeout: 2,
                                         interval: 0.3,
                                         ignore: errors)

    wait.until { revealed.send_keys('Displayed') || true }

    expect(revealed.property(:value)).to eq('Displayed')
  end
end
```

JavaScript also supports [Expected Conditions](https://www.selenium.dev/pt-br/documentation/webdriver/support_features/expected_conditions/)

```js
        await driver.wait(until.elementIsVisible(revealed), 2000);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/waits/waits.spec.js#L52)

##### /examples/javascript/test/waits/waits.spec.js

```js

const { By, Browser, until, Builder} = require('selenium-webdriver');
const assert = require("node:assert");


describe('Waits', function () {
    let driver;

    before(async function () {
        driver = new Builder()
          .forBrowser(Browser.CHROME)
          .build();
    });

    after(async () => await driver.quit());

    it('fail', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        await assert.rejects(async () => {
              await driver.findElement(By.id("box0"))
          },
          Error
        )
    });

    it('sleep', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        await driver.sleep(2000);
        let added = await driver.findElement(By.id("box0"));

        assert.equal(await added.getAttribute('class'), "redbox")
    });

    it('implicit', async function () {
        await driver.manage().setTimeouts({ implicit: 2000 });
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        let added = await driver.findElement(By.id("box0"));

        assert.equal(await added.getAttribute('class'), "redbox")
    });

    it('explicit', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        let revealed = await driver.findElement(By.id("revealed"));
        await driver.findElement(By.id("reveal")).click();
        await driver.wait(until.elementIsVisible(revealed), 2000);
        await revealed.sendKeys("Displayed");
        assert.equal(await revealed.getAttribute("value"), "Displayed")
    })
});
```

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk/examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt#L36-L37)

##### examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt

```kt
```

```java
    Wait<WebDriver> wait =
        new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(2))
            .pollingEvery(Duration.ofMillis(300))
            .ignoring(ElementNotInteractableException.class);

    wait.until(
        d -> {
          revealed.sendKeys("Displayed");
          return true;
        });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L82-L92)

##### /examples/java/src/test/java/dev/selenium/waits/WaitsTest.java

```java
package dev.selenium.waits;

import dev.selenium.BaseTest;
import java.time.Duration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.ElementNotInteractableException;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

public class WaitsTest extends BaseTest {
  @Test
  public void fails() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Assertions.assertThrows(
        NoSuchElementException.class,
        () -> {
          driver.findElement(By.id("box0"));
        });
  }

  @Test
  public void sleep() throws InterruptedException {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Thread.sleep(1000);

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void implicit() {
    startChromeDriver(new ChromeOptions());

    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void explicit() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    wait.until(d -> revealed.isDisplayed());

    revealed.sendKeys("Displayed");
    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }

  @Test
  public void explicitWithOptions() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait =
        new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(2))
            .pollingEvery(Duration.ofMillis(300))
            .ignoring(ElementNotInteractableException.class);

    wait.until(
        d -> {
          revealed.sendKeys("Displayed");
          return true;
        });

    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }
}
```

```py
    errors = [NoSuchElementException, ElementNotInteractableException]
    wait = WebDriverWait(driver, timeout=2, poll_frequency=.2, ignored_exceptions=errors)
    wait.until(lambda _ : revealed.send_keys("Displayed") or True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/waits/test_waits.py#L53-L55)

##### /examples/python/tests/waits/test\_waits.py

```py
import pytest
import time
from selenium.common import NoSuchElementException, ElementNotInteractableException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


def test_fails(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    with pytest.raises(NoSuchElementException):
        driver.find_element(By.ID, 'box0')


def test_sleep(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    time.sleep(2)
    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_implicit(driver):
    driver.implicitly_wait(2)
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_explicit(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(lambda _ : revealed.is_displayed())

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"


def test_explicit_options(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    errors = [NoSuchElementException, ElementNotInteractableException]
    wait = WebDriverWait(driver, timeout=2, poll_frequency=.2, ignored_exceptions=errors)
    wait.until(lambda _ : revealed.send_keys("Displayed") or True)

    assert revealed.get_property("value") == "Displayed"
```

```cs
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2))
            {
                PollingInterval = TimeSpan.FromMilliseconds(300),
            };
            wait.IgnoreExceptionTypes(typeof(ElementNotInteractableException));

            wait.Until(d => {
                revealed.SendKeys("Displayed");
                return true;
            });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L70-L79)

##### /examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs

```cs
using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Waits
{
    [TestClass]
    public class WaitsTest : BaseChromeTest
    {
        [TestMethod]
        public void Fails()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Assert.ThrowsException<NoSuchElementException>(
                () => driver.FindElement(By.Id("box0"))
            );
        }

        [TestMethod]
        public void Sleep()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Thread.Sleep(1000);

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Implicit()
        {
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
            
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Explicit()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2));
            wait.Until(d => revealed.Displayed);

            revealed.SendKeys("Displayed");
            Assert.AreEqual("Displayed", revealed.GetDomProperty("value"));
        }

        [TestMethod]
        public void ExplicitOptions()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2))
            {
                PollingInterval = TimeSpan.FromMilliseconds(300),
            };
            wait.IgnoreExceptionTypes(typeof(ElementNotInteractableException));

            wait.Until(d => {
                revealed.SendKeys("Displayed");
                return true;
            });

            Assert.AreEqual("input", revealed.TagName);
        }
    }
}
```

```rb
    errors = [Selenium::WebDriver::Error::NoSuchElementError,
              Selenium::WebDriver::Error::ElementNotInteractableError]
    wait = Selenium::WebDriver::Wait.new(timeout: 2,
                                         interval: 0.3,
                                         ignore: errors)

    wait.until { revealed.send_keys('Displayed') || true }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/waits/waits_spec.rb#L54-L60)

##### /examples/ruby/spec/waits/waits\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Waits' do
  let(:driver) { start_session }

  it 'fails' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    expect {
      driver.find_element(id: 'box0')
    }.to raise_error(Selenium::WebDriver::Error::NoSuchElementError)
  end

  it 'sleeps' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    sleep 1
    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'implicit' do
    driver.manage.timeouts.implicit_wait = 2
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    wait = Selenium::WebDriver::Wait.new
    wait.until { revealed.displayed? }

    revealed.send_keys('Displayed')
    expect(revealed.property(:value)).to eq('Displayed')
  end

  it 'options with explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    errors = [Selenium::WebDriver::Error::NoSuchElementError,
              Selenium::WebDriver::Error::ElementNotInteractableError]
    wait = Selenium::WebDriver::Wait.new(timeout: 2,
                                         interval: 0.3,
                                         ignore: errors)

    wait.until { revealed.send_keys('Displayed') || true }

    expect(revealed.property(:value)).to eq('Displayed')
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk/examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt#L51-L60)

##### examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt

```kt
```

Última modificação October 31, 2025: [Added Kotlin Code Examples (#2499) (e49b07e4f68)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e49b07e4f68275d61faff820b9b2b640e9d16fb3)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/support_features/expected_conditions/
----

# 期望状态的等待

```py
    wait = WebDriverWait(driver, timeout=2)
    wait.until(EC.visibility_of_element_located((By.ID, "revealed")))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_expected_conditions.py#L14-L15)

##### /examples/python/tests/support/test\_expected\_conditions.py

```py
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

# Expected Conditions API Documentation:
# https://www.selenium.dev/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html


def test_expected_condition(driver):
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html")
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(EC.visibility_of_element_located((By.ID, "revealed")))

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"
```

.NET stopped supporting Expected Conditions in Selenium 4 to minimize maintenance hassle and redundancy.

Ruby makes frequent use of blocks, procs and lambdas and does not need Expected Conditions classes

----
url: https://www.selenium.dev/ja/documentation/webdriver/elements/interactions/
----

# Interacting with web elements

```java
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L18-L22)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L12-L17)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L17-L21)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'color_input').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L11)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
    await submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L20)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
  const assert = require("assert");
  
  (async function firstTest() {
    let driver;
    
    try {
      driver = await new Builder().forBrowser(Browser.CHROME).build();
      await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
    
      let title = await driver.getTitle();
      assert.equal("Web form", title);
    
      await driver.manage().setTimeouts({implicit: 500});
    
      let textBox = await driver.findElement(By.name('my-text'));
      let submitButton = await driver.findElement(By.css('button'));
    
      await textBox.sendKeys('Selenium');
      await submitButton.click();
    
      let message = await driver.findElement(By.id('message'));
      let value = await message.getText();
      assert.equal("Received!", value);
    } catch (e) {
      console.log(e)
    } finally {
      await driver.quit();
    }
  }())
  
```

```kotlin
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    // Click the element
    driver.findElement(By.name("color_input")).click();
  
  
```

```java
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L27-L32)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L22-L27)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L27-L33)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L16)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
      let inputField = await driver.findElement(By.name('no_type'));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/interactions.spec.js#L21)

##### /examples/javascript/test/elements/interactions.spec.js

```js

  const {By, Browser, Builder} = require('selenium-webdriver');
  const assert = require("node:assert");
  
  
  describe('Element Interactions', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('should Clear input and send keys into input field', async function () {
  
      try {
        await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
        let inputField = await driver.findElement(By.name('no_type'));
        await inputField.clear();
        await inputField.sendKeys('Selenium');
        const text = await inputField.getAttribute('value');
        assert.strictEqual(text, "Selenium");
      } catch (e) {
        console.log(e)
      }
    });
  });
```

```kotlin
  
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

	//Clear field to empty it from any previous data
	driver.findElement(By.name("email_input")).clear()
	
    // Enter text 
    driver.findElement(By.name("email_input")).sendKeys("admin@localhost.dev")
  
  
```

```java
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L38-L40)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    email_input.clear()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L34)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L40-L43)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'email_input').clear
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L15)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
      await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/interactions.spec.js#L20)

##### /examples/javascript/test/elements/interactions.spec.js

```js

  const {By, Browser, Builder} = require('selenium-webdriver');
  const assert = require("node:assert");
  
  
  describe('Element Interactions', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('should Clear input and send keys into input field', async function () {
  
      try {
        await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
        let inputField = await driver.findElement(By.name('no_type'));
        await inputField.clear();
        await inputField.sendKeys('Selenium');
        const text = await inputField.getAttribute('value');
        assert.strictEqual(text, "Selenium");
      } catch (e) {
        console.log(e)
      }
    });
  });
```

```kotlin
  
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

	//Clear field to empty it from any previous data
	driver.findElement(By.name("email_input")).clear()
	
  
  
```

## Submit

In Selenium 4 this is no longer implemented with a separate endpoint and functions by executing a script. As such, it is recommended not to use this method and to click the applicable form submission button instead.

最終更新 September 6, 2025: [changed editable to keyboard interactable as per W3C doc (#2472) (5e333fc2769)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/5e333fc2769a9e0ca541477eb2bfc5220da04951)

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/
----

# Diretrizes e recomendações

Guias e recomendações ao preparar soluções de testes com o projecto Selenium.

Uma nota sobre “Melhores práticas”: evitamos intencionalmente a frase “Melhores Práticas” nesta documentação. Nenhuma abordagem funciona para todas as situações. Preferimos a ideia de “Diretrizes e Recomendações”. Nós encorajamos que você leia e decida cuidadosamente quais abordagens funcionarão para você em seu ambiente específico.

O teste funcional é difícil de acertar por muitos motivos. Como se o estado, a complexidade e as dependências do aplicativo não tornassem o teste suficientemente difícil, lidar com navegadores (especialmente com incompatibilidades entre navegadores) torna a escrita de bons testes um desafio.

Selenium fornece ferramentas para facilitar a interação funcional do usuário, mas não o ajuda a escrever suítes de teste bem arquitetadas. Neste capítulo, oferecemos conselhos, diretrizes e recomendações sobre como abordar a automação funcional de páginas da web.

Este capítulo registra os padrões de design de software populares entre muitos dos usuários do Selenium que tiveram sucesso ao longo dos anos.

***

##### [Design patterns and development strategies](/pt-br/documentation/test_practices/design_strategies/)

##### [Sobre automação de testes](/pt-br/documentation/test_practices/overview/)

##### [Tipos de teste](/pt-br/documentation/test_practices/testing_types/)

##### [Diretrizes e recomendações](/pt-br/documentation/test_practices/encouraged/)

Guias e recomendações ao preparar soluções de testes com o projecto Selenium.

##### [Piores práticas](/pt-br/documentation/test_practices/discouraged/)

Temas a evitar quando automatizar navegadores com Selenium.

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/encouraged/
----

# Diretrizes e recomendações

Guias e recomendações ao preparar soluções de testes com o projecto Selenium.

Uma nota sobre “Melhores práticas”: evitamos intencionalmente a frase “Melhores Práticas” nesta documentação. Nenhuma abordagem funciona para todas as situações. Preferimos a ideia de “Diretrizes e Recomendações”. Nós encorajamos que você leia e decida cuidadosamente quais abordagens funcionarão para você em seu ambiente específico.

O teste funcional é difícil de acertar por muitos motivos. Como se o estado, a complexidade e as dependências do aplicativo não tornassem o teste suficientemente difícil, lidar com navegadores (especialmente com incompatibilidades entre navegadores) torna a escrita de bons testes um desafio.

Selenium fornece ferramentas para facilitar a interação funcional do usuário, mas não o ajuda a escrever suítes de teste bem arquitetadas. Neste capítulo, oferecemos conselhos, diretrizes e recomendações sobre como abordar a automação funcional de páginas da web.

Este capítulo registra os padrões de design de software populares entre muitos dos usuários do Selenium que tiveram sucesso ao longo dos anos.

***

##### [Modelos de objetos de página](/pt-br/documentation/test_practices/encouraged/page_object_models/)

##### [Linguagem específica de domínio (DSL)](/pt-br/documentation/test_practices/encouraged/domain_specific_language/)

##### [Gerando estado da aplicação](/pt-br/documentation/test_practices/encouraged/generating_application_state/)

##### [Simulação de serviços externos](/pt-br/documentation/test_practices/encouraged/mock_external_services/)

##### [Relatórios melhorados](/pt-br/documentation/test_practices/encouraged/improved_reporting/)

##### [Evite compartilhamento de estado](/pt-br/documentation/test_practices/encouraged/avoid_sharing_state/)

##### [Tips on working with locators](/pt-br/documentation/test_practices/encouraged/locators/)

When to use which locators and how best to manage them in your code.

##### [Independência de Testes](/pt-br/documentation/test_practices/encouraged/test_independency/)

##### [Considere usar uma API fluente](/pt-br/documentation/test_practices/encouraged/consider_using_a_fluent_api/)

##### [Navegador novo por teste](/pt-br/documentation/test_practices/encouraged/fresh_browser_per_test/)

----
url: https://www.selenium.dev/pt-br/documentation/ide/
----

# Selenium IDE

Selenium IDE é uma extensão do navegador que grava e reproduz uma acção do utilizador.

Selenium’s Integrated Development Environment ([Selenium IDE](//selenium.dev/selenium-ide)) é uma ferramenta de utilização simples que grava as acções de um utilizador usando comandos Selenium com parametros definidos conforme o contexto de cada elemento. Esta é uma forma excelente de aprender todo o sintaxe Selenium. Está disponível para os navegadores Google Chrome, Mozilla Firefox, e Microsoft Edge.

Para mais informações, visite a [Documentação Selenium IDE](https://www.selenium.dev/selenium-ide/docs/en/introduction/getting-started).

Última modificação November 10, 2022: [Translate IDE documentation (#1222) (27f32a5e4d9)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/27f32a5e4d9e0e847cd4d5894f0d55335c4b8cdf)

----
url: https://www.selenium.dev/zh-cn/documentation/grid/advanced_features/
----

# 高级功能

要获得高级功能的所有详细信息, 了解其工作原理, 以及如何设置自己的功能, 请浏览以下部分.

***

##### [可观测性](/zh-cn/documentation/grid/advanced_features/observability/)

##### [GraphQL查询支持](/zh-cn/documentation/grid/advanced_features/graphql_support/)

##### [Grid端点](/zh-cn/documentation/grid/advanced_features/endpoints/)

##### [自定义Node](/zh-cn/documentation/grid/advanced_features/customize_node/)

##### [External datastore](/zh-cn/documentation/grid/advanced_features/external_datastore/)

----
url: https://www.selenium.dev/ja/documentation/webdriver/getting_started/using_selenium/
----

# Seleniumコードの整理と実行

IDEとテストランナーライブラリを使用したSelenium実行のスケーリング

一握り以上の 1 回限りのスクリプトを実行する場合は、コードを整理して操作できる必要があります。このページでは、Seleniumコードを使用して実際に生産的なことを行う方法についてのアイデアを提供します。

## 一般的な用途

ほとんどの人はSeleniumを使用してWebアプリケーションの自動テストを実行します。 しかし、Seleniumはブラウザ自動化のあらゆるユースケースをサポートします。

### 反復タスク

おそらく、Webサイトにログインして何かをダウンロードするか、フォームを送信する必要があります。 Selenium スクリプトを作成して、あらかじめ設定された時間にサービスと共に実行できます。

### Webスクレイピング

APIがないサイトからデータを収集したいとお考えですか?セレン これを行うことができますが、Webサイトに精通していることを確認してください。 一部のWebサイトでは許可されておらず、他のWebサイトではSeleniumがブロックされることさえあります。

### テスティング

テストのためにSeleniumを実行するには、Seleniumが実行したアクションに対してアサーションを行う必要があります。 したがって、優れたアサーションライブラリが必要です。テストの構造を提供する追加機能 使用する必要があります [Test Runner](/ja/documentation/webdriver/getting_started/using_selenium/#test-runner).

## IDEs

Seleniumコードの使用方法に関係なく、優れた統合開発環境がなければ、Seleniumコードの作成や実行はあまり効果的ではありません。一般的なオプションを次に示します…

テストにSeleniumを使用していない場合でも、高度なユースケースがある場合は、テストランナーを使用してコードをより適切に整理するのが理にかなっている場合があります。before/after フックを使用して、グループまたは並行して物事を実行できると非常に便利です。

### 卜

さまざまなテストランナーが利用可能です。

このドキュメントのすべてのコード例は、 テストランナーを使用し、すべてのコードが正しく更新されていることを確認するためにリリースごとに実行されるディレクトリの例。 リンク付きのテストランナーのリストを次に示します。最初の項目は、このリポジトリで使用される項目と このページのすべての例で使用されます。

*
*
*
*
*
*

- [JUnit](https://junit.org/junit5/) - JavaベースのSeleniumテストで広く使用されているテストフレームワーク。
- [TestNG](https://testng.org/) - 並列テスト実行やパラメーター化されたテストなどの追加機能を提供します。

* [pytest](https://pytest.org/) - そのシンプルさと強力なプラグインのおかげで、多くの人に好まれる選択肢です。
* [unittest](https://docs.python.org/3/library/unittest.html) - Python の標準ライブラリテストフレームワーク。

- [NUnit](https://nunit.org/) - .NET の一般的な単体テスト フレームワーク。
- [MS Test](https://docs.microsoft.com/en-us/visualstudio/test/getting-started-with-unit-testing?view=vs-2019) - Microsoft 独自の単体テスト フレームワーク。

* [RSpec](https://rspec.info/) - RubyでSeleniumテストを実行するために最も広く使用されているテストライブラリ。
* [Minitest](https://github.com/seattlerb/minitest) - Ruby標準ライブラリに付属する軽量なテストフレームワークです。

- [Jest](https://jestjs.io/) - 主にReactのテストフレームワークとして知られていますが、Seleniumのテストにも使用できます。
- [Mocha](https://mochajs.org/) - Seleniumテストを実行するための最も一般的なJSライブラリ。

* [Kotest](https://kotest.io/) - Kotlin専用に設計された、柔軟で包括的なテストフレームワークです。
* [JUnit5](https://junit.org/junit5/) - 標準的なJavaテストフレームワークであり、Kotlinと完全に互換性があります。

### 装着

これは、で必要とされたものと非常によく似ています [Seleniumライブラリのインストール](https://www.selenium.dev/ja/documentation/webdriver/getting_started/install_library/)。このコードは、私たちのドキュメント例プロジェクトで使用されているものの例を示しているだけです。

プロジェクトで使用するには、requirements.txt ファイルに追加します:

プロジェクトの ‘csproj’ ファイルで、依存関係を ‘ItemGroup’ の ‘PackageReference’ として指定します:

プロジェクトの gemfile に追加

プロジェクトの ‘package.json’ で、要件を ‘dependencies’ に追加します。:

### 主張

*
*
*
*
*
*

```java
		String title = driver.getTitle();
		assertEquals("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L30-L31)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java
package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

```py
    title = driver.title
    assert title == "Web form"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L8-L9)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

```cs
            var title = driver.Title;
            Assert.AreEqual("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs#L19-L20)

##### /examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted
{
    [TestClass]
    public class UsingSeleniumTest
    {

        [TestMethod]
        public void EightComponents()
        {
            IWebDriver driver = new ChromeDriver();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

            var title = driver.Title;
            Assert.AreEqual("Web form", title);

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            var textBox = driver.FindElement(By.Name("my-text"));
            var submitButton = driver.FindElement(By.TagName("button"));
            
            textBox.SendKeys("Selenium");
            submitButton.Click();
            
            var message = driver.FindElement(By.Id("message"));
            var value = message.Text;
            Assert.AreEqual("Received!", value);
            
            driver.Quit();
        }
    }
}
```

```rb
    title = @driver.title
    expect(title).to eq('Web form')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb#L14-L15)

##### /examples/ruby/spec/getting\_started/using\_selenium\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

```js
    let title = await driver.getTitle();
    assert.equal("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L14-L15)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

```kt
        val title = driver.title
        assertEquals("Web form", title)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L20-21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

### セットアップとティアダウン

*
*
*
*
*
*

### 並べる

```java
	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L19-L22)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java
package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

### 取り壊す

```java
	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L45-L48)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java
package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

### 並べる

```py
def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L25-L28)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

### 取り壊す

```py
def teardown(driver):
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L30-31)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

### 並べる

```rb
  before do
    @driver = Selenium::WebDriver.for :chrome
  end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb#L7-L9)

##### /examples/ruby/spec/getting\_started/using\_selenium\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

### 取り壊す

```rb
  config.after { @driver&.quit }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/spec_helper.rb#L30)

##### /examples/ruby/spec/spec\_helper.rb

```rb
# frozen_string_literal: true

require 'selenium-webdriver'
require 'selenium/webdriver/support/guards'

RSpec.configure do |config|
  # Enable flags like --only-failures and --next-failure
  config.example_status_persistence_file_path = '.rspec_status'

  # Disable RSpec exposing methods globally on `Module` and `main`
  config.disable_monkey_patching!
  Dir.mktmpdir('tmp')
  config.example_status_persistence_file_path = 'tmp/examples.txt'

  config.expect_with :rspec do |c|
    c.syntax = :expect
  end

  config.before do |example|
    bug_tracker = 'https://github.com/SeleniumHQ/seleniumhq.github.io/issues'
    guards = Selenium::WebDriver::Support::Guards.new(example,
                                                      bug_tracker: bug_tracker)
    guards.add_condition(:platform, Selenium::WebDriver::Platform.os)
    guards.add_condition(:ci, Selenium::WebDriver::Platform.ci)

    results = guards.disposition
    send(*results) if results
  end

  config.after { @driver&.quit }

  def start_session
    options = Selenium::WebDriver::Chrome::Options.new
    options.add_argument('disable-search-engine-choice-screen')
    options.add_argument('--no-sandbox')
    @driver = Selenium::WebDriver.for(:chrome, options: options)
  end

  def start_bidi_session
    options = Selenium::WebDriver::Chrome::Options.new(web_socket_url: true)
    @driver = Selenium::WebDriver.for :chrome, options: options
  end

  def start_firefox
    options = Selenium::WebDriver::Options.firefox(timeouts: {implicit: 1500})
    @driver = Selenium::WebDriver.for :firefox, options: options
  end
end
```

\### 並べる

```js
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L7-L9)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

\### 取り壊す

```js
  after(async () => await driver.quit());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L30)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

### 実行

```shell
mvn clean test
```

### Gradle

```shell
gradle clean test
```

````md
```
````

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/README.md#L35)

##### /examples/python/README.md

````md
# Running tests from Selenium Python examples

#### 1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

#### 2. Navigate to `python` directory

```
cd seleniumhq.github.io/examples/python
```

#### 3. Create a virtual environment

- On Windows:

```
py -m venv venv
venv\Scripts\activate
```

- On Linux/Mac:

```
python3 -m venv venv
source venv/bin/activate
```

#### 4. Install dependencies:

```
pip install -r requirements.txt
```

> for help, see: https://packaging.python.org/en/latest/tutorials/installing-packages

#### 5. Run tests

- Run all tests with the default Python interpreter:

```
pytest
```

- Run all tests with every installed/supported Python interpreter:

```
tox
```

> Please have some patience - If you are doing it for the first time, it will take a little while to download the browser drivers

- Run a specific example:

```
pytest path/to/test_script.py
```

> Make sure to replace `path/to/test_script.py` with the path and name of the example you want to run
````

```md
dotnet test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/README.md#L44)

##### /examples/dotnet/README.md

````md

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

## Navigate to the .NET directory
### Change into the .NET examples directory:

```bash
cd seleniumhq.github.io/examples/dotnet/SeleniumDocs
```

## Running the Tests
### Restore dependencies
Install necessary dependencies using the .NET CLI:

```bash
dotnet restore
```

### Run all tests
To run all available tests:

```bash
dotnet test
```

### Run a Specific Test Method
To run a specific test method using its fully qualified name:

```bash
dotnet test --filter "FullyQualifiedName=Namespace.ClassName.MethodName"
```
For example:
```bash
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

You can also filter by test name only (if it's unique):
```bash
dotnet test --filter "Name=EightComponents"
```
````

```md
bundle exec rspec
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/README.md#L26)

##### /examples/ruby/README.md

````md
# Running all tests from Selenium ruby example

Follow these steps to run all test example from selenium ruby

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `ruby` directory

```
cd seleniumhq.github.io/examples/ruby
```

3. Install dependencies using bundler

```
bundler install
```

4. Run all tests

```
bundle exec rspec
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a ruby script

Use this command to run a ruby script and follow the first script example

```
ruby example_script.rb
```
````

### Mocha

```shell
mocha runningTests.spec.js
```

### npx

```shell
npx mocha runningTests.spec.js
```

[Add Example](/documentation/about/contributing/#creating-examples)

### 例

[最初のスクリプト](https://www.selenium.dev/ja/documentation/webdriver/getting_started/first_script/)のトピックでは、Seleniumスクリプトの各コンポーネントを見ました。こちらが、テストランナーを使用したそのコードの例です。

*
*
*
*
*
*

```java

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java)

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py)

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted
{
    [TestClass]
    public class UsingSeleniumTest
    {

        [TestMethod]
        public void EightComponents()
        {
            IWebDriver driver = new ChromeDriver();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

            var title = driver.Title;
            Assert.AreEqual("Web form", title);

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            var textBox = driver.FindElement(By.Name("my-text"));
            var submitButton = driver.FindElement(By.TagName("button"));
            
            textBox.SendKeys("Selenium");
            submitButton.Click();
            
            var message = driver.FindElement(By.Id("message"));
            var value = message.Text;
            Assert.AreEqual("Received!", value);
            
            driver.Quit();
        }
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs)

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb)

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js)

[Add Example](/documentation/about/contributing/#creating-examples)

## 次のステップ

学んだことを活かして、Seleniumコードを構築します!

必要な機能が他にも見つかったら、残りの機能をお読みください [WebDriver ドキュメント](https://www.selenium.dev/ja/documentation/webdriver/).

最終更新 February 25, 2026: [Update "Using Selenium" documentation with C# example from .NET README (#2584) (e1d46ea60e4)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e1d46ea60e47ff168113cd1e609b27a142527573)

## Development Partners

[](https://www.browserstack.com/automate?utm_campaign=open-source-sponsor\&utm_campaigncode=701OW000009sQwVYAU\&utm_medium=partnered\&utm_source=seleniumorg)

[](https://saucelabs.com/resources/topic-hub/selenium?utm_source=selenium\&utm_medium=website\&utm_campaign=selenium-sponsorship-fy25)

[](https://www.testmuai.com)

## Selenium Level Sponsors

[](https://brightdata.com/?utm_source=brand\&utm_campaign=brnd-mkt_partners_selenium)

[](https://applitools.com/)

[](https://www.thordata.com/?ls=waOicIkB\&lk=selenium)

## Support the Selenium Project

Learn more or view the full list of sponsors.

[Learn more**](/sponsors)

----
url: https://www.selenium.dev/_print/documentation/about/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/about/).

# About this documentation

* 1: [Copyright and attributions](#pg-26d70545dd5f0d9b5b7391240d76f67f)
* 2: [Contributing to the Selenium site & documentation](#pg-2ba7a4429edcdba1494489ed25ace7f6)
* 3: [Style guide for Selenium documentation](#pg-1054872413722ea7fd2a89d80ab21a15)
* 4: [Musings about how things came to be](#pg-899420190d53ce8062971b72e398e81d)

These docs, like the code itself, are maintained 100% by volunteers within the Selenium community. Many have been using it since its inception, but many more have only been using it for a short while, and have given their time to help improve the onboarding experience for new users.

If there is an issue with the documentation, we want to know! The best way to communicate an issue is to visit [https://github.com/seleniumhq/seleniumhq.github.io/issues](//github.com/seleniumhq/seleniumhq.github.io/issues) and search to see whether or not the issue has been filed already. If not, feel free to open one!

Many members of the community are present at the #selenium-docs channel of [Selenium Slack Group](https://inviter.co/seleniumhq). Feel free to drop in and ask questions and if you get help which you think could be of use within these documents, be sure to add your contribution! We can update these documents, but it is much easier for everyone when we get contributions from outside the normal committers.

# 1 - Copyright and attributions

| Software                            | Version  | License                                                     |
| ----------------------------------- | -------- | ----------------------------------------------------------- |
| [Hugo](/)                           | v0.110.0 | [Apache 2.0](//gohugo.io/about/license/)                    |
| [Docsy](//github.com/google/docsy/) | —        | [Apache 2.0](//github.com/google/docsy/blob/master/LICENSE) |

## License

All code and documentation originating from the Selenium project is licensed under the Apache 2.0 license, with the [Software Freedom Conservancy](/) as the copyright holder.

The license is included here for convenience, but you can also find it on the [Apache Foundation’s websites](//apache.org/licenses/LICENSE-2.0.html):

```markdown
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
```

# 2 - Contributing to the Selenium site & documentation

Information on improving documentation and code examples for Selenium

Selenium is a big software project, its site and documentation are key to understanding how things work and learning effective ways to exploit its potential.

This project contains both Selenium’s site and documentation. This is an ongoing effort (not targeted at any specific release) to provide updated information on how to use Selenium effectively, how to get involved and how to contribute to Selenium.

Contributions toward the site and docs follow the process described in the below section about contributions.

***

```
    {{< tab header="Ruby" >}}
    {{< gh-codeblock path="/examples/ruby/spec/browsers/chrome_spec.rb#L8-L9" >}}
    {{< /tab >}}
```

```shell
% git clone git@github.com:seleniumhq/seleniumhq.github.io.git
% cd seleniumhq.github.io
```

#### Dependencies: Hugo

We use [Hugo](https://gohugo.io/) and the [Docsy theme](https://www.docsy.dev/) to build and render the site. You will need the “extended” Sass/SCSS version of the Hugo binary to work on this site. We recommend to use Hugo 0.148.2 .

Please follow the [Install Hugo](https://www.docsy.dev/docs/getting-started/#install-hugo) instructions from Docsy.

### Step 2: Branch

Create a feature branch and start hacking:

```shell
% git checkout -b my-feature-branch
```

We practice HEAD-based development, which means all changes are applied directly on top of `dev`.

### Step 3: Make changes

The repository contains the site and docs. To make changes to the site, work on the `website_and_docs` directory. To see a live preview of your changes, run `hugo server` on the site’s root directory.

```shell
% cd website_and_docs
% hugo server
```

The project loads code from GitHub, if that code has been updated, and it isn’t reflected in your preview, you can run hugo without the cache: `hugo server --ignoreCache`

See [Style Guide](https://www.selenium.dev/documentation/about/style/) for more information on our conventions for contribution

### Step 4: Commit

First make sure git knows your name and email address:

```shell
% git config --global user.name 'Santa Claus'
% git config --global user.email 'santa@example.com'
```

**Writing good commit messages is important.** A commit message should describe what changed, why, and reference issues fixed (if any). Follow these guidelines when writing one:

1. The first line should be around 50 characters or less and contain a short description of the change.
2. Keep the second line blank.
3. Wrap all other lines at 72 columns.
4. Include `Fixes #N`, where *N* is the issue number the commit fixes, if any.

A good commit message can look like this:

```text
explain commit normatively in one line

Body of commit message is a few lines of text, explaining things
in more detail, possibly giving some background about the issue
being fixed, etc.

The body of the commit message can be several paragraphs, and
please do proper word-wrap and keep columns shorter than about
72 characters or so. That way `git log` will show things
nicely even when it is indented.

Fixes #141
```

The first line must be meaningful as it’s what people see when they run `git shortlog` or `git log --oneline`.

### Step 5: Rebase

Use `git rebase` (not `git merge`) to sync your work from time to time.

```shell
% git fetch origin
% git rebase origin/trunk
```

### Step 6: Test

Always remember to [run the local server](https://gohugo.io/getting-started/usage/#livereload), with this you can be sure that your changes have not broken anything.

### Step 7: Push

```shell
% git push origin my-feature-branch
```

Go to <https://github.com/yourusername/seleniumhq.github.io.git> and press the *Pull Request* and fill out the form. **Please indicate that you’ve signed the CLA** (see Step 7).

Pull requests are usually reviewed within a few days. If there are comments to address, apply your changes in new commits (preferably [fixups](http://git-scm.com/docs/git-commit)) and push to the same branch.

### Step 8: Integration

When code review is complete, a committer will take your PR and integrate it on the repository’s trunk branch. Because we like to keep a linear history on the trunk branch, we will normally squash and rebase your branch history.

## Communication

All details on how to communicate with the project contributors and the community overall can be found at <https://selenium.dev/support>

# 3 - Style guide for Selenium documentation

Conventions for contributions to the Selenium documentation and code examples

Read our [contributing documentation](https://www.selenium.dev/documentation/about/contributing/) for complete instructions on how to add content to this documentation.

## Alerts

Alerts have been added to direct potential contributors to where specific content is missing.

```html
{{< alert-content />}}
```

or

```html
{{< alert-content >}}
Additional information about what specific content is needed
{{< /alert-content >}}
```

```java
WebDriver driver = new ChromeDriver();
```

```python
driver = webdriver.Chrome()
```

```csharp
var driver = new ChromeDriver();
```

```ruby
driver = Selenium::WebDriver.for :chrome
```

```javascript
let driver = await new Builder().forBrowser('chrome').build();
```

```kotlin
val driver = ChromeDriver()
```

To generate the above tabs, this is what you need to write. Note that the `tabpane` includes `langEqualsHeader=true`. This auto-formats the code in each tab to match the header name, and ensures that all tabs on the page with a language are set to the same thing.

```
{{< tabpane langEqualsHeader=true >}}
  {{< tab header="Java" >}}
    WebDriver driver = new ChromeDriver();
  {{< /tab >}}
  {{< tab header="Python" >}}
    driver = webdriver.Chrome()
  {{< /tab >}}
  {{< tab header="CSharp" >}}
    var driver = new ChromeDriver();
  {{< /tab >}}
  {{< tab header="Ruby" >}}
    driver = Selenium::WebDriver.for :chrome
  {{< /tab >}}
  {{< tab header="JavaScript" >}}
    let driver = await new Builder().forBrowser('chrome').build();
  {{< /tab >}}
  {{< tab header="Kotlin" >}}
    val driver = ChromeDriver()
  {{< /tab >}}
{{< /tabpane >}}
```

#### Reference GitHub Examples

To ensure that all code is kept up to date, our goal is to write the code in the repo where it can be executed when Selenium versions are updated to ensure that everything is correct.

All code examples to be in our [example directories](https://github.com/SeleniumHQ/seleniumhq.github.io/tree/dev/examples).

This code can be automatically displayed in the documentation using the `gh-codeblock` shortcode. The shortcode automatically generates its own html, so we do not want it to auto-format with the language header. If all tabs are using this shortcode, set `text=true` in the `tabpane` and remove `langEqualsHeader=true`. If only some tabs are using this shortcode, keep `langEqualsHeader=true` in the `tabpane` and add `text=true` to the `tab`. Note that the `gh-codeblock` line can not be indented at all.

One great thing about using `gh-codeblock` is that it adds a link to the full example. This means you don’t have to include any additional context code, just the line(s) that are needed, and the user can navigate to the repo to see how to use it.

A basic comparison of code looks like:

```
{{< tabpane text=true >}}
{{< tab header="Java" >}}
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-L27" >}}
{{< /tab >}}
{{< tab header="Python" >}}
{{< gh-codeblock path="/examples/python/tests/getting_started/first_script.py#L18-L19" >}}
{{< /tab >}}
{{< tab header="CSharp" >}}
{{< gh-codeblock path="/examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-L26" >}}
{{< /tab >}}
{{< tab header="Ruby" >}}
{{< gh-codeblock path="/examples/ruby/spec/getting_started/first_script.rb#L17-L18" >}}
{{< /tab >}}
{{< tab header="JavaScript" >}}
{{< gh-codeblock path="/examples/javascript/test/getting_started/firstScript.spec.js#L22-L23" >}}
{{< /tab >}}
{{< tab header="Kotlin" >}}
{{< gh-codeblock path="/examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-L32" >}}
{{< /tab >}}
{{< /tabpane >}}
```

```java
        WebElement message = driver.findElement(By.id("message"));
        message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-L27)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
message = driver.find_element(by=By.ID, value="message")
text = message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L18-L19)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-L26)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
message = driver.find_element(id: 'message')
message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L17-L18)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L22-L23)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val message = driver.findElement(By.id("message"))
        val value = message.getText()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-L32)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

### Using Markdown in a Tab

If you want your example to include something other than code (default) or html (from `gh-codeblock`), you need to first set `text=true`, then change the Hugo syntax for the `tab`to use `%` instead of `<` and `>` with curly braces:

```
{{< tabpane text=true >}}
{{% tab header="Java" %}}
1. Start the driver
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12" >}}
2. Navigate to a page
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14" >}}
3. Quit the driver
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29" >}}
{{% /tab %}}
< ... >
{{< /tabpane >}}
```

This produces:

*

1. Start the driver

   ```java
           WebDriver driver = new ChromeDriver();
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

2. Navigate to a page

   ```java
           driver.get("https://www.selenium.dev/selenium/web/web-form.html");
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

3. Quit the driver

   ```java
           driver.quit();
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

This is preferred to writing code comments because those will not be translated. Only include the code that is needed for the documentation, and avoid over-explaining. Finally, remember not to indent plain text or it will rendered as a codeblock.

# 4 - Musings about how things came to be

Details mostly of interest to Selenium devs about how and why certain parts of the project were created

This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/History)

## Introduction

This is a work in progress. Feel free to add things you know or remember.

### How did the Automation Atoms come about?

On 2012-04-04, jimevans asked on the #selenium IRC channel:

> “What I wanted to ask you about was the history of the automation atoms. I seem to remember them springing fully formed, as if from the head of Zeus, and I’m sure that wasn’t the case. Can you refresh my memory as to how the concept happened?”

simonstewart then proceeded to tell us a nice little story:

> Sure. Are we sitting comfortably? Then I’ll begin. (Brit joke, there)

> Imagine wavy lines as the screen dissolves and we’re transported back to when selenium and webdriver were different projects. Before the projects merged, there was an awful lot of congruent code in webdriver. Congruent, but not shared. The Firefox driver was in JS. The IE driver was mostly C++. The Chrome driver was mostly JS, but different JS from the Firefox driver. And HtmlUnit was unique.

> We then added Selenium Core to the mix. Yet more JS that did basically the same thing.

> Within Google, I was becoming the TL of the browser automation team. And was corralling a framework of our own into the mix. Which was written in JS, and had once been based on Core before it span off on its own path.

> So: multiple codebases, lots of JS doing more or less the same thing. And loads of bugs. Weird mismatches of behaviour in edge-cases.

> `*shudder*`

> So I had a bit of a think. (Dangerous, I know) The idea was to extract the “best of breed” code from all three frameworks (Core, WebDriver and the Google tool). Break them down into code that could be shared. “The smallest, indivisible unit of browser automation” .

> Or “atoms” for short.

> These could be used as the basis the *everything*. Consistent behaviour between browsers. and apis. The other important point was that the JS code in webdriver and core was grown organically. Which is a polite way of saying “I’d rather never edit it again”. Which is a polite way of saying that it was of dubious quality . In places.

> So: high quality was important. And I wanted the code broken up into modules. Because editing a 10k LOC file isn’t a bright idea.

> Within Google we had a library called Closure. Which not only allowed modularization, but “denormalization” of modules into a single file via compilation. And I knew it was being open sourced. So we started building the library in the google codebase. (Where we had access to the unreleased library, code review tools and our amazing testing infrastructure). Using Closure Library.

> “dom.js” was probably the first file I wrote. (We can check). Greg Dennis and Jason Leyba joined in the fun. And the atoms have been growing ever since.

> Technically, we should be calling anything outside of “javascript/atoms” molecules. But then we can’t say that we have atomic drivers. and use imagery from the 50s to describe them.

> `*sigh*`

jimevans replied: “molecular drivers?”

And simonstewart finished with:

> Indeed :) The idea is that the atoms are the lowest level. And we compose the atoms to conform to the WebDriver or RC apis in “javascript/{selenium,webdriver}-atoms” respecitively. And then suck those in as necessary.

### A Story of Crazy-Fun

Simon Stewart :

> So, let’s go back to the very beginning of the project

> When it was me, on my own\
> (the webdriver project, that is, not selenium itself)\
> I knew that I wanted to cover multiple different languages, and so wanted a build tool that could work with all of them\
> That is, that didn't have a built in preference for one that made working with other languages painful\
> ant is java biased. As is maven.\
> nant and msbuild are .net biased\
> rake, otoh, supports nothing very well\
> But, and this is key, any valid rake script is also a valid ruby program\
> It's possible to extend rake to build *anything*\
> So: rake it was\
> The initial rake file was pretty small and manageable\
> But as the project grew, so did the Rakefile\
> Until there was only person who could deal with it (me), and even then it was pretty shaky\
> So, rather than have a project that couldn't be built, I extracted some helper methods to do some of the heavy lifting\
> Which made the Rakefile comprehensible again\
> But they project kept. getting. bigger\
> And the Rakefile got harder and harder to grok\
> At the time, I was working at Google, who have a wonderful build system\
> Google's system is declarative and works across multiple different languages consistently\
> And, most important, it breaks up the build from a single file into little fragments\
> I asked the OSS chaps at Google if it was okay to open source the build grammar, and they gave it the green light\
> So we layered that build grammar into the selenium codebase\
> With one minor change (we handle dictionary args)\
> But that grammar sits on top of rake\
> still, after all this time\
> And there's a problem\
> And that's that rake is single threaded\
> So our builds are constrained to run serially\
> We could use "multitask" types to improve things, but when I've tried that things got very messy, very fast\
> So, our next hurdle is that crazyfun.rb is slow: we need to go faster\
> Which implies a rewrite of crazyfun\
> I'm most comfortable in java\
> So, I've spiked a new version in java that handles the java and js compilation\
> It's significantly faster\
> But, and this is also important, it's a spike\
> The code was designed to be disposable.\
> Now that things have been proved out, I'd really like to do a clean implementation\
> But I'm torn\
> Do I "finish" the new, very fast crazyfun java enough to replace the ruby version?

### A story of driver executeables

> jimevans\
> noob\_einsteinsfo: alright, story time, then. are we sitting comfortably? then we'll begin.\
> noob\_einsteinsfo: back when i first started working on the project (circa 2010), the drivers for all of the browsers were built and maintained by the project.\
> at the time, that meant IE, firefox, and chrome.\
> all of those drivers were packaged as part of the selenium standalone server, and were also packaged in with the various language bindings.\
> this was a conscious decision, so that if one were running locally, there would be no need for the java runtime on the machine just to automate a given browser.\
> there were two factors that led to the development of browser drivers as separate executables.\
> as a quick aside, remember that the webdriver philosophy is to automate the browser using the "best-fit" mechanism for that particular browser.\
> for IE, that means using the COM interfaces; for firefox at the time, that meant using a browser extension; for chrome, it also meant a browser extension.\
> so that meant that the IE driver was developed as a DLL in C++ that was loaded by the language bindings, and communicated with via whatever native-code mechanism was provided by the language (JNI for java, P/Invoke for .NET, ctypes for python, etc.).\
> it also meant that the firefox driver was developed as a browser extension that was packaged inside the various language bindings, and extracted, and used in a profile in firefox.\
> as i said, the IE driver was implemented as a DLL, loaded and communicated with using different mechanisms for different language bindings.\
> the problem is that each of those language-specific mechanisms had different load/unload semantics.\
> ruby, for example, would never call the windows FreeLibrary API after loading the DLL into memory, making multiple instances really challenging.\
> \*process\* semantics, however, as in, starting, stopping, and managing the lifetime of a process on the OS, whatever the OS, are remarkably similar across all languages.\
> so when the IE driver rewrite was completed in 2010, the development team (me) decided to make it a separate executable, so that the load/unload semantics could be consistent no matter what language bindings one was using.\
> concurrently with this, the chromium team made the decision to follow opera's lead and provide a driver implementation for chrome.\
> an implementation that they would develop, enhance, and maintain going forward, relieving the selenium project of the burden of maintaining a chrome driver.\
> \
> XgizmoX\
> and that driver is part of the browser?\
> \
> jimevans\
> XgizmoX: not really, but i believe there may be some smarts built into chrome itself that knows when it's being automated via chromedriver. one of the googlers would be a better person to ask about that.\
> anyway, knowing the different in shared library (.dll/.so/.dynlib) loading semantics, the chromium team (with my encouragement) decided to release their chromedriver implementation as a separate executable.\
> fast-forward a couple of years, and you begin to see the effort to make webdriver a w3c standard.\
> a working group with the w3c created a specification (still in progress, but getting close to finished with the first version), which codified the behavior of webdriver, and how a browser should react to its methods. furthermore, it standardized the protocol used to communicate between language bindings and a driver for a particular browser.\
> i can't emphasize how important and groundbreaking this was.\
> because the w3c and the webdriver working group within it are made up of representatives from the browser vendors themselves, it ensures that the solution will be supported directly by the browser vendors.\
> mozilla created their webdriver implementation (geckodriver) for firefox.\
> the most efficient mechanism for distribution of that browser driver, while maintaining the proper semantics for the language bindings, was to ship as a separate executable.\
> note, this is a gross oversimplification of the geckodriver architecture; the actual executable acts as a relatively thin shim, translating from the wire protocol of the spec to their internal marionette protocol\
> but the point still stands.\
> anyway, the landscape is currently evolving regarding browser-vendor-provided driver implementation. microsoft has one for edge, apple has one for safari (10 and above), the chromium team (largely staffed by googlers) has one for chrome, and now mozilla has one for firefox.\
> given the limited utility of the legacy firefox driver going forward, breaking it out into a separate executable would be wasted effort.\
> this is particularly so, since all of the communication bits that are normally handled by the executable (listening for and responding to http requests from the language bindings) are handled entirely by the browser extension. \\\
> there's literally no need for the legacy firefox driver to be a separate executable.\
> moreover, making it independent of a language runtime would be a significant portion of work\
> (because a .NET shop might reasonably balk at being required to install, say, the java runtime just to automate firefox)\
> so historically speaking, noob-einsteinsfo, that's the general reason for why separate executables have become the norm, and why that paradigm wasn't extended to include the legacy firefox driver.\
> does that make sense?\
> okay.\
> now.\
> about geckodriver.\
> the tale of geckodriver is intimately bound with the status of the aforementioned w3c webdriver spec.\
> level 1 of the specification is mostly done, though it took a number of years of effort to get there.\
> it took a large effort from some very smart people (AutomatedTester among them) to mold the initial documentation of what the webdriver open source software (OSS) project did into proper specification language that could be interpreted and turned into actionable stuff by a browser vendor or other implementor.\
> when beginning the geckodriver (nee marionette) project, mozilla decided to base their implementation on the spec, and only the spec, not following the OSS implementation.\
> this created something of a chicken-and-egg problem, in that while the spec language wasn't completed, it couldn't be implemented.\
> it's only been in the last six months or so that the language concerning the advanced user interactions api (the Actions class in java and .NET) has been made robust enough to actually implement.\
> accordingly, that's the single biggest missing chunk of functionality in geckodriver at present. it wasn't implementable via the spec, so it hasn't been implemented.\
> i do know that it's a very high priority for AutomatedTester and his team to get that implementation done and available.\
> as for why geckodriver is mandatory, and the default implementation for automating firefox in 3.x, that also comes down to some decisions made by mozilla.\
> \
> TheSchaf\
> so i guess there is no other choice than to use the old FF as long as required features are missing\
> WhereIsMySpoon\
> TheSchaf: if you need those features, yes\
> or use another browser\
> TheSchaf\
> well, moveTo and sendKeys should be pretty basic :p\
> \
> jimevans\
> TheSchaf: element.sendKeys works just fine. it's Actions.sendKeys that would be broken.\
> in firefox version fortysomething (i misremember the exact version), there was a feature added that blocked browser extensions that hadn't been signed by the mozilla security team.\
> remember that the legacy firefox driver was built as a browser extension? well, with that feature of the browser enabled, the legacy driver couldn't be loaded by the browser.\
> now, for several versions of firefox, it was possible to disable this feature of the browser, and allow unsigned extensions to continue to be loaded.\
> and selenium did this, by virtue of the settings used in the anonymous profile the bindings created when launching firefox.\
> until firefox 48, at which point, it was no longer possible to disable loading of unsigned extensions.\
> at that point, geckodriver was the only way forward for that.\
> now, two more slight points, then i'll be done with story time.\
> first, by nature of what the legacy driver extension does, it's not possible to get it to pass the certification process of the mozilla security team.\
> we asked, were denied, and were told it wouldn't happen ever, full stop.\
> and that's perfectly reasonable, since what that extension does is a security hole big enough to drive a whole fleet of lorries through.\
> second, it turns out there may, in fact, be a way to privately sign the legacy extension so that it can be loaded and used privately by versions of firefox 48 and higher.\
> that's still a less-than-ideal approach, because there's no way that our merry band of open source developers can know how to automate firefox better than the development teams at mozilla, who create the browser in the first place.\
> i totally get the frustration that geckodriver doesn't have the full feature parity of the legacy implementation, especially when it feels like one is being forced to move to it.\
> raging at the selenium project about that decision is directing one's ire in entirely the wrong direction.\
> however, before going off and saying horrible things about mozilla's decisions, do know that mozilla has several people who are constantly engaged in the project, a few of them right here in this very channel (AutomatedTester, davehunt, to name two).\
> i'm sure i've glossed over or mischaracterized some of the historical details of these things, and i'm happy to be corrected. i'm old, after all, and the memory isn't what it used to be.\
> but that, my friends, is the (not so very) short history of why we have separate executables for drivers, and why geckodriver is the way forward, and why a move to it was necessary when the move was made even though some functionality was lacking.\
> \
> jimevans feels like he's become an unofficial historian of the webdriver project

----
url: https://www.selenium.dev/documentation/webdriver/elements/file_upload/
----

```java
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/FileUploadTest.java#L17-L19)

##### /examples/java/src/test/java/dev/selenium/elements/FileUploadTest.java

```java
package dev.selenium.elements;

import dev.selenium.BaseChromeTest;
import java.io.File;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

public class FileUploadTest extends BaseChromeTest {

  @Test
  public void fileUploadTest() {
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }
}
```

```py
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_file_upload.py#L12-L14)

##### /examples/python/tests/elements/test\_file\_upload.py

```py
import os

from selenium import webdriver
from selenium.webdriver.common.by import By


def test_uploads(driver):
    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"
```

```cs
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/FileUploadTest.cs#L21-L23)

##### /examples/dotnet/SeleniumDocs/Elements/FileUploadTest.cs

```cs
using System;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;

namespace SeleniumDocs.Elements
{
    [TestClass]
    public class FileUploadTest : BaseChromeTest
    {
        [TestMethod]
        public void Uploads()
        {
            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }
    }
}
```

```rb
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/file_upload_spec.rb#L12-L14)

##### /examples/ruby/spec/elements/file\_upload\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'File Upload' do
  let(:driver) { start_session }

  it 'uploads' do
    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    file_name = driver.find_element(id: 'uploaded-files')
    expect(file_name.text).to eq 'selenium-snapshot.png'
  end
end
```

```js
    await driver.get('https://the-internet.herokuapp.com/upload');
    // Upload snapshot
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/fileUpload.spec.js#L24-L25)

##### /examples/javascript/test/elements/fileUpload.spec.js

```js

const {Browser, By, until, Builder} = require("selenium-webdriver");
const path = require("path");
const assert = require('node:assert');


describe('File Upload Test', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async() => await driver.quit());

  it('Should be able to upload a file successfully', async function() {
    const image = path.resolve('./test/resources/selenium-snapshot.png')

    await driver.manage().setTimeouts({implicit: 5000});

    // Navigate to URL
    await driver.get('https://the-internet.herokuapp.com/upload');
    // Upload snapshot
    await driver.findElement(By.id("file-upload")).sendKeys(image);
    await driver.findElement(By.id("file-submit")).submit();

    const revealed = await driver.findElement(By.id('uploaded-files'))
    await driver.wait(until.elementIsVisible(revealed), 2000);
    const data = await driver.findElement(By.css('h3'));

    assert.equal(await data.getText(), `File Uploaded!`);
  });
});
```

[Move Code](/documentation/about/contributing/#moving-examples)

\`\`\`java import org.openqa.selenium.By import org.openqa.selenium.chrome.ChromeDriver fun main() { val driver = ChromeDriver() driver.get("https\://the-internet.herokuapp.com/upload") driver.findElement(By.id("file-upload")).sendKeys("selenium-snapshot.jpg") driver.findElement(By.id("file-submit")).submit() if(driver.pageSource.contains("File Uploaded!")) { println("file uploaded") } else{ println("file not uploaded") } } \`\`\`

Last modified October 30, 2025: [modified link weight for file upload to come in logical order for element (#2491) (f297c0685df)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/f297c0685df60e4c7aaebca746612ee8c659a886)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/drivers/
----

# Sessões de Driver

```java
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L23)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L9)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            driver = new ChromeDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BaseTest.cs#L48)

##### /examples/dotnet/SeleniumDocs/BaseTest.cs

```cs
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs
{
    public class BaseTest
    {
        protected IWebDriver driver;
        protected Uri GridUrl;
        private Process _webserverProcess;
        private const string ServerJarName = "selenium-server-4.44.0.jar";
        private static readonly string BaseDirectory = AppContext.BaseDirectory;
        private const string RelativePathToGrid = "../../../../../";
        private readonly string _examplesDirectory = Path.GetFullPath(Path.Combine(BaseDirectory, RelativePathToGrid));

        [TestCleanup]
        public void Cleanup()
        {
            driver?.Quit();

            if (_webserverProcess != null)
            {
                StopServer();
            }
        }

        protected void StartDriver(string browserVersion = null)
        {
            ChromeOptions options = new ChromeOptions();
            if (browserVersion != null)
            {
                options.BrowserVersion = browserVersion;
                string userDataDir = System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetRandomFileName());
                System.IO.Directory.CreateDirectory(userDataDir);
                options.AddArgument($"--user-data-dir={userDataDir}");
                options.AddArgument("--no-sandbox");
                options.AddArgument("--disable-dev-shm-usage");
            }
            driver = new ChromeDriver(options);
        }

        protected async Task StartServer()
        {
            if (_webserverProcess == null || _webserverProcess.HasExited)
            {
                _webserverProcess = new Process();
                _webserverProcess.StartInfo.FileName =
                    RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "java.exe" : "java";
                string port = GetFreeTcpPort().ToString();
                GridUrl = new Uri("http://localhost:" + port + "/wd/hub");
                _webserverProcess.StartInfo.Arguments = " -jar " + ServerJarName +
                                                        " standalone --port " + port +
                                                        " --selenium-manager true --enable-managed-downloads true";
                _webserverProcess.StartInfo.WorkingDirectory = _examplesDirectory;
                _webserverProcess.Start();
                await EnsureGridIsRunningAsync();
            }
        }

        private void StopServer()
        {
            if (_webserverProcess != null && !_webserverProcess.HasExited)
            {
                _webserverProcess.Kill();
                _webserverProcess.Dispose();
                _webserverProcess = null;
            }
        }

        private static int GetFreeTcpPort()
        {
            TcpListener l = new TcpListener(IPAddress.Loopback, 0);
            l.Start();
            int port = ((IPEndPoint)l.LocalEndpoint).Port;
            l.Stop();
            return port;
        }

        private async Task EnsureGridIsRunningAsync()
        {
            DateTime timeout = DateTime.Now.Add(TimeSpan.FromSeconds(240));
            bool isRunning = false;
            HttpClient client = new HttpClient();

            while (!isRunning && DateTime.Now < timeout)
            {
                try
                {
                    HttpResponseMessage response = await client.GetAsync(GridUrl + "/status");
                    if (response.IsSuccessStatusCode)
                    {
                        isRunning = true;
                    }
                    else
                    {
                        await Task.Delay(1000);
                    }
                }
                catch (HttpRequestException)
                {
                    await Task.Delay(1000);
                }
            }

            if (!isRunning)
            {
                throw new TimeoutException("Could not confirm the remote selenium server is running within 30 seconds");
            }
        }
    }
}
```

```rb
      driver = Selenium::WebDriver.for :chrome, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L14)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options)
      .setChromeService(service)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/drivers/service.spec.js#L46-L50)

##### /examples/javascript/test/drivers/service.spec.js

```js
const fs = require('fs');
const os = require('os');
const path = require('path');
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const {getBinaryPaths} = require("selenium-webdriver/common/driverFinder");

describe('Service Test', function () {
  let driver;
  let userDataDir;
  let service;
  let options;

  afterEach(async function () {
    if (driver) {
      await driver.quit();
      driver = null;
    }
    if (userDataDir) {
      fs.rmSync(userDataDir, { recursive: true, force: true });
      userDataDir = null;
    }
  });

  it('Default service', async function () {
    service = new Chrome.ServiceBuilder();
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });

  it('Set Driver Location', async function () {
    options = new Chrome.Options();
    options.setBrowserVersion("stable");
    let paths = getBinaryPaths(options);
    let driverPath = paths.driverPath;
    let browserPath = paths.browserPath;
    options.setChromeBinaryPath(browserPath);
    userDataDir = fs.mkdtempSync(path.join(os.tmpdir(), 'chrome-profile-'));
    options.addArguments(`--user-data-dir=${userDataDir}`);
    options.addArguments('--no-sandbox');
    options.addArguments('--disable-dev-shm-usage');
    service = new Chrome.ServiceBuilder(driverPath);
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });

  it('Set port', async function () {
    service = new Chrome.ServiceBuilder().setPort(1234);
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
        driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L11)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L28)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L16)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L28)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L35)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

***

##### [Opções do navegador](/pt-br/documentation/webdriver/drivers/options/)

Esses recursos são compartilhados por todos os navegadores.

##### [Configuração do Cliente HTTP](/pt-br/documentation/webdriver/drivers/http_client/)

##### [Classe de Serviço do Driver](/pt-br/documentation/webdriver/drivers/service/)

##### [WebDriver Remoto](/pt-br/documentation/webdriver/drivers/remote_webdriver/)

Última modificação October 30, 2025: [Issue 2452- fixed line number for CSharp to show correct line for driver (#2489) (fe610b23e9b)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/fe610b23e9b91b7314fc8ae3c3d24deb73afee22)

----
url: https://www.selenium.dev/documentation/webdriver/interactions/windows/
----

# Working with windows and tabs

```java
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L16-L20)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L16-L18)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L17-L21)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
driver.window_handle
```

```javascript
await driver.getWindowHandle();
```

```kotlin
driver.windowHandle
```

```java
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L22-L29)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L22-L32)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L23-L30)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
    # Store the ID of the original window
original_window = driver.window_handle

    # Check we don't have other windows open already
assert(driver.window_handles.length == 1, 'Expected one window')

    # Click the link which opens in a new window
driver.find_element(link: 'new window').click

    # Wait for the new window or tab
wait.until { driver.window_handles.length == 2 }

    #Loop through until we find a new window handle
driver.window_handles.each do |handle|
    if handle != original_window
        driver.switch_to.window handle
        break
    end
end

    #Wait for the new tab to finish loading content
wait.until { driver.title == 'Selenium documentation'}
  
```

```javascript
//Store the ID of the original window
const originalWindow = await driver.getWindowHandle();

//Check we don't have other windows open already
assert((await driver.getAllWindowHandles()).length === 1);

//Click the link which opens in a new window
await driver.findElement(By.linkText('new window')).click();

//Wait for the new window or tab
await driver.wait(
    async () => (await driver.getAllWindowHandles()).length === 2,
    10000
  );

//Loop through until we find a new window handle
const windows = await driver.getAllWindowHandles();
windows.forEach(async handle => {
  if (handle !== originalWindow) {
    await driver.switchTo().window(handle);
  }
});

//Wait for the new tab to finish loading content
await driver.wait(until.titleIs('Selenium documentation'), 10000);
  
```

```kotlin
//Store the ID of the original window
val originalWindow = driver.getWindowHandle()

//Check we don't have other windows open already
assert(driver.getWindowHandles().size() === 1)

//Click the link which opens in a new window
driver.findElement(By.linkText("new window")).click()

//Wait for the new window or tab
wait.until(numberOfWindowsToBe(2))

//Loop through until we find a new window handle
for (windowHandle in driver.getWindowHandles()) {
    if (!originalWindow.contentEquals(windowHandle)) {
        driver.switchTo().window(windowHandle)
        break
    }
}

//Wait for the new tab to finish loading content
wait.until(titleIs("Selenium documentation"))

  
```

```java
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L31-L34)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L46-L46)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L32-L35)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
    #Close the tab or window
driver.close

    #Switch back to the old tab or window
driver.switch_to.window original_window
  
```

```javascript
//Close the tab or window
await driver.close();

//Switch back to the old tab or window
await driver.switchTo().window(originalWindow);
  
```

```kotlin
//Close the tab or window
driver.close()

//Switch back to the old tab or window
driver.switchTo().window(originalWindow)

  
```

```java
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L36-L42)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L53-L58)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L37-L43)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

Opens a new tab and switches to new tab:

```rb
    driver.switch_to.new_window(:tab)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/windows_spec.rb#L9)

##### /examples/ruby/spec/interactions/windows\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Windows' do
  let(:driver) { start_session }

  it 'opens new tab' do
    driver.switch_to.new_window(:tab)

    expect(driver.window_handles.size).to eq 2
  end

  it 'opens new window' do
    driver.switch_to.new_window(:window)

    expect(driver.window_handles.size).to eq 2
  end
end
```

Opens a new window and switches to new window:

```rb
    driver.switch_to.new_window(:window)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/windows_spec.rb#L15)

##### /examples/ruby/spec/interactions/windows\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Windows' do
  let(:driver) { start_session }

  it 'opens new tab' do
    driver.switch_to.new_window(:tab)

    expect(driver.window_handles.size).to eq 2
  end

  it 'opens new window' do
    driver.switch_to.new_window(:window)

    expect(driver.window_handles.size).to eq 2
  end
end
```

Opens a new tab and switches to new tab

```js
    await driver.switchTo().newWindow('tab');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L70)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

Opens a new window and switches to new window:

```js
    await driver.switchTo().newWindow('window');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L75)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Opens a new tab and switches to new tab
driver.switchTo().newWindow(WindowType.TAB)

// Opens a new window and switches to new window
driver.switchTo().newWindow(WindowType.WINDOW)
  
```

```java
        //quitting driver
        driver.quit(); //close all windows
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L44-L45)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L13-L13)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //quitting driver
              driver.Quit(); //close all windows
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L45-L46)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
driver.quit
```

```javascript
await driver.quit();
```

```kotlin
driver.quit()
```

```java
/**
 * Example using JUnit
 * https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
 */
@AfterAll
public static void tearDown() {
    driver.quit();
}
  
```

```python
    # unittest teardown
    # https://docs.python.org/3/library/unittest.html?highlight=teardown#unittest.TestCase.tearDown
def tearDown(self):
    self.driver.quit()
  
```

```csharp
/*
    Example using Visual Studio's UnitTesting
    https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.aspx
*/
[TestCleanup]
public void TearDown()
{
    driver.Quit();
}
  
```

```ruby
    # UnitTest Teardown
    # https://www.rubydoc.info/github/test-unit/test-unit/Test/Unit/TestCase
def teardown
    @driver.quit
end
  
```

```javascript
/**
 * Example using Mocha
 * https://mochajs.org/#hooks
 */
after('Tear down', async function () {
  await driver.quit();
});
  
```

```kotlin
/**
 * Example using JUnit
 * https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
 */
@AfterAll
fun tearDown() {
    driver.quit()
}
  
```

```java
try {
    //WebDriver code here...
} finally {
    driver.quit();
}
  
```

```python
try:
    #WebDriver code here...
finally:
    driver.quit()
  
```

```csharp
try {
    //WebDriver code here...
} finally {
    driver.Quit();
}
  
```

```ruby
begin
    #WebDriver code here...
ensure
    driver.quit
end
  
```

```javascript
try {
    //WebDriver code here...
} finally {
    await driver.quit();
}
  
```

```kotlin
try {
    //WebDriver code here...
} finally {
    driver.quit()
}
  
```

Python’s WebDriver now supports the python context manager, which when using the `with` keyword can automatically quit the driver at the end of execution.

```python
with webdriver.Firefox() as driver:
  # WebDriver code here...

# WebDriver will automatically quit after indentation
```

```java
//Access each dimension individually
int width = driver.manage().window().getSize().getWidth();
int height = driver.manage().window().getSize().getHeight();

//Or store the dimensions and query them later
Dimension size = driver.manage().window().getSize();
int width1 = size.getWidth();
int height1 = size.getHeight();
  
```

```python
    # Access each dimension individually
width = driver.get_window_size().get("width")
height = driver.get_window_size().get("height")

    # Or store the dimensions and query them later
size = driver.get_window_size()
width1 = size.get("width")
height1 = size.get("height")
  
```

```csharp
//Access each dimension individually
int width = driver.Manage().Window.Size.Width;
int height = driver.Manage().Window.Size.Height;

//Or store the dimensions and query them later
System.Drawing.Size size = driver.Manage().Window.Size;
int width1 = size.Width;
int height1 = size.Height;
  
```

```ruby
    # Access each dimension individually
width = driver.manage.window.size.width
height = driver.manage.window.size.height

    # Or store the dimensions and query them later
size = driver.manage.window.size
width1 = size.width
height1 = size.height
  
```

Access each dimension individually

```js
    const { width, height } = await driver.manage().window().getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L93)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

(or) store the dimensions and query them later

```js
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L96-L98)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
//Access each dimension individually
val width = driver.manage().window().size.width
val height = driver.manage().window().size.height

//Or store the dimensions and query them later
val size = driver.manage().window().size
val width1 = size.width
val height1 = size.height
  
```

```java
driver.manage().window().setSize(new Dimension(1024, 768));
```

```python
driver.set_window_size(1024, 768)
```

```csharp
driver.Manage().Window.Size = new Size(1024, 768);
```

```ruby
driver.manage.window.resize_to(1024,768)
```

```javascript
await driver.manage().window().setRect({ width: 1024, height: 768 });
```

```kotlin
driver.manage().window().size = Dimension(1024, 768)
```

```java
// Access each dimension individually
int x = driver.manage().window().getPosition().getX();
int y = driver.manage().window().getPosition().getY();

// Or store the dimensions and query them later
Point position = driver.manage().window().getPosition();
int x1 = position.getX();
int y1 = position.getY();
  
```

```python
    # Access each dimension individually
x = driver.get_window_position().get('x')
y = driver.get_window_position().get('y')

    # Or store the dimensions and query them later
position = driver.get_window_position()
x1 = position.get('x')
y1 = position.get('y')
  
```

```csharp
//Access each dimension individually
int x = driver.Manage().Window.Position.X;
int y = driver.Manage().Window.Position.Y;

//Or store the dimensions and query them later
Point position = driver.Manage().Window.Position;
int x1 = position.X;
int y1 = position.Y;
  
```

```ruby
    #Access each dimension individually
x = driver.manage.window.position.x
y = driver.manage.window.position.y

    # Or store the dimensions and query them later
rect  = driver.manage.window.rect
x1 = rect.x
y1 = rect.y
  
```

Access each dimension individually

```js
    const { x, y } = await driver.manage().window().getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L108)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

(or) store the dimensions and query them later

```js
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L111-L113)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Access each dimension individually
val x = driver.manage().window().position.x
val y = driver.manage().window().position.y

// Or store the dimensions and query them later
val position = driver.manage().window().position
val x1 = position.x
val y1 = position.y

  
```

```java
// Move the window to the top left of the primary monitor
driver.manage().window().setPosition(new Point(0, 0));
  
```

```python
    # Move the window to the top left of the primary monitor
driver.set_window_position(0, 0)
  
```

```csharp
// Move the window to the top left of the primary monitor
driver.Manage().Window.Position = new Point(0, 0);
  
```

```ruby
driver.manage.window.move_to(0,0)
  
```

```javascript
// Move the window to the top left of the primary monitor
await driver.manage().window().setRect({ x: 0, y: 0 });
  
```

```kotlin
// Move the window to the top left of the primary monitor
driver.manage().window().position = Point(0,0)
    
```

```java
driver.manage().window().maximize();
```

```python
driver.maximize_window()
```

```csharp
driver.Manage().Window.Maximize();
```

```ruby
driver.manage.window.maximize
```

```javascript
await driver.manage().window().maximize();
```

```kotlin
driver.manage().window().maximize()
```

```java
driver.manage().window().minimize();
```

```python
driver.minimize_window()
```

```csharp
driver.Manage().Window.Minimize();
```

```ruby
driver.manage.window.minimize
```

```javascript
await driver.manage().window().minimize();
```

```kotlin
driver.manage().window().minimize()
```

```java
driver.manage().window().fullscreen();
```

```python
driver.fullscreen_window()
```

```csharp
driver.Manage().Window.FullScreen();
```

```ruby
driver.manage.window.full_screen
```

```javascript
await driver.manage().window().fullscreen();
```

```kotlin
driver.manage().window().fullscreen()
```

```java
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.*;
import org.openqa.selenium.*;

public class SeleniumTakeScreenshot {
    public static void main(String args[]) throws IOException {
        WebDriver driver = new ChromeDriver();
        driver.get("http://www.example.com");
        File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(scrFile, new File("./image.png"));
        driver.quit();
    }
}
  
```

```python
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("http://www.example.com")

    # Returns and base64 encoded string into image
driver.save_screenshot('./image.png')

driver.quit()
```

```csharp
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using OpenQA.Selenium.Support.UI;

  var driver = new ChromeDriver();
  driver.Navigate().GoToUrl("http://www.example.com");
  Screenshot screenshot = (driver as ITakesScreenshot).GetScreenshot();
  screenshot.SaveAsFile("screenshot.png", ScreenshotImageFormat.Png); // Format values are Bmp, Gif, Jpeg, Png, Tiff
  
```

```ruby
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://example.com/'

    # Takes and Stores the screenshot in specified path
  driver.save_screenshot('./image.png')

end
  
```

```js
    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L56-L59)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
import com.oracle.tools.packager.IOUtils.copyFile
import org.openqa.selenium.*
import org.openqa.selenium.chrome.ChromeDriver
import java.io.File

fun main(){
    val driver =  ChromeDriver()
    driver.get("https://www.example.com")
    val scrFile = (driver as TakesScreenshot).getScreenshotAs<File>(OutputType.FILE)
    copyFile(scrFile, File("./image.png"))
    driver.quit()
}
   
```

```java
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.File;
import java.io.IOException;

public class SeleniumelementTakeScreenshot {
  public static void main(String args[]) throws IOException {
    WebDriver driver = new ChromeDriver();
    driver.get("https://www.example.com");
    WebElement element = driver.findElement(By.cssSelector("h1"));
    File scrFile = element.getScreenshotAs(OutputType.FILE);
    FileUtils.copyFile(scrFile, new File("./image.png"));
    driver.quit();
  }
}
  
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("http://www.example.com")

ele = driver.find_element(By.CSS_SELECTOR, 'h1')

    # Returns and base64 encoded string into image
ele.screenshot('./image.png')

driver.quit()
  
```

```csharp
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;
    using OpenQA.Selenium.Support.UI;

    // Webdriver
    var driver = new ChromeDriver();
    driver.Navigate().GoToUrl("http://www.example.com");

    // Fetch element using FindElement
    var webElement = driver.FindElement(By.CssSelector("h1"));

    // Screenshot for the element
    var elementScreenshot = (webElement as ITakesScreenshot).GetScreenshot();
    elementScreenshot.SaveAsFile("screenshot_of_element.png");
  
```

```ruby
    # Works with Selenium4-alpha7 Ruby bindings and above
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://example.com/'
  ele = driver.find_element(:css, 'h1')

    # Takes and Stores the element screenshot in specified path
  ele.save_screenshot('./image.jpg')
end
  
```

```js
    let header = await driver.findElement(By.css('h1'));
      // Captures the element screenshot
      let encodedString = await header.takeScreenshot(true);
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
  
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L44-L48)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
  const chrome = require('selenium-webdriver/chrome');
  const assert = require("node:assert");
  let opts = new chrome.Options();
  opts.addArguments('--headless');
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let imgMagicNumber = 'iVBOR'
  let base64Code
  
  describe('Interactions - Windows', function () {
    let driver;
    before(async function () {
      driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
    });
  
    after(async () => await driver.quit());
  
    it('Should be able to print page to pdf', async function () {
  
      await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
      let base64 = await driver.printPage({pageRanges: ["1-2"]});
      // page can be saved as a PDF as below
      // await fs.writeFileSync('./test.pdf', base64, 'base64');
  
      base64Code = base64.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, pdfMagicNumber)
    });
  
    it('Should be able to get text using executeScript', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
      // Stores the header element
      let header = await driver.findElement(By.css('h1'));
  
      // Executing JavaScript to capture innerText of header element
      let text = await driver.executeScript('return arguments[0].innerText', header);
      assert.strictEqual(text, `Type Stuff`)
    });
  
    it('Should be able to take Element Screenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      let header = await driver.findElement(By.css('h1'));
      // Captures the element screenshot
      let encodedString = await header.takeScreenshot(true);
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to takeScreenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      // Captures the screenshot
      let encodedString = await driver.takeScreenshot();
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to switch to newWindow and newTab and close', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
      const initialWindow = await driver.getAllWindowHandles();
      assert.strictEqual(initialWindow.length, 1)
  
      // Opens a new tab and switches to new tab
      await driver.switchTo().newWindow('tab');
      const browserTabs = await driver.getAllWindowHandles();
      assert.strictEqual(browserTabs.length, 2)
  
      // Opens a new window and switches to new window
      await driver.switchTo().newWindow('window');
      const windows = await driver.getAllWindowHandles();
      assert.strictEqual(windows.length, 3)
  
      //Close the tab or window
      await driver.close();
  
      //Switch back to the old tab or window
      await driver.switchTo().window(windows[1]);
  
      const windowsAfterClose = await driver.getAllWindowHandles();
      assert.strictEqual(windowsAfterClose.length, 2);
    });
  
    it('Should be able to getWindow Size', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { width, height } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const windowWidth = rect.width;
      const windowHeight = rect.height;
  
      assert.ok(windowWidth>0);
      assert.ok(windowHeight>0);
    });
  
    it('Should be able to getWindow position', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { x, y } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const x1 = rect.x;
      const y1 = rect.y;
  
      assert.ok(x1>=0);
      assert.ok(y1>=0);
    });
  });
```

```kotlin
import org.apache.commons.io.FileUtils
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.*
import java.io.File

fun main() {
    val driver = ChromeDriver()
    driver.get("https://www.example.com")
    val element = driver.findElement(By.cssSelector("h1"))
    val scrFile: File = element.getScreenshotAs(OutputType.FILE)
    FileUtils.copyFile(scrFile, File("./image.png"))
    driver.quit()
}
  
```

```java
    //Creating the JavascriptExecutor interface object by Type casting
      JavascriptExecutor js = (JavascriptExecutor)driver;
    //Button Element
      WebElement button =driver.findElement(By.name("btnLogin"));
    //Executing JavaScript to click on element
      js.executeScript("arguments[0].click();", button);
    //Get return value from script
      String text = (String) js.executeScript("return arguments[0].innerText", button);
    //Executing JavaScript directly
      js.executeScript("console.log('hello world')");
  
```

```python
    # Stores the header element
header = driver.find_element(By.CSS_SELECTOR, "h1")

    # Executing JavaScript to capture innerText of header element
driver.execute_script('return arguments[0].innerText', header)
  
```

```csharp
	//creating Chromedriver instance
	IWebDriver driver = new ChromeDriver();
	//Creating the JavascriptExecutor interface object by Type casting
	IJavaScriptExecutor js = (IJavaScriptExecutor) driver;
	//Button Element
	IWebElement button = driver.FindElement(By.Name("btnLogin"));
	//Executing JavaScript to click on element
	js.ExecuteScript("arguments[0].click();", button);
	//Get return value from script
	String text = (String)js.ExecuteScript("return arguments[0].innerText", button);
	//Executing JavaScript directly
	js.ExecuteScript("console.log('hello world')");
  
```

```ruby
    # Stores the header element
header = driver.find_element(css: 'h1')

    # Get return value from script
result = driver.execute_script("return arguments[0].innerText", header)

    # Executing JavaScript directly
driver.execute_script("alert('hello world')")
  
```

```js
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L33-L37)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Stores the header element
val header = driver.findElement(By.cssSelector("h1"))

// Get return value from script
val result = driver.executeScript("return arguments[0].innerText", header)

// Executing JavaScript directly
driver.executeScript("alert('hello world')")
  
```

```java
    import org.openqa.selenium.print.PrintOptions;

    driver.get("https://www.selenium.dev");
    printer = (PrintsPage) driver;

    PrintOptions printOptions = new PrintOptions();
    printOptions.setPageRanges("1-2");

    Pdf pdf = printer.print(printOptions);
    String content = pdf.getContent();
  
```

```python
    from selenium.webdriver.common.print_page_options import PrintOptions

    print_options = PrintOptions()
    print_options.page_ranges = ['1-2']

    driver.get("printPage.html")

    base64code = driver.print_page(print_options)
  
```

```csharp
    // code sample not available please raise a PR
  
```

```ruby
    driver.navigate_to 'https://www.selenium.dev'

    base64encodedContent = driver.print_page(orientation: 'landscape')
  
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
      let base64 = await driver.printPage({pageRanges: ["1-2"]});
      // page can be saved as a PDF as below
      // await fs.writeFileSync('./test.pdf', base64, 'base64');
  
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L22-L25)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
  const chrome = require('selenium-webdriver/chrome');
  const assert = require("node:assert");
  let opts = new chrome.Options();
  opts.addArguments('--headless');
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let imgMagicNumber = 'iVBOR'
  let base64Code
  
  describe('Interactions - Windows', function () {
    let driver;
    before(async function () {
      driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
    });
  
    after(async () => await driver.quit());
  
    it('Should be able to print page to pdf', async function () {
  
      await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
      let base64 = await driver.printPage({pageRanges: ["1-2"]});
      // page can be saved as a PDF as below
      // await fs.writeFileSync('./test.pdf', base64, 'base64');
  
      base64Code = base64.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, pdfMagicNumber)
    });
  
    it('Should be able to get text using executeScript', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
      // Stores the header element
      let header = await driver.findElement(By.css('h1'));
  
      // Executing JavaScript to capture innerText of header element
      let text = await driver.executeScript('return arguments[0].innerText', header);
      assert.strictEqual(text, `Type Stuff`)
    });
  
    it('Should be able to take Element Screenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      let header = await driver.findElement(By.css('h1'));
      // Captures the element screenshot
      let encodedString = await header.takeScreenshot(true);
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to takeScreenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      // Captures the screenshot
      let encodedString = await driver.takeScreenshot();
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to switch to newWindow and newTab and close', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
      const initialWindow = await driver.getAllWindowHandles();
      assert.strictEqual(initialWindow.length, 1)
  
      // Opens a new tab and switches to new tab
      await driver.switchTo().newWindow('tab');
      const browserTabs = await driver.getAllWindowHandles();
      assert.strictEqual(browserTabs.length, 2)
  
      // Opens a new window and switches to new window
      await driver.switchTo().newWindow('window');
      const windows = await driver.getAllWindowHandles();
      assert.strictEqual(windows.length, 3)
  
      //Close the tab or window
      await driver.close();
  
      //Switch back to the old tab or window
      await driver.switchTo().window(windows[1]);
  
      const windowsAfterClose = await driver.getAllWindowHandles();
      assert.strictEqual(windowsAfterClose.length, 2);
    });
  
    it('Should be able to getWindow Size', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { width, height } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const windowWidth = rect.width;
      const windowHeight = rect.height;
  
      assert.ok(windowWidth>0);
      assert.ok(windowHeight>0);
    });
  
    it('Should be able to getWindow position', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { x, y } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const x1 = rect.x;
      const y1 = rect.y;
  
      assert.ok(x1>=0);
      assert.ok(y1>=0);
    });
  });
```

```kotlin
    driver.get("https://www.selenium.dev")
    val printer = driver as PrintsPage

    val printOptions = PrintOptions()
    printOptions.setPageRanges("1-2")
    
    val pdf: Pdf = printer.print(printOptions)
    val content = pdf.content
  
```

Last modified May 11, 2026: [Move Python examples in Windows interactions docs (#2629) (d368a9324d6)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/d368a9324d6aa6bb62c016bb5572d28966a7f091)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/actions_api/
----

# Ações API

Uma interface de baixo nível para fornecer ações de entrada de dispositivo virtualizadas para o navegador da web..

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/ActionsTest.java#L21-L28)

##### /examples/java/src/test/java/dev/selenium/actions\_api/ActionsTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;

public class ActionsTest extends BaseChromeTest {
    @Test
    public void pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        long start = System.currentTimeMillis();

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();

        long duration = System.currentTimeMillis() - start;
        Assertions.assertTrue(duration > 2000);
        Assertions.assertTrue(duration < 3000);
    }

    @Test
    public void releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        Actions actions = new Actions(driver);
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        ((RemoteWebDriver) driver).resetInputState();

        actions.sendKeys("a").perform();
        Assertions.assertEquals("A", String.valueOf(clickable.getAttribute("value").charAt(0)));
        Assertions.assertEquals("a", String.valueOf(clickable.getAttribute("value").charAt(1)));
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_actions.py#L13-L20)

##### /examples/python/tests/actions\_api/test\_actions.py

```py
from time import time

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.by import By


def test_pauses(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    start = time()

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()

    duration = time() - start
    assert duration > 2
    assert duration < 3


def test_releases_all(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .click_and_hold(clickable)\
        .key_down(Keys.SHIFT)\
        .key_down("a")\
        .perform()

    ActionBuilder(driver).clear_actions()

    ActionChains(driver).key_down('a').perform()

    assert clickable.get_attribute('value')[0] == "A"
    assert clickable.get_attribute('value')[1] == "a"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs#L18-L25)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class ActionsTest : BaseChromeTest
    {
        [TestMethod]
        public void Pause()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            DateTime start = DateTime.Now;

            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();

            TimeSpan duration = DateTime.Now - start;
            Assert.IsTrue(duration > TimeSpan.FromSeconds(2));
            Assert.IsTrue(duration < TimeSpan.FromSeconds(3));
        }

        [TestMethod]
        public void ReleaseAll()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            var actions = new Actions(driver);
            actions.ClickAndHold(clickable)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            ((WebDriver)driver).ResetInputState();

            actions.SendKeys("a").Perform();
            var value = clickable.GetAttribute("value");
            Assert.AreEqual("A", value[..1]);
            Assert.AreEqual("a", value.Substring(1, 1));
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/actions_spec.rb#L12-L19)

##### /examples/ruby/spec/actions\_api/actions\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Actions' do
  let(:driver) { start_session }

  it 'pauses' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
    start = Time.now

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform

    duration = Time.now - start
    expect(duration).to be > 2
    expect(duration).to be < 3
  end

  it 'releases all' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    action = driver.action
                   .click_and_hold(clickable)
                   .key_down(:shift)
                   .key_down('a')
    action.perform

    driver.action.release_actions

    action.key_down('a').perform
    expect(clickable.attribute('value')[0]).to eq 'A'
    expect(clickable.attribute('value')[-1]).to eq 'a'
  end
end
```

```js
    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/actionsTest.spec.js#L18-L25)

##### /examples/javascript/test/actionsApi/actionsTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Pause and Release All Actions', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('Pause', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const start = Date.now()

    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()

    const end = Date.now() - start
    assert.ok(end > 2000)
    assert.ok(end < 4000)
  })

  it('Clear', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const clickable = driver.findElement(By.id('clickable'))
    await driver.actions()
      .click(clickable)
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    await driver.actions().clear()
    await driver.actions().sendKeys('a').perform()

    const value = await clickable.getAttribute('value')
    assert.deepStrictEqual('A', value.substring(0, 1))
    assert.deepStrictEqual('a', value.substring(1, 2))
  })
})
```

```kt
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/ActionsTest.kt#L22-L29)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/ActionsTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration

class ActionsTest : BaseTest() {

    @Test
    fun pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val start = System.currentTimeMillis()

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 

        val duration = System.currentTimeMillis() - start
        Assertions.assertTrue(duration > 2000)
        Assertions.assertTrue(duration < 4000)
    }

    @Test
    fun releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        val actions = Actions(driver)
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        (driver as RemoteWebDriver).resetInputState()

        actions.sendKeys("a").perform()
        Assertions.assertEquals("A", clickable.getAttribute("value")!!.get(0).toString())
        Assertions.assertEquals("a", clickable.getAttribute("value")!!.get(1).toString())
    }
}
```

```java
        ((RemoteWebDriver) driver).resetInputState();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/ActionsTest.java#L46)

##### /examples/java/src/test/java/dev/selenium/actions\_api/ActionsTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;

public class ActionsTest extends BaseChromeTest {
    @Test
    public void pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        long start = System.currentTimeMillis();

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();

        long duration = System.currentTimeMillis() - start;
        Assertions.assertTrue(duration > 2000);
        Assertions.assertTrue(duration < 3000);
    }

    @Test
    public void releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        Actions actions = new Actions(driver);
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        ((RemoteWebDriver) driver).resetInputState();

        actions.sendKeys("a").perform();
        Assertions.assertEquals("A", String.valueOf(clickable.getAttribute("value").charAt(0)));
        Assertions.assertEquals("a", String.valueOf(clickable.getAttribute("value").charAt(1)));
    }
}
```

```py
    ActionBuilder(driver).clear_actions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_actions.py#L37)

##### /examples/python/tests/actions\_api/test\_actions.py

```py
from time import time

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.by import By


def test_pauses(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    start = time()

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()

    duration = time() - start
    assert duration > 2
    assert duration < 3


def test_releases_all(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .click_and_hold(clickable)\
        .key_down(Keys.SHIFT)\
        .key_down("a")\
        .perform()

    ActionBuilder(driver).clear_actions()

    ActionChains(driver).key_down('a').perform()

    assert clickable.get_attribute('value')[0] == "A"
    assert clickable.get_attribute('value')[1] == "a"
```

```cs
            ((WebDriver)driver).ResetInputState();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs#L44)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class ActionsTest : BaseChromeTest
    {
        [TestMethod]
        public void Pause()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            DateTime start = DateTime.Now;

            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();

            TimeSpan duration = DateTime.Now - start;
            Assert.IsTrue(duration > TimeSpan.FromSeconds(2));
            Assert.IsTrue(duration < TimeSpan.FromSeconds(3));
        }

        [TestMethod]
        public void ReleaseAll()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            var actions = new Actions(driver);
            actions.ClickAndHold(clickable)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            ((WebDriver)driver).ResetInputState();

            actions.SendKeys("a").Perform();
            var value = clickable.GetAttribute("value");
            Assert.AreEqual("A", value[..1]);
            Assert.AreEqual("a", value.Substring(1, 1));
        }
    }
}
```

```rb
    driver.action.release_actions
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/actions_spec.rb#L36)

##### /examples/ruby/spec/actions\_api/actions\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Actions' do
  let(:driver) { start_session }

  it 'pauses' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
    start = Time.now

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform

    duration = Time.now - start
    expect(duration).to be > 2
    expect(duration).to be < 3
  end

  it 'releases all' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    action = driver.action
                   .click_and_hold(clickable)
                   .key_down(:shift)
                   .key_down('a')
    action.perform

    driver.action.release_actions

    action.key_down('a').perform
    expect(clickable.attribute('value')[0]).to eq 'A'
    expect(clickable.attribute('value')[-1]).to eq 'a'
  end
end
```

```js
    await driver.actions().clear()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/actionsTest.spec.js#L42)

##### /examples/javascript/test/actionsApi/actionsTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Pause and Release All Actions', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('Pause', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const start = Date.now()

    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()

    const end = Date.now() - start
    assert.ok(end > 2000)
    assert.ok(end < 4000)
  })

  it('Clear', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const clickable = driver.findElement(By.id('clickable'))
    await driver.actions()
      .click(clickable)
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    await driver.actions().clear()
    await driver.actions().sendKeys('a').perform()

    const value = await clickable.getAttribute('value')
    assert.deepStrictEqual('A', value.substring(0, 1))
    assert.deepStrictEqual('a', value.substring(1, 2))
  })
})
```

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/ActionsTest.kt#L47)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/ActionsTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration

class ActionsTest : BaseTest() {

    @Test
    fun pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val start = System.currentTimeMillis()

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 

        val duration = System.currentTimeMillis() - start
        Assertions.assertTrue(duration > 2000)
        Assertions.assertTrue(duration < 4000)
    }

    @Test
    fun releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        val actions = Actions(driver)
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        (driver as RemoteWebDriver).resetInputState()

        actions.sendKeys("a").perform()
        Assertions.assertEquals("A", clickable.getAttribute("value")!!.get(0).toString())
        Assertions.assertEquals("a", clickable.getAttribute("value")!!.get(1).toString())
    }
}
```

***

##### [Ações de Teclado](/pt-br/documentation/webdriver/actions_api/keyboard/)

Uma representação de qualquer dispositivo de entrada de teclado para interagir com uma página da web.

##### [Ações do Mouse](/pt-br/documentation/webdriver/actions_api/mouse/)

Uma representação de qualquer dispositivo de ponteiro para interagir com uma página da web.

##### [Ações de Caneta](/pt-br/documentation/webdriver/actions_api/pen/)

Uma representação de uma entrada de ponteiro do tipo caneta stylus para interagir com uma página da web.

##### [Ações de Roda de Rolagem](/pt-br/documentation/webdriver/actions_api/wheel/)

“Uma representação de um dispositivo de entrada de roda de rolagem para interagir com uma página da web.”

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/troubleshooting/
----

# Troubleshooting Assistance

How to solve WebDriver problems.

It is not always obvious the root cause of errors in Selenium.

1. The most common Selenium-related error is a result of poor synchronization. Read about [Waiting Strategies](https://www.selenium.dev/pt-br/documentation/webdriver/waits/). If you aren’t sure if it is a synchronization strategy you can try *temporarily* hard coding a large sleep where you see the issue, and you’ll know if adding an explicit wait can help.

2. Note that many errors that get reported to the project are actually caused by issues in the underlying drivers that Selenium sends the commands to. You can rule out a driver problem by executing the command in multiple [browsers](https://www.selenium.dev/pt-br/documentation/webdriver/browsers/).

3. If you have questions about how to do things, check out the [Support options](/support/) for ways get assistance.

4. If you think you’ve found a problem with Selenium code, go ahead and file a [Bug Report](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=I-defect%2Cneeds-triaging\&template=bug-report.yml\&title=%5B%F0%9F%90%9B+Bug%5D%3A+) on GitHub.

***

##### [Understanding Common Errors](/pt-br/documentation/webdriver/troubleshooting/errors/)

How to solve various problems in your Selenium code.

##### [Logging Selenium commands](/pt-br/documentation/webdriver/troubleshooting/logging/)

Getting information about Selenium execution.

##### [Como atualizar para Selenium 4](/pt-br/documentation/webdriver/troubleshooting/upgrade_to_selenium_4/)

Interessado no Selenium 4? Veja este guia para realizar o upgrade para a ultima versão!

Última modificação November 7, 2024: [Rephrase/reformat a few sentences (#1981) (77ae509e3ca)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/77ae509e3ca40109ca5e74fec1f4f05f69df75f7)

----
url: https://www.selenium.dev/pt-br/_print/documentation/overview/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/overview/).

# Resumo

Será Selenium a ferramenta para você? Veja um resumo dos componentes do projecto.

* 1: [Entendendo os componentes](#pg-68f6deb0243c535972e6625993aae9a2)
* 2: [Detalhes](#pg-508f19d5c8da38c831dfdcd8b21fabc4)

# 1 - Entendendo os componentes

# 2 - Detalhes

----
url: https://www.selenium.dev/documentation/webdriver/actions_api/mouse/
----

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L22-L25)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L14-L17)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L11-L14)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    let clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.move({origin: clickable}).press().perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/clickAndHold.spec.js#L14-L16)

##### /examples/javascript/test/actionsApi/mouse/clickAndHold.spec.js

```js
const {By, Builder} = require('selenium-webdriver');

describe('Click and hold', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and mouseDown on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    let clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.move({origin: clickable}).press().perform();
  });
});
```

```kt
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L23-L26)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L34-L37)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L26-L29)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L30-L33)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L22-L25)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    let click = driver.findElement(By.id("click"));
    const actions = driver.actions({async: true});
    await actions.move({origin: click}).click().perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/clickAndRelease.spec.js#L14-L16)

##### /examples/javascript/test/actionsApi/mouse/clickAndRelease.spec.js

```js
const {By,Builder} = require('selenium-webdriver');

describe('Click and release', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    let click = driver.findElement(By.id("click"));
    const actions = driver.actions({async: true});
    await actions.move({origin: click}).click().perform();
  });
});
```

```kt
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L35-L38)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L46-L49)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L37-L40)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L43-L46)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L34-L37)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.contextClick(clickable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/rightClick.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/rightClick.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Right click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and right click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.contextClick(clickable).perform();

    await driver.sleep(500);
    const clicked = await driver.findElement(By.id('click-status')).getText();
    assert.deepStrictEqual(clicked, `context-clicked`)
  });
});
```

```kt
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L47-L50)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L60-L66)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L51-L54)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L59-L63)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L47-L50)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js#L19-L20)

##### /examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js

```js
const {By, Button, Browser, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Should be able to perform BACK click and FORWARD click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Back click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)

    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)
  });

  it('Forward click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();
    await driver.navigate().back();

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)

    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L61-L67)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L78-L84)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L65-L68)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L77-L81)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L61-L64)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js#L32-L33)

##### /examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js

```js
const {By, Button, Browser, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Should be able to perform BACK click and FORWARD click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Back click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)

    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)
  });

  it('Forward click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();
    await driver.navigate().back();

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)

    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L79-L85)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L93-L96)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L76-L79)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L91-L94)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L73-L76)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.doubleClick(clickable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/doubleClick.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/doubleClick.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Double click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Double-click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.doubleClick(clickable).perform();

    await driver.sleep(500);
    const status = await driver.findElement(By.id('click-status')).getText();
    assert.deepStrictEqual(status, `double-clicked`)
  });
});
```

```kt
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L94-L97)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L105-L108)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L87-L90)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L104-L107)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L84-L87)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const hoverable = driver.findElement(By.id("hover"));
    const actions = driver.actions({async: true});
    await actions.move({origin: hoverable}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveToElement.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/moveToElement.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Move to element', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move into an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const hoverable = driver.findElement(By.id("hover"));
    const actions = driver.actions({async: true});
    await actions.move({origin: hoverable}).perform();

    const status = await driver.findElement(By.id('move-status')).getText();
    assert.deepStrictEqual(status, `hovered`)
  });
});
```

```kt
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L106-L109)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L118-L121)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L98-L101)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L132-L135)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L97-L100)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L119-L122)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L131-L136)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L110-L112)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L146-L150)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      driver.action
            .move_to_location(8, 12)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L114-L116)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L27-L28)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L132-L137)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L153-L155)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L126-L128)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L167-L169)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      driver.action
            .move_by(13, 15)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L128-L130)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L40)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L154-L156)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L166-L170)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L139-L143)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L181-L185)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L141-L145)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js#L27-L30)

##### /examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Drag and Drop', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('By Offset', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });

  it('Onto Element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });
});
```

```kt
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L167-L171)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L179-L184)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L151-L156)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L195-L200)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L153-L158)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js#L15-L19)

##### /examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Drag and Drop', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('By Offset', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });

  it('Onto Element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });
});
```

```kt
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L180-L185)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

----
url: https://www.selenium.dev/documentation/test_practices/encouraged/test_independency/
----

# Test independency

Write each test as its own unit. Write the tests in a way that will not be reliant on other tests to complete:

Let us say there is a content management system with which you can create some custom content which then appears on your website as a module after publishing, and it may take some time to sync between the CMS and the application.

A wrong way of testing your module is that the content is created and published in one test, and then checking the module in another test. This is not feasible as the content may not be available immediately for the other test after publishing.

Instead, you can create a stub content which can be turned on and off within the affected test, and use that for validating the module. However, for content creation, you can still have a separate test.

----
url: https://www.selenium.dev/pt-br/documentation/grid/advanced_features/customize_node/
----

# Personalizando um Nó

```bash
java -jar custom_node-server.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

```bash
java -jar selenium-server-4.6.0.jar \
--ext custom_node-1.0-SNAPSHOT.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

Aqui está um exemplo que apenas imprime algumas mensagens no console sempre que houver uma atividade de interesse (sessão criada, sessão excluída, execução de um comando do webdriver, etc.) no Node.

Sample customized node

```java
package org.seleniumhq.samples;

import java.net.URI;
import java.util.UUID;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.NoSuchSessionException;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.grid.config.Config;
import org.openqa.selenium.grid.data.CreateSessionRequest;
import org.openqa.selenium.grid.data.CreateSessionResponse;
import org.openqa.selenium.grid.data.NodeId;
import org.openqa.selenium.grid.data.NodeStatus;
import org.openqa.selenium.grid.data.Session;
import org.openqa.selenium.grid.log.LoggingOptions;
import org.openqa.selenium.grid.node.HealthCheck;
import org.openqa.selenium.grid.node.Node;
import org.openqa.selenium.grid.node.local.LocalNodeFactory;
import org.openqa.selenium.grid.security.Secret;
import org.openqa.selenium.grid.security.SecretOptions;
import org.openqa.selenium.grid.server.BaseServerOptions;
import org.openqa.selenium.internal.Either;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
import org.openqa.selenium.remote.tracing.Tracer;

public class DecoratedLoggingNode extends Node {

  private Node node;

  protected DecoratedLoggingNode(Tracer tracer, NodeId nodeId, URI uri, Secret registrationSecret, Duration sessionTimeout) {
    super(tracer, nodeId, uri, registrationSecret, sessionTimeout);
  }

  public static Node create(Config config) {
    LoggingOptions loggingOptions = new LoggingOptions(config);
    BaseServerOptions serverOptions = new BaseServerOptions(config);
    URI uri = serverOptions.getExternalUri();
    SecretOptions secretOptions = new SecretOptions(config);
    NodeOptions nodeOptions = new NodeOptions(config);
    Duration sessionTimeout = nodeOptions.getSessionTimeout();

    // Refer to the foot notes for additional context on this line.
    Node node = LocalNodeFactory.create(config);

    DecoratedLoggingNode wrapper = new DecoratedLoggingNode(loggingOptions.getTracer(),
        node.getId(),
        uri,
        secretOptions.getRegistrationSecret(),
        sessionTimeout);
    wrapper.node = node;
    return wrapper;
  }

  @Override
  public Either<WebDriverException, CreateSessionResponse> newSession(
      CreateSessionRequest sessionRequest) {
    System.out.println("Before newSession()");
    try {
      return this.node.newSession(sessionRequest);
    } finally {
      System.out.println("After newSession()");
    }
  }

  @Override
  public HttpResponse executeWebDriverCommand(HttpRequest req) {
    try {
      System.out.println("Before executeWebDriverCommand(): " + req.getUri());
      return node.executeWebDriverCommand(req);
    } finally {
      System.out.println("After executeWebDriverCommand()");
    }
  }

  @Override
  public Session getSession(SessionId id) throws NoSuchSessionException {
    try {
      System.out.println("Before getSession()");
      return node.getSession(id);
    } finally {
      System.out.println("After getSession()");
    }
  }

  @Override
  public HttpResponse uploadFile(HttpRequest req, SessionId id) {
    try {
      System.out.println("Before uploadFile()");
      return node.uploadFile(req, id);
    } finally {
      System.out.println("After uploadFile()");
    }
  }

  @Override
  public void stop(SessionId id) throws NoSuchSessionException {
    try {
      System.out.println("Before stop()");
      node.stop(id);
    } finally {
      System.out.println("After stop()");
    }
  }

  @Override
  public boolean isSessionOwner(SessionId id) {
    try {
      System.out.println("Before isSessionOwner()");
      return node.isSessionOwner(id);
    } finally {
      System.out.println("After isSessionOwner()");
    }
  }

  @Override
  public boolean isSupporting(Capabilities capabilities) {
    try {
      System.out.println("Before isSupporting");
      return node.isSupporting(capabilities);
    } finally {
      System.out.println("After isSupporting()");
    }
  }

  @Override
  public NodeStatus getStatus() {
    try {
      System.out.println("Before getStatus()");
      return node.getStatus();
    } finally {
      System.out.println("After getStatus()");
    }
  }

  @Override
  public HealthCheck getHealthCheck() {
    try {
      System.out.println("Before getHealthCheck()");
      return node.getHealthCheck();
    } finally {
      System.out.println("After getHealthCheck()");
    }
  }

  @Override
  public void drain() {
    try {
      System.out.println("Before drain()");
      node.drain();
    } finally {
      System.out.println("After drain()");
    }

  }

  @Override
  public boolean isReady() {
    try {
      System.out.println("Before isReady()");
      return node.isReady();
    } finally {
      System.out.println("After isReady()");
    }
  }
}
```

***Notas de Rodapé:***

No exemplo acima, a linha `Node node = LocalNodeFactory.create(config);` cria explicitamente um `LocalNode`.

Basicamente, existem 2 tipos de implementações *visíveis para o usuário* de `org.openqa.selenium.grid.node.Node` disponíveis.

Essas classes são bons pontos de partida para aprender como criar um Node personalizado e também para compreender os detalhes internos de um Node.

* `org.openqa.selenium.grid.node.local.LocalNode` - Usado para representar um Node de execução contínua e é a implementação padrão que é usada quando você inicia um `node`.

  * Pode ser criado chamando `LocalNodeFactory.create(config);`, onde:

    * `LocalNodeFactory` pertence a `org.openqa.selenium.grid.node.local`
    * `Config` pertence a `org.openqa.selenium.grid.config`

* `org.openqa.selenium.grid.node.k8s.OneShotNode` - Esta é uma implementação de referência especial em que o Node encerra-se graciosamente após atender a uma sessão de teste. Esta classe atualmente não está disponível como parte de nenhum artefato Maven pré-construído.

  * Você pode consultar o código-fonte [aqui](https://github.com/SeleniumHQ/selenium/blob/trunk/java/src/org/openqa/selenium/grid/node/k8s/OneShotNode.java) para entender seus detalhes internos.

  * Para construí-lo localmente, consulte [aqui](https://github.com/SeleniumHQ/selenium/blob/trunk/deploys/k8s/README.md).

  * Pode ser criado chamando `OneShotNode.create(config)`, onde:

    * `OneShotNode` pertence a `org.openqa.selenium.grid.node.k8s`
    * `Config` pertence a `org.openqa.selenium.grid.config`

Última modificação May 17, 2024: [Update Custom Node Initialization in Grid Advanced Features (#1729) (808af3e6bdd)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/808af3e6bddcae225b07dc2547e4e8024feae912)

----
url: https://www.selenium.dev/zh-cn/documentation/legacy/selenium_3/grid_setup/
----

# 配置自己的服务网格

```shell
java -jar selenium-server-standalone.jar -role hub
```

转发器(hub)默认会监听4444端口，你也可以通过打开浏览器访问<http://localhost:4444/grid/console>来查看转发器(hub)的状态。

如果需要改变默认端口，你可以添加`-port`加上一个数字作为参数来代表你期望监听的端口， 同时，所有其他的可选参数都可以在下面这个JSON配置文件里找到。

你已经在上面获得了一个简单命令，当然如果你希望一些更高级的配置， 方便起见，你也可以指定一个JSON格式的配置文件来配置并启动你的转发器(hub)。 你可以这么做：

```shell
java -jar selenium-server-standalone.jar -role hub -hubConfig hubConfig.json -debug
```

下面你可以看到一个配置文件`hubConfig.json`的例子。 我们会在第二步深入探讨怎么来提供节点配置文件。

```json
{
  "_comment" : "Configuration for Hub - hubConfig.json",
  "host": ip,
  "maxSession": 5,
  "port": 4444,
  "cleanupCycle": 5000,
  "timeout": 300000,
  "newSessionWaitTimeout": -1,
  "servlets": [],
  "prioritizer": null,
  "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
  "throwOnCapabilityNotPresent": true,
  "nodePolling": 180000,
  "platform": "WINDOWS"}
```

### 第二部: 启动节点

无论你期望你的服务网格使用新的WebDriver的功能，还是Selenium 1 RC的功能，或者2者皆有。 你都只需要使用`selenium-server-standalone.jar`来启动节点。

```shell
java -jar selenium-server-standalone.jar -role node -hub http://localhost:4444
```

如果不通过`-port`来指定端口，会选一个可用端口。你也可以在一个终端机上运行多个节点， 但是如果你这么做了，你需要意识到当你的测试使用截屏会引发你的系统内存资源和问题。

#### 配置节点的可选参数

正如前面提到的，作为一个向下兼容，“wd"和”rc”这两个角色都是节点角色的合法的自己。 当节点同时允许RC饿WebDriver的远程链接时，这些角色限制了远程连接使用的API。

通过在命令行中设置JVM属性(\_在-jar参数前\_使用`-D`参数)，会被传递到节点里： `-Dwebdriver.chrome.driver=chromedriver.exe`

#### 使用JSON配置节点

你也可以使用JSON配置文件来启动服务网格节点

```shell
java -Dwebdriver.chrome.driver=chromedriver.exe -jar selenium-server-standalone.jar -role node -nodeConfig node1Config.json
```

这里是一个配置文件`nodeConfig.json`的例子:

```json
{
  "capabilities": [
    {
      "browserName": "firefox",
      "acceptSslCerts": true,
      "javascriptEnabled": true,
      "takesScreenshot": false,
      "firefox_profile": "",
      "browser-version": "27",
      "platform": "WINDOWS",
      "maxInstances": 5,
      "firefox_binary": "",
      "cleanSession": true
    },
    {
      "browserName": "chrome",
      "maxInstances": 5,
      "platform": "WINDOWS",
      "webdriver.chrome.driver": "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"
    },
    {
      "browserName": "internet explorer",
      "maxInstances": 1,
      "platform": "WINDOWS",
      "webdriver.ie.driver": "C:/Program Files (x86)/Internet Explorer/iexplore.exe"
    }
  ],
  "configuration": {
    "_comment" : "Configuration for Node",
    "cleanUpCycle": 2000,
    "timeout": 30000,
    "proxy": "org.openqa.grid.selenium.proxy.WebDriverRemoteProxy",
    "port": 5555,
    "host": ip,
    "register": true,
    "hubPort": 4444,
    "maxSession": 5
  }
}
```

```shell
java -jar selenium-server-standalone.jar -role hub -log log.txt
```

使用你习惯的文本编辑器来打开日志文件(例子里用的log.txt)，查找"ERROR"日志来定位你的问题。

### 使用 `-debug` 参数

同时，你也可以通过使用`-debug`来向控制台打印debug日志。 启动Selenium服务网格的转发器(hub)或节点的时候使用`-debug`参数。下面是一个例子：

```shell
java -jar selenium-server-standalone.jar -role hub -debug
```

## 提醒

Selenium服务网格需要使用合适的防火墙许可来隔离外部访问。

如果不能有效的保护你的服务网格，可能会导致以下问题：

* 提供了一个开发的接口来访问服务网格的基础设施
* 你将会允许第三方来访问内部web服务和文件
* 你将会允许第三方来执行定制的二进制文件

请参考这篇文章[Detectify](/zh-cn/), 这里给了一个很好的概要， 关于暴露一个服务网格后会如何被滥用：[Don’t Leave your Grid Wide Open](//labs.detectify.com/2017/10/06/guest-blog-dont-leave-your-grid-wide-open/).

## Docker Selenium

[Docker](/zh-cn/)提供了一个方便的途径来在容器中构建一个可扩张的Selenium服务网格基础设置， 容器是软件的标准单元，包含了所有执行应用程序需要的东西，包括所有的依赖，它以一种可靠的，可以复制的方法来在不同的终端机上运行。

Selenium项目维护了一组Docker镜像，你可以下载并运行来快速的获得一个可用的服务网格。 Firefox和Chrome都提供了可用的镜像。你可以在[Docker Selenium](//github.com/SeleniumHQ/docker-selenium) 找到关于如何启动服务网格的详细信息.

### 前提

创建服务网格的唯一的前提是安装了Docker并能正常运行 [Install Docker](//www.docker.com/products/docker-desktop).

----
url: https://www.selenium.dev/ja/documentation/webdriver/bidi/cdp/
----

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/CdpTest.java#L22-L27)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/CdpTest.java

```java
package dev.selenium.bidi.cdp;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chromium.HasCdp;

import java.util.HashMap;
import java.util.Map;

public class CdpTest extends BaseTest {
  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
  }

  @Test
  public void setCookie() {
    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);

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }
}
```

```py
    cookie = {'name': 'cheese',
              'value': 'gouda',
              'domain': 'www.selenium.dev',
              'secure': True}

    driver.execute_cdp_cmd('Network.setCookie', cookie)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_cdp.py#L2-L7)

##### /examples/python/tests/bidi/cdp/test\_cdp.py

```py
def test_set_cookie(driver):
    cookie = {'name': 'cheese',
              'value': 'gouda',
              'domain': 'www.selenium.dev',
              'secure': True}

    driver.execute_cdp_cmd('Network.setCookie', cookie)

    driver.get('https://www.selenium.dev')
    cheese = driver.get_cookie(cookie['name'])

    assert cheese['value'] == 'gouda'
```

```cs
            var cookie = new Dictionary<string, object>
            {
                { "name", "cheese" },
                { "value", "gouda" },
                { "domain", "www.selenium.dev" },
                { "secure", true }
            };
            ((ChromeDriver)driver).ExecuteCdpCommand("Network.setCookie", cookie);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/CDPTest.cs#L14-L21)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/CDPTest.cs

```cs
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class CDPTest : BaseChromeTest
    {
        [TestMethod]
        public void SetCookie()
        {
            var cookie = new Dictionary<string, object>
            {
                { "name", "cheese" },
                { "value", "gouda" },
                { "domain", "www.selenium.dev" },
                { "secure", true }
            };
            ((ChromeDriver)driver).ExecuteCdpCommand("Network.setCookie", cookie);
            
            driver.Url = "https://www.selenium.dev";
            Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);

        }
    }
}
```

```rb
    driver.execute_cdp('Network.setCookie',
                       name: 'cheese',
                       value: 'gouda',
                       domain: 'www.selenium.dev',
                       secure: true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/cdp_spec.rb#L9-L13)

##### /examples/ruby/spec/bidi/cdp/cdp\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'sets cookie' do
    driver.execute_cdp('Network.setCookie',
                       name: 'cheese',
                       value: 'gouda',
                       domain: 'www.selenium.dev',
                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end
end
```

***

##### [Chrome DevTools Logging Features](/ja/documentation/webdriver/bidi/cdp/logging/)

Logging features using CDP.

##### [Chrome DevTools Network Features](/ja/documentation/webdriver/bidi/cdp/network/)

Network features using CDP.

##### [Chrome DevTools Script Features](/ja/documentation/webdriver/bidi/cdp/script/)

Script features using CDP.

最終更新 August 17, 2024: [add missing foreign language pages under cdp (#1864) (36b16c7407d)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/36b16c7407d344165bcc40f266806d74e9937edc)

----
url: https://www.selenium.dev/documentation/webdriver/bidi/logging/
----

# WebDriver BiDi Logging Features

These features are related to logging. Because “logging” can refer to so many different things, these methods are made available via a “script” namespace.

Remember that to use WebDriver BiDi, you must enable it in Options. For more details, see [Enabling BiDi](https://www.selenium.dev/documentation/webdriver/bidi/)

```py
    driver.script.add_console_message_handler(log_entries.append)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/test_bidi_logging.py#L11)

##### /examples/python/tests/bidi/test\_bidi\_logging.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_console_message_handler(log_entries.append)

    driver.find_element(By.ID, "consoleLog").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Hello, world!"


@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0


@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_javascript_error_handler(log_entries.append)

    driver.find_element(By.ID, "jsException").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Error: Not working"


@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    log_entries = []
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/logging_spec.rb#L11)

##### /examples/ruby/spec/bidi/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_console_message_handler { |log| log_entries << log }

    driver.find_element(id: 'consoleLog').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Hello, world!'
  end

  it 'removes console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_console_message_handler { |log| log_entries << log }
    driver.script.remove_console_message_handler(id)

    driver.find_element(id: 'consoleLog').click
    expect(log_entries).to be_empty
  end

  it 'adds JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_javascript_error_handler { |error| log_entries << error }

    driver.find_element(id: 'jsException').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Error: Not working'
  end

  it 'removes JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_javascript_error_handler { |error| log_entries << error }
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(id: 'jsException').click
    expect(log_entries).to be_empty
  end
end
```

```py
    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/test_bidi_logging.py#L23-24)

##### /examples/python/tests/bidi/test\_bidi\_logging.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_console_message_handler(log_entries.append)

    driver.find_element(By.ID, "consoleLog").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Hello, world!"


@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0


@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_javascript_error_handler(log_entries.append)

    driver.find_element(By.ID, "jsException").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Error: Not working"


@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    log_entries = []
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/logging_spec.rb#L22-L23)

##### /examples/ruby/spec/bidi/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_console_message_handler { |log| log_entries << log }

    driver.find_element(id: 'consoleLog').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Hello, world!'
  end

  it 'removes console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_console_message_handler { |log| log_entries << log }
    driver.script.remove_console_message_handler(id)

    driver.find_element(id: 'consoleLog').click
    expect(log_entries).to be_empty
  end

  it 'adds JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_javascript_error_handler { |error| log_entries << error }

    driver.find_element(id: 'jsException').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Error: Not working'
  end

  it 'removes JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_javascript_error_handler { |error| log_entries << error }
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(id: 'jsException').click
    expect(log_entries).to be_empty
  end
end
```

```py
    driver.script.add_javascript_error_handler(log_entries.append)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/test_bidi_logging.py#L35)

##### /examples/python/tests/bidi/test\_bidi\_logging.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_console_message_handler(log_entries.append)

    driver.find_element(By.ID, "consoleLog").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Hello, world!"


@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0


@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_javascript_error_handler(log_entries.append)

    driver.find_element(By.ID, "jsException").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Error: Not working"


@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    log_entries = []
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/logging_spec.rb#L33)

##### /examples/ruby/spec/bidi/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_console_message_handler { |log| log_entries << log }

    driver.find_element(id: 'consoleLog').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Hello, world!'
  end

  it 'removes console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_console_message_handler { |log| log_entries << log }
    driver.script.remove_console_message_handler(id)

    driver.find_element(id: 'consoleLog').click
    expect(log_entries).to be_empty
  end

  it 'adds JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_javascript_error_handler { |error| log_entries << error }

    driver.find_element(id: 'jsException').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Error: Not working'
  end

  it 'removes JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_javascript_error_handler { |error| log_entries << error }
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(id: 'jsException').click
    expect(log_entries).to be_empty
  end
end
```

```py
    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/test_bidi_logging.py#L47-48)

##### /examples/python/tests/bidi/test\_bidi\_logging.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_console_message_handler(log_entries.append)

    driver.find_element(By.ID, "consoleLog").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Hello, world!"


@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0


@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_javascript_error_handler(log_entries.append)

    driver.find_element(By.ID, "jsException").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Error: Not working"


@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    log_entries = []
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/logging_spec.rb#L44-L45)

##### /examples/ruby/spec/bidi/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_console_message_handler { |log| log_entries << log }

    driver.find_element(id: 'consoleLog').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Hello, world!'
  end

  it 'removes console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_console_message_handler { |log| log_entries << log }
    driver.script.remove_console_message_handler(id)

    driver.find_element(id: 'consoleLog').click
    expect(log_entries).to be_empty
  end

  it 'adds JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_javascript_error_handler { |error| log_entries << error }

    driver.find_element(id: 'jsException').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Error: Not working'
  end

  it 'removes JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_javascript_error_handler { |error| log_entries << error }
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(id: 'jsException').click
    expect(log_entries).to be_empty
  end
end
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

----
url: https://www.selenium.dev/pt-br/documentation/legacy/selenium_ide/
----

# Selenium IDE Legado

```html
<tr>
    <td>Command</td>
    <td>target (locator)</td>
    <td>Value</td>
</tr>
```

|            |              |       |
| ---------- | ------------ | ----- |
| verifyText | //div//a\[2] | Login |

Os parâmetros nem sempre são necessários, depende do comando. Em alguns casos ambos são necessários, em outros um parâmetro é necessário, e ainda em outros, o comando pode não ter nenhum parâmetro. Aqui estão mais alguns exemplos:

|                   |             |                         |
| ----------------- | ----------- | ----------------------- |
| goBackAndWait     |             |                         |
| verifyTextPresent |             | Welcome to My Home Page |
| type              | id=phone    | (555) 666-7066          |
| type              | id=address1 | ${myVariableAddress}    |

```html
<table>
    <tr><td>open</td><td>/download/</td><td></td></tr>
    <tr><td>assertTitle</td><td></td><td>Downloads</td></tr>
    <tr><td>verifyText</td><td>//h2</td><td>Downloads</td></tr>
</table>
```

Renderizado como uma tabela em um navegador, seria assim:

|             |            |           |
| ----------- | ---------- | --------- |
| open        | /download/ |           |
| assertTitle |            | Downloads |
| verifyText  | //h2       | Downloads |

A sintaxe HTML Selenese pode ser usada para escrever e executar testes sem exigir conhecimento de uma linguagem de programação. Com um conhecimento básico de Selenese e Selenium-IDE você pode produzir e executar casos de teste rapidamente.

## Suítes de Teste

Uma suíte de testes é uma coleção de testes. Frequentemente, você executará todos os testes em uma suite de teste como um trabalho em lote contínuo.

Ao usar a Selenium-IDE, as suítes de testes também podem ser definidas usando um arquivo HTML simples. A sintaxe novamente é simples. Uma tabela HTML define uma lista de testes onde cada linha define o caminho do sistema de arquivos para cada teste. Um exemplo diz tudo.

```html
<html>
<head>
<title>Test Suite Function Tests - Priority 1</title>
</head>
<body>
<table>
  <tr><td><b>Suite Of Tests</b></td></tr>
  <tr><td><a href="./Login.html">Login</a></td></tr>
  <tr><td><a href="./SearchValues.html">Test Searching for Values</a></td></tr>
  <tr><td><a href="./SaveValues.html">Test Save</a></td></tr>
</table>
</body>
</html>
```

| Command     | Target     | Value        |
| ----------- | ---------- | ------------ |
| open        | /download/ |              |
| assertTitle |            | Downloads    |
| verifyText  | //h2       | Downloads    |
| assertTable | 1.2.1      | Selenium IDE |
| verifyTable | 1.2.2      | June 3, 2008 |
| verifyTable | 1.2.3      | 1.0 beta 2   |

O exemplo acima primeiro abre uma página e, em seguida, faz uma asserção para saber se a página correta é carregada comparando o título com o valor esperado. Só se passar, o seguinte comando será executado e verificará se o texto está presente na localização esperada. O caso de teste, então, faz uma asserção para saber se a primeira coluna na segunda linha da primeira tabela contém o valor esperado, e somente se este for aprovado as células restantes nessa linha serão “verificadas”.

### **verifyTextPresent**

O comando `verifyTextPresent` é usado para verificar se existe um texto específico em algum lugar na página. Leva um único argumento - o texto a ser verificado. Por exemplo:

| Command           | Target             | Value |
| ----------------- | ------------------ | ----- |
| verifyTextPresent | Marketing Analysis |       |

Isso faria com que o Selenium procurasse e verificasse que a string de texto “Marketing Analysis” aparece em algum lugar na página que está sendo testada. Use verifyTextPresent quando você está interessado apenas no próprio texto estar presente na página. Não use isso quando você também precisa testar onde o texto está na página.

### **verifyElementPresent**

Use este comando quando precisar testar a presença de um elemento de UI específico, em vez de seu conteúdo. Esta verificação não verifica o texto, apenas a tag HTML. Um uso comum é verificar a presença de uma imagem.

| Command              | Target      | Value |
| -------------------- | ----------- | ----- |
| verifyElementPresent | //div/p/img |       |

Este comando verifica se uma imagem, especificada pela existência de uma tag HTML `<img>`, está presente na página e aparece após uma tag `<div>` e uma tag `<p>`. O primeiro (e único) parâmetro é um localizador para informar o comando Selenese de como encontrar o elemento. Os localizadores são explicados na próxima seção.

`verifyElementPresent` pode ser usado para verificar a existência de qualquer tag HTML dentro da página. Você pode verificar a existência de links, parágrafos, divisões `<div>`, etc. Aqui estão mais alguns exemplos.

| Command              | Target                        | Value |
| -------------------- | ----------------------------- | ----- |
| verifyElementPresent | //div/p                       |       |
| verifyElementPresent | //div/a                       |       |
| verifyElementPresent | id=Login                      |       |
| verifyElementPresent | link=Go to Marketing Research |       |
| verifyElementPresent | //a\[2]                       |       |
| verifyElementPresent | //head/title                  |       |

Esses exemplos ilustram a variedade de maneiras pelas quais um elemento de UI pode ser testado. Novamente, os localizadores são explicados na próxima seção.

### **verifyText**

Use `verifyText` quando o texto e seu elemento de UI devem ser testados. verifyText deve usar um localizador. Se você escolher um localizador *XPath* ou *DOM*, você pode verificar se um texto específico aparece em um local específico na página em relação a outro componente na página.

| Command    | Target              | Value                                                               |
| ---------- | ------------------- | ------------------------------------------------------------------- |
| verifyText | //table/tr/td/div/p | This is my text and it occurs right after the div inside the table. |

## Localizando elementos

Para muitos comandos do Selenium, um alvo é necessário. Este alvo identifica um elemento no conteúdo do aplicativo da web, e consiste na estratégia de localização seguida pela localização no formato `locatorType = location`. O tipo de localizador pode ser omitido em muitos casos. Os vários tipos de localizadores são explicados abaixo com exemplos para cada um.

### Localizando pelo Identificador

Este é provavelmente o método mais comum de localização de elementos e é o padrão quando nenhum tipo de localizador reconhecido é usado. Com esta estratégia, o primeiro elemento com o valor do atributo id correspondente ao local será usado. E se nenhum elemento tem um atributo *id* correspondente, então o primeiro elemento com um atributo *name* correspondente ao local será usado.

Por exemplo, o código fonte da sua página pode ter atributos id e name do seguinte modo:

```html
  <html>
   <body>
    <form id="loginForm">
     <input name="username" type="text" />
     <input name="password" type="password" />
     <input name="continue" type="submit" value="Login" />
    </form>
   </body>
  <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
    </body>
   <html>
```

* `id=loginForm` (3)

### Localizando pelo *name*

O tipo Localizador de Nome irá localizar o primeiro elemento com um atributo *name* correspondente. Se vários elementos tiverem o mesmo valor para um atributo *name*, então você pode usar filtros para refinar ainda mais sua estratégia de localização. O tipo de filtro padrão é *value* (correspondendo ao atributo *value*).

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
  <html>
   <body>
    <p>Are you sure you want to do this?</p>
    <a href="continue.html">Continue</a> 
    <a href="cancel.html">Cancel</a>
  </body>
  <html>
```

* `link=Continue` (4)
* `link=Cancel` (5)

### Localizando pelo DOM

O Document Object Model representa um documento HTML e pode ser acessado usando JavaScript. Esta estratégia de localização usa um JavaScript que representa um elemento na página, que pode ser simplesmente a localização do elemento usando a notação hierárquica.

Uma vez que apenas os localizadores `dom` começam com “document”, não é necessário incluir o rótulo `dom=` ao especificar um localizador DOM.

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input class="required" name="username" type="text" />
      <input class="required passfield" name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | glob:\*Film\*Television\*             |       |

O título real da página acessada clicando no link era “De Anza Film And Television Department - Menu”. Usando um padrão em vez do texto exato, o `verifyTitle` vai passar enquanto as duas palavras “Film” e “Television” aparecerem (nessa ordem) em qualquer lugar no título da página. Por exemplo, se o proprietário da página encurtar o título apenas para “Film & Television Department”, o teste ainda seria aprovado. Usar um padrão para um link e um teste simples de que o link funcionou (como o `verifyTitle` acima faz) pode reduzir bastante a manutenção de tais casos de teste.

#### Padrão de Expressões Regulares

Os padrões de *expressão regular* são os mais poderosos dos três tipos de padrões que o Selenese suporta. Expressões regulares também são suportados pela maioria das linguagens de programação de alto nível, muitos editores de texto e uma série de ferramentas, incluindo utilitários **grep**, **sed** e **awk** da linha de comando Linux / Unix. Em Selenese, padrões de expressão regular permitem que um usuário execute muitas tarefas que iriam ser muito difíceis de outra forma. Por exemplo, suponha que seu teste precise garantir que uma determinada célula da tabela contivesse nada além de um número. `regexp:[0-9]+` é um padrão simples que corresponderá a um número decimal de qualquer comprimento.

Enquanto os padrões de Globbing do Selenese suportam apenas o **\*** e **\[ ]** (classe de caracteres), os padrões de expressão regular Selenese oferecem a mesma ampla gama de caracteres especiais que existem em JavaScript. Abaixo está um subconjunto desses caracteres especiais:

| PATTERN | MATCH                                                                     |
| ------- | ------------------------------------------------------------------------- |
| .       | qualquer caractere isolado                                                |
| \[ ]    | classe de caracteres: qualquer caractere definido dentros dos colchetes   |
| \*      | quantificação: 0 ou mais do caractere anterior (ou grupo)                 |
| +       | quantificação: 1 ou mais do caractere anterior (ou grupo)                 |
| ?       | quantificação: 0 ou 1 do caractere anterior (ou grupo)                    |
| {1,5}   | quantificação: 1 até 5 repetições do caractere anterior (ou grupo)        |
| \|      | alternação: o caractere/grupo na esquerda OU o caractere/grupo na direita |
| ( )     | agrupamento: normalmente usado com alternação e/ou quantificação          |

Os padrões de expressão regular em Selenese precisam ser prefixados com `regexp:` ou `regexpi:`. O primeiro é sensível a maiúsculas e minúsculas; o último não faz distinção entre maiúsculas e minúsculas.

Alguns exemplos ajudarão a esclarecer como os padrões de expressão regular podem ser usados com comandos Selenese. O primeiro usa o que é provavelmente o padrão de expressão regular mais comumente usado - **.\*** (“ponto estrela”). Esta sequência de dois caracteres pode ser traduzida como “0 ou mais ocorrências de qualquer caractere” ou, mais simplesmente, “qualquer coisa ou nada.” É o equivalente do padrão globbing de um caractere **\*** (um único asterisco).

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | regexp:.\*Film.\*Television.\*        |       |

O exemplo acima é funcionalmente equivalente ao exemplo anterior que usou padrões de globbing para este mesmo teste. As únicas diferenças são o prefixo (**regexp:** em vez de **glob:**) e o padrão “qualquer coisa ou nada” (**.\*** em vez de apenas **\***).

O exemplo mais complexo abaixo testa que a página de clima do Yahoo! para Anchorage, Alasca, contém informações sobre o horário do nascer do sol:

| Command           | Target                                            | Value |
| ----------------- | ------------------------------------------------- | ----- |
| open              | <http://weather.yahoo.com/forecast/USAK0012.html> |       |
| verifyTextPresent | regexp:Sunrise: \*\[0-9]{1,2}:\[0-9]{2} \[ap]m    |       |

Vamos examinar a expressão regular acima em partes:

|              |                                                         |
| ------------ | ------------------------------------------------------- |
| `Sunrise: *` | A string **Sunrise:** seguida por 0 ou mais espaços     |
| `[0-9]{1,2}` | 1 ou 2 dígitos (para a hora do dia)                     |
| `:`          | O caractere **:** (sem caracteres especiais envolvidos) |
| `[0-9]{2}`   | 2 dígitos (para os minutos) seguidos de um espaço       |
| `[ap]m`      | “a” ou “p” seguido por “m” (am ou pm)                   |

#### Padrão Exato

O tipo de padrão **exato** do Selenium é de utilidade marginal. Ele não usa nenhum caractere especial. Então, se você precisasse procurar um caractere de asterisco real (que é especial para globbing e padrões de expressão regular), o padrão **exato** seria uma maneira fazer isso. Por exemplo, se você quiser selecionar um item rotulado “Real\*” em uma lista suspensa, o código a seguir pode funcionar ou não. O asterisco no padrão `glob:Real*` irá corresponder a qualquer coisa ou a nada. Portanto, se houvesse uma opção de seleção anterior rotulada “Números reais”, ser a opção selecionada em vez da opção “Real\*”.

| Command | Target   | Value        |
| ------- | -------- | ------------ |
| select  | //select | glob:Real \* |

A fim de garantir que o item “Real\*” seja selecionado, o prefixo `exact:` pode ser usado para criar um padrão **exato** conforme mostrado abaixo:

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| select  | //select | exact:Real \* |

Mas o mesmo efeito pode ser alcançado escapando o asterisco em um padrão de expressão regular:

| Command | Target   | Value            |
| ------- | -------- | ---------------- |
| select  | //select | regexp:Real \\\* |

| Command | Target            | Value |
| ------- | ----------------- | ----- |
| store   | <paul@mysite.org> |       |

Posteriormente em seu script, você desejará usar o valor armazenado de sua variável. Para acessar o valor de uma variável, coloque a variável em colchetes ({}) e preceda-a com um cifrão como a seguir.

| Command    | Target  | Value         |
| ---------- | ------- | ------------- |
| verifyText | //div/p | \\${userName} |

Um uso comum de variáveis é armazenar a entrada para um campo input.

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| type    | id=login | \\${userName} |

| Command         | Target                                         | Value       |
| --------------- | ---------------------------------------------- | ----------- |
| store           | 10                                             | hits        |
| storeXpathCount | //blockquote                                   | blockquotes |
| storeEval       | storedVars\[‘hits’].storedVars\[‘blockquotes’] | paragraphs  |

Este próximo exemplo ilustra como um snippet de JavaScript pode incluir chamadas para métodos, neste caso, os métodos `toUpperCase` e `toLowerCase`do objeto JavaScript String.

| Command   | Target                            | Value |
| --------- | --------------------------------- | ----- |
| store     | Edith Wharton                     | name  |
| storeEval | storedVars\[’name’].toUpperCase() | uc    |
| storeEval | storedVars\[’name’].toUpperCase() | lc    |

#### Usando JavaScript com parâmetros não-script

JavaScript também pode ser usado para ajudar a gerar valores para parâmetros, mesmo quando o parâmetro não é especificado para ser do tipo **script**. No entanto, neste caso, uma sintaxe especial é necessária - o parâmetro *inteiro* deve ser prefixado por `javascript{` com um `}` final, que envolve o snippet JavaScript, como em `javascript{*yourCodeHere*}`. Abaixo está um exemplo em que o segundo parâmetro do comando `type`

* `value` - é gerado através do código JavaScript usando esta sintaxe especial:

| Command | Target            | Value                                                 |
| ------- | ----------------- | ----------------------------------------------------- |
| store   | league of nations | searchString                                          |
| type    | q                 | javascript{storedVars\[‘searchString’].toUpperCase()} |

## *echo* - O comando de print do Selenese

Selenese tem um comando simples que permite imprimir texto para a saída do seu teste. Isso é útil para fornecer notas de progresso informativas em seu teste que são exibidas no console durante a execução. Essas notas também podem ser usadas para fornecer contexto em seus relatórios de resultados de teste, o que pode ser útil para descobrir onde existe um defeito em uma página, caso seu teste encontre um problema. Finalmente, declarações echo podem ser usadas para imprimir o conteúdo de variáveis Selenium.

| Command | Target                    | Value |
| ------- | ------------------------- | ----- |
| echo    | Testing page footer now.  |       |
| echo    | Username is \\${userName} |       |

## Alertas, Popups e Múltiplas Janelas

Suponha que você esteja testando uma página semelhante a esta.

```html
  <!DOCTYPE HTML>
  <html>
  <head>
    <script type="text/javascript">
      function output(resultText){
        document.getElementById('output').childNodes[0].nodeValue=resultText;
      }

      function show_confirm(){
        var confirmation=confirm("Chose an option.");
        if (confirmation==true){
          output("Confirmed.");
        }
        else{
          output("Rejected!");
        }
      }
      
      function show_alert(){
        alert("I'm blocking!");
        output("Alert is gone.");
      }
      function show_prompt(){
        var response = prompt("What's the best web QA tool?","Selenium");
        output(response);
      }
      function open_window(windowName){
        window.open("newWindow.html",windowName);
      }
      </script>
  </head>
  <body>

    <input type="button" id="btnConfirm" onclick="show_confirm()" value="Show confirm box" />
    <input type="button" id="btnAlert" onclick="show_alert()" value="Show alert" />
    <input type="button" id="btnPrompt" onclick="show_prompt()" value="Show prompt" />
    <a href="newWindow.html" id="lnkNewWindow" target="_blank">New Window Link</a>
    <input type="button" id="btnNewNamelessWindow" onclick="open_window()" value="Open Nameless Window" />
    <input type="button" id="btnNewNamedWindow" onclick="open_window('Mike')" value="Open Named Window" />

    <br />
    <span id="output">
    </span>
  </body>
  </html>
```

O usuário deve responder às caixas de alerta / confirmação, bem como mover o foco para as novas janelas pop-up abertas. Felizmente, o Selenium pode cobrir pop-ups de JavaScript.

Mas antes de começarmos a abordar alertas / confirmações / solicitações em detalhes individuais, é útil compreender a semelhança entre eles. Alertas, caixas de confirmação e todos os prompts têm variações do seguinte

| Command                   | Description                                                              |
| ------------------------- | ------------------------------------------------------------------------ |
| assertFoo(pattern)        | gera erro se o padrão não corresponder ao texto do pop-up                |
| assertFooPresent          | gera erro se o pop-up estiver presente                                   |
| assertFooNotPresent       | gera um erro se algum pop-up não estiver presente                        |
| storeFoo(variable)        | armazena o texto do pop-up em uma variável                               |
| storeFooPresent(variable) | armazena o texto do pop-up em uma variável e retorna verdadeiro ou falso |

Ao executar no Selenium, pop-ups de JavaScript não aparecerão. Isto é porque as chamadas de função são realmente substituídas em tempo de execução pelo próprio JavaScript do Selenium. No entanto, só porque você não pode ver o pop-up, não significa que você não tem que lidar com isso. Para lidar com um pop-up, você deve chamar sua função `assertFoo(padrão)`. Se você falhar em fazer a asserção da presença de um pop-up, seu próximo comando será bloqueado e você obterá um erro semelhante ao seguinte `[error] Error: There was an unexpected Confirmation! [Chose an option.]`

### Alertas

Vamos começar com alertas porque eles são os pop-ups mais simples de lidar. Para começar, abra o exemplo de HTML acima em um navegador e clique no botão “Show alert”. Você vai observar que, depois de fechar o alerta, o texto “Alert is gone.” é exibido na página. Agora execute as mesmas etapas com a gravação da Selenium IDE e verifique que o texto é adicionado após fechar o alerta. Seu teste será parecido com este:

| Command           | Target         | Value |
| ----------------- | -------------- | ----- |
| open              | /              |       |
| click             | btnAlert       |       |
| assertAlert       | I’m blocking!  |       |
| verifyTextPresent | Alert is gone. |       |

Você pode estar pensando: “Isso é estranho, nunca tentei fazer uma asserção nesse alerta.” Mas isso é a Selenium-IDE manipulando e fechando o alerta para você. Se você remover essa etapa e repetir o teste você obterá o seguinte erro `[error] Error: There was an unexpected Alert! [I'm blocking!]`. Você deve incluir uma asserção do alerta para reconhecer sua presença.

Se você apenas deseja verificar que um alerta está presente, mas não sabe ou não se importa o texto que ele contém, você pode usar `assertAlertPresent`. Isso retornará verdadeiro ou falso, sendo que falso faz o teste parar.

### Confirmações

As confirmações se comportam da mesma forma que os alertas, com `assertConfirmation` e `assertConfirmationPresent` oferecendo as mesmas características de suas contrapartes de alerta. No entanto, por padrão, o Selenium selecionará OK quando uma confirmação for exibida. Tente gravar clicando no botão “Show confirm box” na página de amostra, mas clique no botão “Cancel” no pop-up e, em seguida, confirme o texto de saída. Seu teste pode ser semelhante a este:

| Command                        | Target            | Value |
| ------------------------------ | ----------------- | ----- |
| open                           | /                 |       |
| click                          | btnConfirm        |       |
| chooseCancelOnNextConfirmation |                   |       |
| assertConfirmation             | Choose an option. |       |
| verifyTextPresent              | Rejected          |       |

A função `chooseCancelOnNextConfirmation` diz ao Selenium que todas as seguintes confirmações devem retornar falso. Ela pode ser redefinido chamando chooseOkOnNextConfirmation.

Você vai notar que não pode repetir este teste, porque o Selenium reclama que há uma confirmação não tratada. Isso ocorre porque a ordem dos registros de eventos do Selenium-IDE faz com que o clique e chooseCancelOnNextConfirmation sejam colocados na ordem errada (faz sentido se você pensar sobre isso, o Selenium não pode saber que você está cancelando antes de abrir uma confirmação). Simplesmente troque esses dois comandos e seu teste funcionará bem.

### Prompts

Os prompts se comportam da mesma forma que os alertas, com `assertPrompt` e `assertPromptPresent` oferecendo as mesmas características que suas contrapartes de alerta. Por padrão, o Selenium irá esperar você inserir dados quando o prompt for exibido. Tente gravar clicando no botão “Show prompt” na página de amostra e digite “Selenium” no prompt. Seu teste pode ser semelhante a este:

| Command            | Target                       | Value |
| ------------------ | ---------------------------- | ----- |
| open               | /                            |       |
| answerOnNextPrompt | Selenium!                    |       |
| click              | id=btnPrompt                 |       |
| assertPrompt       | What’s the best web QA tool? |       |
| verifyTextPresent  | Selenium!                    |       |

```html
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Sample Selenium Test Suite</title>
    </head>
    <body>
        <table cellpadding="1" cellspacing="1" border="1">
            <thead>
                <tr><td>Test Cases for De Anza A-Z Directory Links</td></tr>
            </thead>
        <tbody>
            <tr><td><a href="./a.html">A Links</a></td></tr>
            <tr><td><a href="./b.html">B Links</a></td></tr>
            <tr><td><a href="./c.html">C Links</a></td></tr>
            <tr><td><a href="./d.html">D Links</a></td></tr>
        </tbody>
        </table>
    </body>
</html>
```

***

*error loading test case: no command found*

Você usou **File => Open** para tentar abrir um arquivo de suíte de testes. Use **File => Open Test Suite** em vez disso.

Uma solicitação de aprimoramento foi levantada para melhorar esta mensagem de erro. Veja a [issue 1010](http://code.google.com/p/selenium/issues/detail?id=1010).

***

Este tipo de **erro** pode indicar um problema de tempo, ou seja, o elemento especificado por um localizador em seu comando não foi totalmente carregado quando o comando foi executado. Tente colocar um **pause 5000** antes do comando para determinar se o problema está realmente relacionado ao tempo. Em caso afirmativo, investigue usando um comando **waitFor\*** ou **\*AndWait** apropriado antes do comando com falha.

***

Sempre que sua tentativa de usar a substituição de variável falha, como é o caso para o comando **open** acima, isso indica que você não criou realmente a variável cujo valor você está tentando acessar. Isto é às vezes devido a colocar a variável no campo **Valor** quando deve estar no campo **Destino** ou vice-versa. No exemplo acima, os dois parâmetros para o comando **store** foram erroneamente colocados na ordem inversa do que é necessário. Para qualquer comando Selenese, o primeiro parâmetro obrigatório deve ir no campo **Destino** e o segundo parâmetro obrigatório (se houver) deve ir no campo **Valor**.

***

*error loading test case: \[Exception… “Component returned failure code: 0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND) \[nsIFileInputStream.init]” nresult: “0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND)” location: “JS frame :: chrome://selenium-ide/content/file-utils.js :: anonymous :: line 48” data: no]*

Um dos casos de teste em seu conjunto de testes não pode ser encontrado. Certifique-se de que o caso de teste está realmente localizado onde o conjunto de testes indica que ele está localizado. Além disso, certifique-se de que seus arquivos de caso de teste tenham a extensão .html em seus nomes de arquivo e no arquivo de suíte de testes onde são referenciados.

Uma solicitação de aprimoramento foi levantada para melhorar esta mensagem de erro. Veja a [issue 1011](http://code.google.com/p/selenium/issues/detail?id=1011).

***

O conteúdo do seu arquivo de extensão não foi lido pela Selenium-IDE. Certifique-se de ter especificado o nome do caminho adequado para o arquivo de extensões via **Options => Options => General** no campo **Selenium Core extensions**. Além disso, a Selenium-IDE deve ser reiniciada após qualquer alteração em um arquivo de extensões *ou* no conteúdo do campo **Selenium Core extensions**.

***

##### [HTML runner](/pt-br/documentation/legacy/selenium_ide/html_runner/)

Execute HTML Selenium IDE exports from command line

----
url: https://www.selenium.dev/ja/documentation/webdriver/interactions/cookies/
----

# クッキーの使用

```java

    WebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L30-L32)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L5-L9)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L32-L34)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L9-L11)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L18)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

  const {Browser, Builder} = require("selenium-webdriver");
  const assert = require('assert')
  
  
  describe('Cookies', function() {
    let driver;
  
    before(async function() {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('Create a cookie', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // set a cookie on the current domain
      await driver.manage().addCookie({ name: 'key', value: 'value' });
    });
  
    it('Create cookies with sameSite', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
      await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
      await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
    });
  
    it('Read cookie', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // set a cookie on the current domain
      await driver.manage().addCookie({ name: 'foo', value: 'bar' });
  
      // Get cookie details with named cookie 'foo'
      await driver.manage().getCookie('foo').then(function(cookie) {
        assert.equal(cookie.value, 'bar');
      });
    });
  
    it('Read all cookies', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // Add few cookies
      await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
      await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
  
      // Get all Available cookies
      await driver.manage().getCookies().then(function(cookies) {
        assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
      });
    });
  
    it('Delete a cookie', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // Add few cookies
      await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
      await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
  
      // Delete a cookie with name 'test1'
      await driver.manage().deleteCookie('test1');
  
      // Get all Available cookies
      await driver.manage().getCookies().then(function(cookies) {
        assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
      });
    });
  
    it('Delete all cookies', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // Add few cookies
      await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
      await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
  
      // Delete all cookies
      await driver.manage().deleteAllCookies();
    });
  });
  
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")

        // Adds the cookie into current browser context
        driver.manage().addCookie(Cookie("key", "value"))
    } finally {
        driver.quit()
    }
}  
  
```

```java
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L38-L42)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L13-L20)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L40-L44)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L17-L21)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L35-L38)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("foo", "bar"))

        // Get cookie details with named cookie 'foo'
        val cookie = driver.manage().getCookieNamed("foo")
        println(cookie)
    } finally {
        driver.quit()
    }
}  
  
```

```java
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L52-L66)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L24-L32)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L51-L64)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L26-L31)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L49-L51)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        driver.manage().addCookie(Cookie("test2", "cookie2"))

        // Get All available cookies
        val cookies = driver.manage().cookies
        println(cookies)
    } finally {
        driver.quit()
    }
}  
  
```

```java
        }
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L74-L77)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L35-L43)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L70-L73)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L40-L43)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L61-L62)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        val cookie1 = Cookie("test2", "cookie2")
        driver.manage().addCookie(cookie1)

        // delete a cookie with name 'test1'
        driver.manage().deleteCookieNamed("test1")

        // delete cookie by passing cookie object of current browsing context.
        driver.manage().deleteCookie(cookie1)
    } finally {
        driver.quit()
    }
}  
  
```

```java
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L100-L105)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L47-L55)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L92-L97)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L49-L54)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L77-L78)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        driver.manage().addCookie(Cookie("test2", "cookie2"))

        // deletes all cookies
        driver.manage().deleteAllCookies()
    } finally {
        driver.quit()
    }
}  
  
```

```java

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L112-L121)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L59-L71)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SameSiteCookie {
  class SameSiteCookie {
    static void Main(string[] args) {
      IWebDriver driver = new ChromeDriver();
      try {
        driver.Navigate().GoToUrl("http://www.example.com");

        var cookie1Dictionary = new System.Collections.Generic.Dictionary<string, object>() {
          { "name", "test1" }, { "value", "cookie1" }, { "sameSite", "Strict" } };
        var cookie1 = Cookie.FromDictionary(cookie1Dictionary);

        var cookie2Dictionary = new System.Collections.Generic.Dictionary<string, object>() {
          { "name", "test2" }, { "value", "cookie2" }, { "sameSite", "Lax" } };
        var cookie2 = Cookie.FromDictionary(cookie2Dictionary);

        driver.Manage().Cookies.AddCookie(cookie1);
        driver.Manage().Cookies.AddCookie(cookie2);

        System.Console.WriteLine(cookie1.SameSite);
        System.Console.WriteLine(cookie2.SameSite);
      } finally {
        driver.Quit();
      }
    }
  }
}
  
```

```ruby
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://www.example.com'
  # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
  driver.manage.add_cookie(name: "foo", value: "bar", same_site: "Strict")
  driver.manage.add_cookie(name: "foo1", value: "bar", same_site: "Lax")
  puts driver.manage.cookie_named('foo')
  puts driver.manage.cookie_named('foo1')
ensure
  driver.quit
end
  
```

```js
  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L24-L26)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("http://www.example.com")
        val cookie = Cookie.Builder("key", "value").sameSite("Strict").build()
        val cookie1 = Cookie.Builder("key", "value").sameSite("Lax").build()
        driver.manage().addCookie(cookie)
        driver.manage().addCookie(cookie1)
        println(cookie.getSameSite())
        println(cookie1.getSameSite())
    } finally {
        driver.quit()
    }
} 
  
```

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/interactions/alerts/
----

# Alertas, prompts e confirmações JavaScript

```java

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L36-L41)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L12-L18)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L15-L22)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L19-L21)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See an example alert")).click()

//Wait for the alert to be displayed and store it in a variable
val alert = wait.until(ExpectedConditions.alertIsPresent())

//Store the alert text in a variable
val text = alert.getText()

//Press the OK button
alert.accept()
  
```

```java
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L131-L138)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L26-L32)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See a sample confirm")).Click();

//Wait for the alert to be displayed
wait.Until(ExpectedConditions.AlertIsPresent());

//Store the alert in a variable
IAlert alert = driver.SwitchTo().Alert();

//Store the alert in a variable for reuse
string text = alert.Text;

//Press the Cancel button
alert.Dismiss();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L28-L35)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L30-L32)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See a sample confirm")).click()

//Wait for the alert to be displayed
wait.until(ExpectedConditions.alertIsPresent())

//Store the alert in a variable
val alert = driver.switchTo().alert()

//Store the alert in a variable for reuse
val text = alert.text

//Press the Cancel button
alert.dismiss()
  
```

```java
        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L79-L84)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L40-L47)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See a sample prompt")).Click();

//Wait for the alert to be displayed and store it in a variable
IAlert alert = wait.Until(ExpectedConditions.AlertIsPresent());

//Type your message
alert.SendKeys("Selenium");

//Press the OK button
alert.Accept();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L41-L48)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L42-L45)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See a sample prompt")).click()

//Wait for the alert to be displayed and store it in a variable
val alert = wait.until(ExpectedConditions.alertIsPresent())

//Type your message
alert.sendKeys("Selenium")

//Press the OK button
alert.accept()
  
```

Última modificação August 14, 2025: [Fixing path for code block (c7fcb0099f5)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/c7fcb0099f58ba4d4dd467a8c6667f6130749d82)

----
url: https://www.selenium.dev/zh-cn/documentation/ie_driver_server/internals/
----

最后修改 January 10, 2022: [More wiki (#907) \[deploy site\] (adcf706a1ad)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/adcf706a1ad907d028dc57d10201a265972432af)

----
url: https://www.selenium.dev/documentation/legacy/selenium_2/grid_platforms/
----

# History of Grid Platforms

```
	[[DesiredCapabilities]] capability = DesiredCapabilities.internetExplorer();
	capability.setVersion("8");
	capability.setPlatform(Platform.XP);
	WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
```

The request for a new session with specified DesiredCapability is sent to the Grid Hub, which will look through all of the registered nodes to see if any of them match the specification given by the test. If no node matches the specification, a CapabilityNotPresentOnTheGridException will be returned.

It is a common misconception that the PLATFORM determines the ability to choose the Operating System on which the new session will be created. In this situation, platform and operating system are not the same, thus specifying the platform to “Windows 2003 Server” will not allow you to choose between a Windows XP, Vista, and 2003 server. This misconception can be born from platforms such as Mac OSX and Linux, where the name of the platform matches the name of the Operating System.

In case of Selenium Grid, platform refers to the underlying interactions between the Driver Atoms and the web browser. Mac OSX and Linux based Operating Systems (Centos, Ubuntu, Debian, etc..) have a relatively stable communication with the web browsers such as Firefox and Chrome. Thus the platform names are simple to understand, as seen in the example bellow:

```
   capability.setPlatform(Platform.MAC);   //Set platform to OSX
   capability.setPlatform(Platform.LINUX); // Set platform to Linux based systems
```

The prior to release of Vista, Windows based Operating Systems only had one platform, shown here:

```
	capability.setPlatform(Platform.WINDOWS); //Set platform to Windows
```

However, with the introduction of UAC in Windows Vista, there were major changes done to the underlying interactions between WebDriver and Internet Explorer. To work around the UAC constrains a new platform was added to nodes with Windows based Operating systems:

```
	capability.setPlatform(Platform.VISTA); //Set platform to VISTA
```

With the release of Windows 8, another major overhaul happened in how the WebDriver communicates with Internet Explorer, thus a new platform was added for Windows 8 based nodes:

```
	capability.setPlatform(Platform.WIN8); //Set platform to Windows 8
```

Similar story happened with introduction of Windows 8.1, in this example the platform is set to Windows 8.1:

```
	capability.setPlatform(Platform.WIN8_1); //Set platform to Windows 8.1
```

```
  	capability.setPlatform(Platform.VISTA); //Will return a node with Windows Vista or 2008 Server or Windows 7 Operating System.
  	capability.setPlatform(Platform.XP);   //Will return a node with Windows XP or 2003 Server or Windows 2000 Professional Operating System.   
  	capability.setPlatform(Platform.WINDOWS); //Will return a node with ANY Windows Operating System
```

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/troubleshooting/errors/
----

# Understanding Common Errors

***

##### [Unable to Locate Driver Error](/pt-br/documentation/webdriver/troubleshooting/errors/driver_location/)

Troubleshooting missing path to driver executable.

Última modificação May 12, 2026: [docs: add Selenium Wait Generator to NoSuchElementException solutions (#2627) (a25fe46dcbf)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/a25fe46dcbfe2b07ccb95ec80923b9d94eadd12b)

----
url: https://www.selenium.dev/ja/documentation/webdriver/bidi/w3c/input/
----

# Browsing Context

```java
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ActionsTest.java#L41-L44)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ActionsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Input;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.interactions.Actions;

class ActionsTest extends BaseTest {
    private Input input;

    private String windowHandle;

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        windowHandle = driver.getWindowHandle();
        input = new Input(driver);
    }

    @Test
    void canPerformInputActions() {
        driver.get("https://www.selenium.dev/selenium/web/formSelectionPage.html");

        List<WebElement> options = driver.findElements(By.tagName("option"));

        Actions actions = new Actions(driver);
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());

        WebElement showButton = driver.findElement(By.name("showselected"));
        showButton.click();

        WebElement resultElement = driver.findElement(By.id("result"));
        Assertions.assertTrue(resultElement.getText().contains("roquefort parmigiano cheddar"));
        }

    @Test
    void canPerformReleaseAction() {
        driver.get("https://www.selenium.dev/selenium/web/bidi/release_action.html");

        WebElement inputTextBox = driver.findElement(By.id("keys"));

        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);

        List<Map<String, Object>> events =
                (List<Map<String, Object>>)
                        ((JavascriptExecutor) driver).executeScript("return allEvents.events");
        Assertions.assertEquals("KeyB", events.get(0).get("code"));
        Assertions.assertEquals("KeyA", events.get(1).get("code"));
        }
    }
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/input.spec.js#L27-L29)

##### /examples/javascript/test/bidirectional/input.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, Key, Builder} = require("selenium-webdriver")
const Input = require('selenium-webdriver/bidi/input')

describe('Input module', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can perform input action', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/formSelectionPage.html')

    let options = await driver.findElements(By.tagName('option'))

    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)

    let showButton = await driver.findElement(By.name('showselected'))
    showButton.click()

    let resultElement = await driver.findElement(By.id('result'))
    await resultElement.getText().then(function (text) {
      assert(text.includes('oquefort parmigiano cheddar'), `text is: ${text}`)
    })
  })

  it('can execute release in browsing context', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/bidi/release_action.html')

    let inputTextBox = await driver.findElement(By.id('keys'))

    await driver.executeScript('arguments[0].focus()', inputTextBox)

    const actions = driver.actions().keyDown('a').keyDown('b').getSequences()

    await input.perform(browsingContextId, actions)

    await driver.executeScript('resetEvents()')

    await input.release(browsingContextId)

    const events = await driver.executeScript('return allEvents.events')

    assert.strictEqual(events[0].code, 'KeyB')
    assert.strictEqual(events[1].code, 'KeyA')
  })
})
```

```java
        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ActionsTest.java#L59-L65)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ActionsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Input;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.interactions.Actions;

class ActionsTest extends BaseTest {
    private Input input;

    private String windowHandle;

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        windowHandle = driver.getWindowHandle();
        input = new Input(driver);
    }

    @Test
    void canPerformInputActions() {
        driver.get("https://www.selenium.dev/selenium/web/formSelectionPage.html");

        List<WebElement> options = driver.findElements(By.tagName("option"));

        Actions actions = new Actions(driver);
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());

        WebElement showButton = driver.findElement(By.name("showselected"));
        showButton.click();

        WebElement resultElement = driver.findElement(By.id("result"));
        Assertions.assertTrue(resultElement.getText().contains("roquefort parmigiano cheddar"));
        }

    @Test
    void canPerformReleaseAction() {
        driver.get("https://www.selenium.dev/selenium/web/bidi/release_action.html");

        WebElement inputTextBox = driver.findElement(By.id("keys"));

        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);

        List<Map<String, Object>> events =
                (List<Map<String, Object>>)
                        ((JavascriptExecutor) driver).executeScript("return allEvents.events");
        Assertions.assertEquals("KeyB", events.get(0).get("code"));
        Assertions.assertEquals("KeyA", events.get(1).get("code"));
        }
    }
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await input.release(browsingContextId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/input.spec.js#L55)

##### /examples/javascript/test/bidirectional/input.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, Key, Builder} = require("selenium-webdriver")
const Input = require('selenium-webdriver/bidi/input')

describe('Input module', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can perform input action', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/formSelectionPage.html')

    let options = await driver.findElements(By.tagName('option'))

    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)

    let showButton = await driver.findElement(By.name('showselected'))
    showButton.click()

    let resultElement = await driver.findElement(By.id('result'))
    await resultElement.getText().then(function (text) {
      assert(text.includes('oquefort parmigiano cheddar'), `text is: ${text}`)
    })
  })

  it('can execute release in browsing context', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/bidi/release_action.html')

    let inputTextBox = await driver.findElement(By.id('keys'))

    await driver.executeScript('arguments[0].focus()', inputTextBox)

    const actions = driver.actions().keyDown('a').keyDown('b').getSequences()

    await input.perform(browsingContextId, actions)

    await driver.executeScript('resetEvents()')

    await input.release(browsingContextId)

    const events = await driver.executeScript('return allEvents.events')

    assert.strictEqual(events[0].code, 'KeyB')
    assert.strictEqual(events[1].code, 'KeyA')
  })
})
```

----
url: https://www.selenium.dev/ja/documentation/webdriver/actions_api/pen/
----

```java
        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/PenTest.java#L26-L33)

##### /examples/java/src/test/java/dev/selenium/actions\_api/PenTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PenTest extends BaseChromeTest {
    @Test
    public void usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();

        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    @Test
    public void setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();
        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("-72", moveBy.get("tiltX"));
        Assertions.assertEquals("9", moveBy.get("tiltY"));
        Assertions.assertEquals("86", moveBy.get("twist"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    private Map<String, String> getPropertyInfo(WebElement element) {
        String text = element.getText();
        text = text.substring(text.indexOf(' ') + 1);

        return Arrays.stream(text.split(", "))
                .map(s -> s.split(": "))
                .collect(Collectors.toMap(
                        a -> a[0],
                        a -> a[1]
                ));
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_pen.py#L12-L20)

##### /examples/python/tests/actions\_api/test\_pen.py

```py
import math

from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.interaction import POINTER_PEN
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.by import By


def test_use_pen(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def test_set_pointer_event_properties(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert move_by["tiltX"] == "-72"
    assert move_by["tiltY"] == "9"
    assert move_by["twist"] == "86"
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def properties(element):
    kv = element.text.split(' ', 1)[1].split(', ')
    return {x[0]:x[1] for x in list(map(lambda item: item.split(': '), kv))}
```

```cs
            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs#L19-L28)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class PenTest : BaseChromeTest
    {
        [TestMethod]
        public void UsePen()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        [TestMethod]
        public void SetPointerEventProperties()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual((-72).ToString(), moveBy["tiltX"]);
            Assert.AreEqual((9).ToString(), moveBy["tiltY"]);
            Assert.AreEqual((86).ToString(), moveBy["twist"]);
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        private Dictionary<string, string> getProperties(IWebElement element)
        {
            var str = element.Text;
            str = str[(str.Split()[0].Length + 1)..];
            IEnumerable<string[]> keyValue = str.Split(", ").Select(part => part.Split(":"));
            return keyValue.ToDictionary(split => split[0].Trim(), split => split[1].Trim());
        }

        private bool VerifyEquivalent(decimal expected, string actual)
        {
            var absolute = Math.Abs(expected - decimal.Parse(actual));
            if (absolute <= 1)
            {
                return true;
            }

            throw new Exception("Expected: " + expected + "; but received: " + actual);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/pen_spec.rb#L11-L17)

##### /examples/ruby/spec/actions\_api/pen\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Pen' do
  let(:driver) { start_session }

  it 'uses a pen' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  it 'sets pointer event attributes' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s,
                               'tiltX' => -72.to_s,
                               'tiltY' => 9.to_s,
                               'twist' => 86.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  def properties(element)
    element.text.sub(/.*?\s/, '').split(',').to_h { |item| item.lstrip.split(/\s*:\s*/) }
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/PenTest.kt#L23-L30)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/PenTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import kotlin.collections.Map
import java.time.Duration

class PenTest : BaseTest() {
  
    @Test
    fun usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
    }

    @Test
    fun setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY")) 
	    
        Assertions.assertEquals("-72", moveBy.get("tiltX"))
        Assertions.assertEquals("9", moveBy.get("tiltY"))
        Assertions.assertEquals("86", moveBy.get("twist"))
    }
    
    fun getPropertyInfo(element: WebElement): Map<String, String> {
        var text = element.getText()  
        text = text.substring(text.indexOf(" ")+1)
        return text.split(", ")
        .map { it.split(": ") }
        .map { it.first() to it.last() }
        .toMap() 
    }
}
```

```java
        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/PenTest.java#L67-L81)

##### /examples/java/src/test/java/dev/selenium/actions\_api/PenTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PenTest extends BaseChromeTest {
    @Test
    public void usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();

        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    @Test
    public void setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();
        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("-72", moveBy.get("tiltX"));
        Assertions.assertEquals("9", moveBy.get("tiltY"));
        Assertions.assertEquals("86", moveBy.get("twist"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    private Map<String, String> getPropertyInfo(WebElement element) {
        String text = element.getText();
        text = text.substring(text.indexOf(' ') + 1);

        return Arrays.stream(text.split(", "))
                .map(s -> s.split(": "))
                .collect(Collectors.toMap(
                        a -> a[0],
                        a -> a[1]
                ));
    }
}
```

```py
    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_pen.py#L53-L61)

##### /examples/python/tests/actions\_api/test\_pen.py

```py
import math

from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.interaction import POINTER_PEN
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.by import By


def test_use_pen(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def test_set_pointer_event_properties(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert move_by["tiltX"] == "-72"
    assert move_by["tiltY"] == "9"
    assert move_by["twist"] == "86"
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def properties(element):
    kv = element.text.split(' ', 1)[1].split(', ')
    return {x[0]:x[1] for x in list(map(lambda item: item.split(': '), kv))}
```

```cs
            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs#L64-L77)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class PenTest : BaseChromeTest
    {
        [TestMethod]
        public void UsePen()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        [TestMethod]
        public void SetPointerEventProperties()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual((-72).ToString(), moveBy["tiltX"]);
            Assert.AreEqual((9).ToString(), moveBy["tiltY"]);
            Assert.AreEqual((86).ToString(), moveBy["twist"]);
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        private Dictionary<string, string> getProperties(IWebElement element)
        {
            var str = element.Text;
            str = str[(str.Split()[0].Length + 1)..];
            IEnumerable<string[]> keyValue = str.Split(", ").Select(part => part.Split(":"));
            return keyValue.ToDictionary(split => split[0].Trim(), split => split[1].Trim());
        }

        private bool VerifyEquivalent(decimal expected, string actual)
        {
            var absolute = Math.Abs(expected - decimal.Parse(actual));
            if (absolute <= 1)
            {
                return true;
            }

            throw new Exception("Expected: " + expected + "; but received: " + actual);
        }
    }
}
```

```rb
    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/pen_spec.rb#L50-L56)

##### /examples/ruby/spec/actions\_api/pen\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Pen' do
  let(:driver) { start_session }

  it 'uses a pen' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  it 'sets pointer event attributes' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s,
                               'tiltX' => -72.to_s,
                               'tiltY' => 9.to_s,
                               'twist' => 86.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  def properties(element)
    element.text.sub(/.*?\s/, '').split(',').to_h { |item| item.lstrip.split(/\s*:\s*/) }
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/PenTest.kt#L64-L78)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/PenTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import kotlin.collections.Map
import java.time.Duration

class PenTest : BaseTest() {
  
    @Test
    fun usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
    }

    @Test
    fun setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY")) 
	    
        Assertions.assertEquals("-72", moveBy.get("tiltX"))
        Assertions.assertEquals("9", moveBy.get("tiltY"))
        Assertions.assertEquals("86", moveBy.get("twist"))
    }
    
    fun getPropertyInfo(element: WebElement): Map<String, String> {
        var text = element.getText()  
        text = text.substring(text.indexOf(" ")+1)
        return text.split(", ")
        .map { it.split(": ") }
        .map { it.first() to it.last() }
        .toMap() 
    }
}
```

----
url: https://www.selenium.dev/zh-cn/_print/documentation/overview/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/overview/).

# 概述

Selenium适合你吗? 请参见不同项目组件的概述.

* 1: [了解组件](#pg-bc711db3b396346aab3713246e79c629)
* 2: [深度介绍](#pg-3414129d0faf4a89833aacadc67e9d72)

# 1 - 了解组件

# 2 - 深度介绍

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/
----

# 驱动会话

```java
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L23)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L9)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            driver = new ChromeDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BaseTest.cs#L48)

##### /examples/dotnet/SeleniumDocs/BaseTest.cs

```cs
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs
{
    public class BaseTest
    {
        protected IWebDriver driver;
        protected Uri GridUrl;
        private Process _webserverProcess;
        private const string ServerJarName = "selenium-server-4.44.0.jar";
        private static readonly string BaseDirectory = AppContext.BaseDirectory;
        private const string RelativePathToGrid = "../../../../../";
        private readonly string _examplesDirectory = Path.GetFullPath(Path.Combine(BaseDirectory, RelativePathToGrid));

        [TestCleanup]
        public void Cleanup()
        {
            driver?.Quit();

            if (_webserverProcess != null)
            {
                StopServer();
            }
        }

        protected void StartDriver(string browserVersion = null)
        {
            ChromeOptions options = new ChromeOptions();
            if (browserVersion != null)
            {
                options.BrowserVersion = browserVersion;
                string userDataDir = System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetRandomFileName());
                System.IO.Directory.CreateDirectory(userDataDir);
                options.AddArgument($"--user-data-dir={userDataDir}");
                options.AddArgument("--no-sandbox");
                options.AddArgument("--disable-dev-shm-usage");
            }
            driver = new ChromeDriver(options);
        }

        protected async Task StartServer()
        {
            if (_webserverProcess == null || _webserverProcess.HasExited)
            {
                _webserverProcess = new Process();
                _webserverProcess.StartInfo.FileName =
                    RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "java.exe" : "java";
                string port = GetFreeTcpPort().ToString();
                GridUrl = new Uri("http://localhost:" + port + "/wd/hub");
                _webserverProcess.StartInfo.Arguments = " -jar " + ServerJarName +
                                                        " standalone --port " + port +
                                                        " --selenium-manager true --enable-managed-downloads true";
                _webserverProcess.StartInfo.WorkingDirectory = _examplesDirectory;
                _webserverProcess.Start();
                await EnsureGridIsRunningAsync();
            }
        }

        private void StopServer()
        {
            if (_webserverProcess != null && !_webserverProcess.HasExited)
            {
                _webserverProcess.Kill();
                _webserverProcess.Dispose();
                _webserverProcess = null;
            }
        }

        private static int GetFreeTcpPort()
        {
            TcpListener l = new TcpListener(IPAddress.Loopback, 0);
            l.Start();
            int port = ((IPEndPoint)l.LocalEndpoint).Port;
            l.Stop();
            return port;
        }

        private async Task EnsureGridIsRunningAsync()
        {
            DateTime timeout = DateTime.Now.Add(TimeSpan.FromSeconds(240));
            bool isRunning = false;
            HttpClient client = new HttpClient();

            while (!isRunning && DateTime.Now < timeout)
            {
                try
                {
                    HttpResponseMessage response = await client.GetAsync(GridUrl + "/status");
                    if (response.IsSuccessStatusCode)
                    {
                        isRunning = true;
                    }
                    else
                    {
                        await Task.Delay(1000);
                    }
                }
                catch (HttpRequestException)
                {
                    await Task.Delay(1000);
                }
            }

            if (!isRunning)
            {
                throw new TimeoutException("Could not confirm the remote selenium server is running within 30 seconds");
            }
        }
    }
}
```

```rb
      driver = Selenium::WebDriver.for :chrome, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L14)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options)
      .setChromeService(service)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/drivers/service.spec.js#L46-L50)

##### /examples/javascript/test/drivers/service.spec.js

```js
const fs = require('fs');
const os = require('os');
const path = require('path');
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const {getBinaryPaths} = require("selenium-webdriver/common/driverFinder");

describe('Service Test', function () {
  let driver;
  let userDataDir;
  let service;
  let options;

  afterEach(async function () {
    if (driver) {
      await driver.quit();
      driver = null;
    }
    if (userDataDir) {
      fs.rmSync(userDataDir, { recursive: true, force: true });
      userDataDir = null;
    }
  });

  it('Default service', async function () {
    service = new Chrome.ServiceBuilder();
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });

  it('Set Driver Location', async function () {
    options = new Chrome.Options();
    options.setBrowserVersion("stable");
    let paths = getBinaryPaths(options);
    let driverPath = paths.driverPath;
    let browserPath = paths.browserPath;
    options.setChromeBinaryPath(browserPath);
    userDataDir = fs.mkdtempSync(path.join(os.tmpdir(), 'chrome-profile-'));
    options.addArguments(`--user-data-dir=${userDataDir}`);
    options.addArguments('--no-sandbox');
    options.addArguments('--disable-dev-shm-usage');
    service = new Chrome.ServiceBuilder(driverPath);
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });

  it('Set port', async function () {
    service = new Chrome.ServiceBuilder().setPort(1234);
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
        driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L11)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L28)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L16)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L28)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L35)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

***

##### [浏览器选项](/zh-cn/documentation/webdriver/drivers/options/)

这些capabilities用于所有浏览器.

##### [HTTP Client Configuration](/zh-cn/documentation/webdriver/drivers/http_client/)

##### [驱动服务类](/zh-cn/documentation/webdriver/drivers/service/)

##### [远程WebDriver](/zh-cn/documentation/webdriver/drivers/remote_webdriver/)

最后修改 October 30, 2025: [Issue 2452- fixed line number for CSharp to show correct line for driver (#2489) (fe610b23e9b)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/fe610b23e9b91b7314fc8ae3c3d24deb73afee22)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/troubleshooting/errors/driver_location/
----

# Unable to Locate Driver Error

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.bash_profile
source ~/.bash_profile
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Terminal and execute:

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.zshenv
source ~/.zshenv
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Command Prompt and execute:

```shell
echo %PATH%
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
setx PATH "%PATH%;C:\WebDriver\bin"
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver.exe --version
```

| 浏览器               | 支持的操作系统                     | 维护者              | 下载                                                                    | 问题追溯                                                             |
| ----------------- | --------------------------- | ---------------- | --------------------------------------------------------------------- | ---------------------------------------------------------------- |
| Chromium/Chrome   | Windows/macOS/Linux         | Google           | [下载](//chromedriver.chromium.org/downloads)                           | [Issues](//bugs.chromium.org/p/chromedriver/issues/list)         |
| Firefox           | Windows/macOS/Linux         | Mozilla          | [下载](//github.com/mozilla/geckodriver/releases)                       | [Issues](//github.com/mozilla/geckodriver/issues)                |
| Edge              | Windows/macOS/Linux         | Microsoft        | [下载](//developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/) | [Issues](https://github.com/MicrosoftDocs/edge-developer/issues) |
| Internet Explorer | Windows                     | Selenium Project | [下载](/downloads)                                                      | [Issues](//github.com/SeleniumHQ/selenium/labels/D-IE)           |
| Safari            | macOS High Sierra and newer | Apple            | 内置                                                                    | [Issues](//bugreport.apple.com/logon)                            |

备注：Opera驱动不再适用于Selenium的最新功能，目前官方不支持。

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/drivers/remote_webdriver/
----

# WebDriver Remoto

```java
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L38-L39)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L13-L14)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L28-L29)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L20-L21)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L49-L52)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

Python adds a local file detector to remote webdriver instances by default, but you can also create your own class.

```py
    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#LL29-L32)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

.NET adds a local file detector to remote webdriver instances by default, but you can also create your own class.

```cs
            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L47-L50)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

Ruby adds a local file detector to remote webdriver instances by default, but you can also create your own lambda:

```rb
    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L33-L36)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## Downloads

Chrome, Edge and Firefox each allow you to set the location of the download directory. When you do this on a remote computer, though, the location is on the remote computer’s local file system. Selenium allows you to enable downloads to get these files onto the client computer.

### Enable Downloads in the Grid

Regardless of the client, when starting the grid in node or standalone mode, you must add the flag:

```
--enable-managed-downloads true
```

```java
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L60-L62)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L42-L44)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L59-L64)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L43-L44)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    List<String> files = ((HasDownloads) driver).getDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L73)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    files = driver.get_downloadable_files()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L52)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L72)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    files = driver.downloadable_files
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L52)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L83)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    driver.download_file(downloadable_file, target_directory)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L58)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L79)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    driver.download_file(downloadable_file, target_directory)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L57)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((HasDownloads) driver).deleteDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L88)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    driver.delete_downloadable_files()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L64)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ((RemoteWebDriver)driver).DeleteDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L84)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    driver.delete_downloadable_files
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L62)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    driver = new Augmenter().augment(driver);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L98)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

Of interest, using the `RemoteWebDriverBuilder` automatically augments the driver, so it is a great way to get all the functionality by default:

```java
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L106-L111)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

.NET uses a custom command executor for executing commands that are valid for the given browser in the remote driver.

```cs
            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L96-L100)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```xml
  <dependency>
      <groupId>io.opentelemetry</groupId>
      <artifactId>opentelemetry-exporter-jaeger</artifactId>
      <version>1.0.0</version>
    </dependency>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-netty</artifactId>
      <version>1.35.0</version>
    </dependency>
```

### Add/pass the required system properties while running the client

*

```java
System.setProperty("otel.traces.exporter", "jaeger");
System.setProperty("otel.exporter.jaeger.endpoint", "http://localhost:14250");
System.setProperty("otel.resource.attributes", "service.name=selenium-java-client");

ImmutableCapabilities capabilities = new ImmutableCapabilities("browserName", "chrome");

WebDriver driver = new RemoteWebDriver(new URL("http://www.example.com"), capabilities);

driver.get("http://www.google.com");

driver.quit();
```

Please refer to [Tracing Setup](https://github.com/SeleniumHQ/selenium/blob/selenium-4.0.0-beta-1/java/server/src/org/openqa/selenium/grid/commands/tracing.txt) for more information on external dependencies versions required for the desired Selenium version.

More information can be found at:

* OpenTelemetry: <https://opentelemetry.io>
* Configuring OpenTelemetry: <https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure>
* Jaeger: <https://www.jaegertracing.io>
* [Selenium Grid Observability](https://www.selenium.dev/pt-br/documentation/grid/advanced_features/observability/)

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/encouraged/locators/
----

# Tips on working with locators

Última modificação February 10, 2022: [#891 Update locators (#947) \[deploy site\] (f39d357da08)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/f39d357da08a64c9dc00e3be29c6c369729482bb)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/bidi/cdp/network/
----

# Chrome DevTools Network Features

```java
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L41-L43)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
        credentials = base64.b64encode("admin:admin".encode()).decode()
        auth = {'authorization': 'Basic ' + credentials}
        await connection.session.execute(connection.devtools.network.set_extra_http_headers(Headers(auth)))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L13-15)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L25-L32)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L9-L11)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      HttpResponse res = next.execute(req);
                      contentType.add(res.getHeader("Content-Type"));
                      return res;
                    })) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L56-L65)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L46-L51)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L20-L24)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    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!"))))) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L75-L85)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L62-L73)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L31-L35)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L97-L110)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L85-L97)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    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
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L42-L46)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L125-L126)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    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())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L26-L28)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L114-L118)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L56-L57)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    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()));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L142-L157)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L37-L44)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L136-L143)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L68-L71)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    devTools.send(
            Browser.setDownloadBehavior(
                    Browser.SetDownloadBehaviorBehavior.ALLOWANDNAME,
                    Optional.empty(),
                    Optional.of(""),
                    Optional.of(true)));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L171-L176)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    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
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L82-L88)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

----
url: https://www.selenium.dev/documentation/grid/
----

# Grid

Want to run tests in parallel across multiple machines? Then, Grid is for you.

Selenium Grid allows the execution of WebDriver scripts on remote machines by routing commands sent by the client to remote browser instances.

Grid aims to:

* Provide an easy way to run tests in parallel on multiple machines
* Allow testing on different browser versions
* Enable cross platform testing

Interested? Go through the following sections to understand how Grid works, and how to set up your own.

***

##### [Getting started with Selenium Grid](/documentation/grid/getting_started/)

Instructions for a simple Selenium Grid

##### [When to Use Grid](/documentation/grid/applicability/)

Is Grid right for you?

##### [Selenium Grid Components](/documentation/grid/components/)

Understand how to use the different Grid components

##### [Configuration of Components](/documentation/grid/configuration/)

Here you can see how each Grid component can be configured individually based on common configuration values and component-specific configuration values.

##### [Grid architecture](/documentation/grid/architecture/)

##### [Advanced features of Selenium](/documentation/grid/advanced_features/)

To get all the details of the advanced features, understand how it works, and how to set up your own, please browse thorough the following sections.

Last modified February 6, 2024: [Grid as 4 in the index (f414b1ef8f2)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/f414b1ef8f2f4d0412a75fe8ca059786be95b0c0)

----
url: https://www.selenium.dev/ja/documentation/about/style/
----

# Style guide for Selenium documentation

Conventions for contributions to the Selenium documentation and code examples

Read our [contributing documentation](https://www.selenium.dev/ja/documentation/about/contributing/) for complete instructions on how to add content to this documentation.

## Alerts

Alerts have been added to direct potential contributors to where specific content is missing.

```html
{{< alert-content />}}
```

or

```html
{{< alert-content >}}
Additional information about what specific content is needed
{{< /alert-content >}}
```

```java
WebDriver driver = new ChromeDriver();
```

```python
driver = webdriver.Chrome()
```

```csharp
var driver = new ChromeDriver();
```

```ruby
driver = Selenium::WebDriver.for :chrome
```

```javascript
let driver = await new Builder().forBrowser('chrome').build();
```

```kotlin
val driver = ChromeDriver()
```

To generate the above tabs, this is what you need to write. Note that the `tabpane` includes `langEqualsHeader=true`. This auto-formats the code in each tab to match the header name, and ensures that all tabs on the page with a language are set to the same thing.

```
{{< tabpane langEqualsHeader=true >}}
  {{< tab header="Java" >}}
    WebDriver driver = new ChromeDriver();
  {{< /tab >}}
  {{< tab header="Python" >}}
    driver = webdriver.Chrome()
  {{< /tab >}}
  {{< tab header="CSharp" >}}
    var driver = new ChromeDriver();
  {{< /tab >}}
  {{< tab header="Ruby" >}}
    driver = Selenium::WebDriver.for :chrome
  {{< /tab >}}
  {{< tab header="JavaScript" >}}
    let driver = await new Builder().forBrowser('chrome').build();
  {{< /tab >}}
  {{< tab header="Kotlin" >}}
    val driver = ChromeDriver()
  {{< /tab >}}
{{< /tabpane >}}
```

#### Reference GitHub Examples

To ensure that all code is kept up to date, our goal is to write the code in the repo where it can be executed when Selenium versions are updated to ensure that everything is correct.

All code examples to be in our [example directories](https://github.com/SeleniumHQ/seleniumhq.github.io/tree/dev/examples).

This code can be automatically displayed in the documentation using the `gh-codeblock` shortcode. The shortcode automatically generates its own html, so we do not want it to auto-format with the language header. If all tabs are using this shortcode, set `text=true` in the `tabpane` and remove `langEqualsHeader=true`. If only some tabs are using this shortcode, keep `langEqualsHeader=true` in the `tabpane` and add `text=true` to the `tab`. Note that the `gh-codeblock` line can not be indented at all.

One great thing about using `gh-codeblock` is that it adds a link to the full example. This means you don’t have to include any additional context code, just the line(s) that are needed, and the user can navigate to the repo to see how to use it.

A basic comparison of code looks like:

```
{{< tabpane text=true >}}
{{< tab header="Java" >}}
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-L27" >}}
{{< /tab >}}
{{< tab header="Python" >}}
{{< gh-codeblock path="/examples/python/tests/getting_started/first_script.py#L18-L19" >}}
{{< /tab >}}
{{< tab header="CSharp" >}}
{{< gh-codeblock path="/examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-L26" >}}
{{< /tab >}}
{{< tab header="Ruby" >}}
{{< gh-codeblock path="/examples/ruby/spec/getting_started/first_script.rb#L17-L18" >}}
{{< /tab >}}
{{< tab header="JavaScript" >}}
{{< gh-codeblock path="/examples/javascript/test/getting_started/firstScript.spec.js#L22-L23" >}}
{{< /tab >}}
{{< tab header="Kotlin" >}}
{{< gh-codeblock path="/examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-L32" >}}
{{< /tab >}}
{{< /tabpane >}}
```

```java
        WebElement message = driver.findElement(By.id("message"));
        message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-L27)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
message = driver.find_element(by=By.ID, value="message")
text = message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L18-L19)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-L26)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
message = driver.find_element(id: 'message')
message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L17-L18)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L22-L23)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val message = driver.findElement(By.id("message"))
        val value = message.getText()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-L32)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

### Using Markdown in a Tab

If you want your example to include something other than code (default) or html (from `gh-codeblock`), you need to first set `text=true`, then change the Hugo syntax for the `tab`to use `%` instead of `<` and `>` with curly braces:

```
{{< tabpane text=true >}}
{{% tab header="Java" %}}
1. Start the driver
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12" >}}
2. Navigate to a page
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14" >}}
3. Quit the driver
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29" >}}
{{% /tab %}}
< ... >
{{< /tabpane >}}
```

This produces:

*

1. Start the driver

   ```java
           WebDriver driver = new ChromeDriver();
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

2. Navigate to a page

   ```java
           driver.get("https://www.selenium.dev/selenium/web/web-form.html");
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

3. Quit the driver

   ```java
           driver.quit();
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

This is preferred to writing code comments because those will not be translated. Only include the code that is needed for the documentation, and avoid over-explaining. Finally, remember not to indent plain text or it will rendered as a codeblock.

----
url: https://www.selenium.dev/_print/documentation/grid/advanced_features/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/grid/advanced_features/).

# Advanced features of Selenium

To get all the details of the advanced features, understand how it works, and how to set up your own, please browse thorough the following sections.

* 1: [Observability in Selenium Grid](#pg-31c8fbb2badbe02b79aa5e8066e4dbb4)
* 2: [GraphQL query support](#pg-76186a5d24597c9acf1bcb112d5b8cb6)
* 3: [Grid endpoints](#pg-69471da8f601bc6b170f1ec47d69f853)
* 4: [Customizing a Node](#pg-abdf1d3e182274141e4d8a3e7686dcf8)
* 5: [External datastore](#pg-fe0209b2f377f5b9f5e592aade250b62)

# 1 - Observability in Selenium Grid

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar standalone --log-level FINE
```

2. Jaeger UI - OpenTelemetry provides the APIs and SDKs to instrument traces in the code. Whereas Jaeger is a tracing backend, that aids in collecting the tracing telemetry data and providing querying, filtering and visualizing features for the data.

Detailed instructions of visualizing traces using Jaeger UI can be obtained by running the command :

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar info tracing
```

[A very good example and scripts to run the server and send traces to Jaeger](https://github.com/manoj9788/tracing-selenium-grid)

## Leveraging event logs

Tracing has to be enabled for event logging as well, even if one does not wish to export traces to visualize them.\
**By default, tracing is enabled. No additional parameters need to be passed to see logs on the console.** All events within a span are logged at FINE level. Error events are logged at WARN level.

All event logs have the following fields :

| Field            | Field value     | Description                                                                                                                                                                            |
| ---------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Event time       | eventId         | Timestamp of the event record in epoch nanoseconds.                                                                                                                                    |
| Trace Id         | tracedId        | Each trace is uniquely identified by a trace id.                                                                                                                                       |
| Span Id          | spanId          | Each span within a trace is uniquely identified by a span id.                                                                                                                          |
| Span Kind        | spanKind        | Span kind is a property of span indicating the type of span. It helps in understanding the nature of the unit of work done by the Span.                                                |
| Event name       | eventName       | This maps to the log message.                                                                                                                                                          |
| Event attributes | eventAttributes | This forms the crux of the event logs, based on the operation executed, it has JSON formatted key-value pairs. This also includes a handler class attribute, to show the logger class. |

Sample log

```
FINE [LoggingOptions$1.lambda$export$1] - {
  "traceId": "fc8aef1d44b3cc8bc09eb8e581c4a8eb",
  "spanId": "b7d3b9865d3ddd45",
  "spanKind": "INTERNAL",
  "eventTime": 1597819675128886121,
  "eventName": "Session request execution complete",
  "attributes": {
    "http.status_code": 200,
    "http.handler_class": "org.openqa.selenium.grid.router.HandleSession",
    "http.url": "\u002fsession\u002fdd35257f104bb43fdfb06242953f4c85",
    "http.method": "DELETE",
    "session.id": "dd35257f104bb43fdfb06242953f4c85"
  }
}
```

In addition to the above fields, based on [OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/exceptions.md) error logs consist of :

| Field                | Field value          | Description                                                                                                                   |
| -------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Exception type       | exception.type       | The class name of the exception.                                                                                              |
| Exception message    | exception.message    | Reason for the exception.                                                                                                     |
| Exception stacktrace | exception.stacktrace | Prints the call stack at the point of time when the exception was thrown. Helps in understanding the origin of the exception. |

Sample error log

```
WARN [LoggingOptions$1.lambda$export$1] - {
  "traceId": "7efa5ea57e02f89cdf8de586fe09f564",
  "spanId": "914df6bc9a1f6e2b",
  "spanKind": "INTERNAL",
  "eventTime": 1597820253450580272,
  "eventName": "exception",
  "attributes": {
    "exception.type": "org.openqa.selenium.ScriptTimeoutException",
    "exception.message": "Unable to execute request: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist ..." (full message will be printed),
    "exception.stacktrace": "org.openqa.selenium.ScriptTimeoutException: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist\nBuild info: version: '4.0.0-alpha-7', revision: 'Unknown'\nSystem info: host: 'XYZ-MacBook-Pro.local', ip: 'fe80:0:0:0:10d5:b63a:bdc6:1aff%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.7'\nDriver info: driver.version: unknown ...." (full stack will be printed),
    "http.handler_class": "org.openqa.selenium.grid.distributor.remote.RemoteDistributor",
    "http.url": "\u002fsession",
    "http.method": "POST"
  }
}
```

# 2 - GraphQL query support

```shell
{
    session(id: "<session-id>") : {
        id,
        capabilities,
        startTime,
        uri,
        nodeId,
        nodeUri,
        sessionDurationMillis
        slot : {
            id,
            stereotype,
            lastStarted
        }
    }
    grid: {
        uri,
        totalSlots,
        nodeCount,
        maxSession,
        sessionCount,
        version,
        sessionQueueSize
    }
    sessionsInfo: {
        sessionQueueRequests,
        sessions: [
            {
                id,
                capabilities,
                startTime,
                uri,
                nodeId,
                nodeUri,
                sessionDurationMillis
                slot : {
                    id,
                    stereotype,
                    lastStarted
                }
            }
        ]
    }
    nodesInfo: {
        nodes : [
            {
                id,
                uri,
                status,
                maxSession,
                slotCount,
                sessions: [
                    {
                        id,
                        capabilities,
                        startTime,
                        uri,
                        nodeId,
                        nodeUri,
                        sessionDurationMillis
                        slot : {
                            id,
                            stereotype,
                            lastStarted
                        }
                    }
                ],
                sessionCount,
                stereotypes,
                version,
                osInfo: {
                    arch,
                    name,
                    version
                }
            }
        ]
    }
}
```

## Querying GraphQL

The best way to query GraphQL is by using `curl` requests. The query is interpreted as JSON. Ensure double quotes are properly escaped to avoid unexpected errors. GraphQL allows you to fetch only the data that you want, nothing more nothing less.

Some of the example GraphQL queries are given below. You can build your own queries as you like.

### Querying the number of `maxSession` and `sessionCount` in the grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ grid { maxSession, sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

Generally on local machine the `<LINK_TO_GRAPHQL_ENDPOINT>` would be `http://localhost:4444/graphql`

### Querying all details for session, node and the Grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { uri, maxSession, sessionCount }, nodesInfo { nodes { id, uri, status, sessions { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } }, slotCount, sessionCount }} }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the current session count in the Grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the max session count in the Grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { maxSession } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting all session details for all nodes in the Grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, capabilities, startTime, uri, nodeId, nodeId, sessionDurationMillis } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query to get slot information for all sessions in each Node in the Grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, slot { id, stereotype, lastStarted } } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query to get session information for a given session:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ session (id: \"<session-id>\") { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } } } "}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Querying the capabilities of each node in the grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { stereotypes } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Querying the status of each node in the grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { status } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Querying the URI of each node and the grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { uri } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the current requests in the New Session Queue:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessionQueueRequests } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the New Session Queue size :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionQueueSize } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

# 3 - Grid endpoints

## Grid

### Grid Status

Grid status provides the current state of the Grid. It consists of details about every registered Node. For every Node, the status includes information regarding Node availability, sessions, and slots.

```shell
curl --request GET 'http://localhost:4444/status'
```

### Delete session

Deleting the session terminates the WebDriver session, quits the driver and removes it from the active sessions map. Any request using the removed session-id or reusing the driver instance will throw an error.

```shell
curl --request DELETE 'http://localhost:4444/session/<session-id>'
```

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret> '
```

In the fully distributed mode, the URL is the Router server address.

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET;'
```

### Drain Node

Node drain command is for graceful node shutdown. Draining a Node stops the Node after all the ongoing sessions are complete. However, it does not accept any new session requests.

In the Standalone mode, the Distributor URL is the Standalone server address.

In the Hub-Node mode, the Distributor URL is the Hub server address.

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret> '
```

In the fully distributed mode, the URL is the Router server address.

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request POST 'http://<Router-URL>/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET;'
```

## Node

The endpoints in this section are applicable for Hub-Node mode and fully distributed Grid mode where the Node runs independently. The default Node URL is http\://localhost:5555 in case of one Node. In case of multiple Nodes, use [Grid status](/documentation/grid/advanced_features/endpoints/#grid-status) to get all Node details and locate the Node address.

### Status

The Node status is essentially a health-check for the Node. Distributor pings the node status at regular intervals and updates the Grid Model accordingly. The status includes information regarding availability, sessions, and slots.

```shell
curl --request GET 'http://localhost:5555/status'
```

### Drain

Distributor passes the [drain](/documentation/grid/advanced_features/endpoints/#drain-node) command to the appropriate node identified by the node-id. To drain the Node directly, use the curl command enlisted below. Both endpoints are valid and produce the same result. Drain finishes the ongoing sessions before stopping the Node.

```shell
curl --request POST 'http://localhost:5555/se/grid/node/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request POST 'http://<node-URL>/se/grid/node/drain' --header 'X-REGISTRATION-SECRET;'
```

### Check session owner

To check if a session belongs to a Node, use the curl command enlisted below.

```shell
curl --request GET 'http://localhost:5555/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request GET 'http://<node-URL>/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

It will return true if the session belongs to the Node else it will return false.

### Delete session

Deleting the session terminates the WebDriver session, quits the driver and removes it from the active sessions map. Any request using the removed session-id or reusing the driver instance will throw an error.

```shell
curl --request DELETE 'http://localhost:5555/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request DELETE 'http://<node-URL>/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

## New Session Queue

### Clear New Session Queue

New Session Request Queue holds the new session requests. To clear the queue, use the curl command enlisted below. Clearing the queue rejects all the requests in the queue. For each such request, the server returns an error response to the respective client. The result of the clear command is the total number of deleted requests.

In the Standalone mode, the Queue URL is the Standalone server address.

In the Hub-Node mode, the Queue URL is the Hub server address.

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

In the fully distributed mode, the Queue URL is Router server address.

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET;'
```

### Get New Session Queue Requests

New Session Request Queue holds the new session requests. To get the current requests in the queue, use the curl command enlisted below. The response returns the total number of requests in the queue and the request payloads.

In the Standalone mode, the Queue URL is the Standalone server address.

In the Hub-Node mode, the Queue URL is the Hub server address.

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

In the fully distributed mode, the Queue URL is Router server address.

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

# 4 - Customizing a Node

```bash
java -jar custom_node-server.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

```bash
java -jar selenium-server-4.6.0.jar \
--ext custom_node-1.0-SNAPSHOT.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

Below is a sample that just prints some messages on to the console whenever there’s an activity of interest (session created, session deleted, a webdriver command executed etc.,) on the Node.

Sample customized node

```java
package org.seleniumhq.samples;

import java.io.IOException;
import java.net.URI;
import java.util.UUID;
import java.util.function.Supplier;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.NoSuchSessionException;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.grid.config.Config;
import org.openqa.selenium.grid.data.CreateSessionRequest;
import org.openqa.selenium.grid.data.CreateSessionResponse;
import org.openqa.selenium.grid.data.NodeId;
import org.openqa.selenium.grid.data.NodeStatus;
import org.openqa.selenium.grid.data.Session;
import org.openqa.selenium.grid.log.LoggingOptions;
import org.openqa.selenium.grid.node.HealthCheck;
import org.openqa.selenium.grid.node.Node;
import org.openqa.selenium.grid.node.local.LocalNodeFactory;
import org.openqa.selenium.grid.security.Secret;
import org.openqa.selenium.grid.security.SecretOptions;
import org.openqa.selenium.grid.server.BaseServerOptions;
import org.openqa.selenium.internal.Either;
import org.openqa.selenium.io.TemporaryFilesystem;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
import org.openqa.selenium.remote.tracing.Tracer;

public class DecoratedLoggingNode extends Node {

  private Node node;

  protected DecoratedLoggingNode(Tracer tracer, NodeId nodeId, URI uri, Secret registrationSecret, Duration sessionTimeout) {
    super(tracer, nodeId, uri, registrationSecret, sessionTimeout);
  }

  public static Node create(Config config) {
    LoggingOptions loggingOptions = new LoggingOptions(config);
    BaseServerOptions serverOptions = new BaseServerOptions(config);
    URI uri = serverOptions.getExternalUri();
    SecretOptions secretOptions = new SecretOptions(config);
    NodeOptions nodeOptions = new NodeOptions(config);
    Duration sessionTimeout = nodeOptions.getSessionTimeout();

    // Refer to the foot notes for additional context on this line.
    Node node = LocalNodeFactory.create(config);

    DecoratedLoggingNode wrapper = new DecoratedLoggingNode(loggingOptions.getTracer(),
        node.getId(),
        uri,
        secretOptions.getRegistrationSecret(),
        sessionTimeout);
    wrapper.node = node;
    return wrapper;
  }

  @Override
  public Either<WebDriverException, CreateSessionResponse> newSession(
      CreateSessionRequest sessionRequest) {
    return perform(() -> node.newSession(sessionRequest), "newSession");
  }

  @Override
  public HttpResponse executeWebDriverCommand(HttpRequest req) {
    return perform(() -> node.executeWebDriverCommand(req), "executeWebDriverCommand");
  }

  @Override
  public Session getSession(SessionId id) throws NoSuchSessionException {
    return perform(() -> node.getSession(id), "getSession");
  }

  @Override
  public HttpResponse uploadFile(HttpRequest req, SessionId id) {
    return perform(() -> node.uploadFile(req, id), "uploadFile");
  }

  @Override
  public HttpResponse downloadFile(HttpRequest req, SessionId id) {
    return perform(() -> node.downloadFile(req, id), "downloadFile");
  }

  @Override
  public TemporaryFilesystem getDownloadsFilesystem(UUID uuid) {
    return perform(() -> {
      try {
        return node.getDownloadsFilesystem(uuid);
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
    }, "downloadsFilesystem");
  }

  @Override
  public TemporaryFilesystem getUploadsFilesystem(SessionId id) throws IOException {
    return perform(() -> {
      try {
        return node.getUploadsFilesystem(id);
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
    }, "uploadsFilesystem");

  }

  @Override
  public void stop(SessionId id) throws NoSuchSessionException {
    perform(() -> node.stop(id), "stop");
  }

  @Override
  public boolean isSessionOwner(SessionId id) {
    return perform(() -> node.isSessionOwner(id), "isSessionOwner");
  }

  @Override
  public boolean isSupporting(Capabilities capabilities) {
    return perform(() -> node.isSupporting(capabilities), "isSupporting");
  }

  @Override
  public NodeStatus getStatus() {
    return perform(() -> node.getStatus(), "getStatus");
  }

  @Override
  public HealthCheck getHealthCheck() {
    return perform(() -> node.getHealthCheck(), "getHealthCheck");
  }

  @Override
  public void drain() {
    perform(() -> node.drain(), "drain");
  }

  @Override
  public boolean isReady() {
    return perform(() -> node.isReady(), "isReady");
  }

  private void perform(Runnable function, String operation) {
    try {
      System.err.printf("[COMMENTATOR] Before %s()%n", operation);
      function.run();
    } finally {
      System.err.printf("[COMMENTATOR] After %s()%n", operation);
    }
  }

  private <T> T perform(Supplier<T> function, String operation) {
    try {
      System.err.printf("[COMMENTATOR] Before %s()%n", operation);
      return function.get();
    } finally {
      System.err.printf("[COMMENTATOR] After %s()%n", operation);
    }
  }
}
```

***Foot Notes:***

In the above example, the line `Node node = LocalNodeFactory.create(config);` explicitly creates a `LocalNode`.

There are basically 2 types of *user facing implementations* of `org.openqa.selenium.grid.node.Node` available.

These classes are good starting points to learn how to build a custom Node and also to learn the internals of a Node.

* `org.openqa.selenium.grid.node.local.LocalNode` - Used to represent a long running Node and is the default implementation that gets wired in when you start a `node`.

  * It can be created by calling `LocalNodeFactory.create(config);`, where:

    * `LocalNodeFactory` belongs to `org.openqa.selenium.grid.node.local`
    * `Config` belongs to `org.openqa.selenium.grid.config`

* `org.openqa.selenium.grid.node.k8s.OneShotNode` - This is a special reference implementation wherein the Node gracefully shuts itself down after servicing one test session. This class is currently not available as part of any pre-built maven artifact.

  * You can refer to the source code [here](https://github.com/SeleniumHQ/selenium/blob/trunk/java/src/org/openqa/selenium/grid/node/k8s/OneShotNode.java) to understand its internals.

  * To build it locally refer [here](https://github.com/SeleniumHQ/selenium/blob/trunk/deploys/k8s/README.md).

  * It can be created by calling `OneShotNode.create(config)`, where:

    * `OneShotNode` belongs to `org.openqa.selenium.grid.node.k8s`
    * `Config` belongs to `org.openqa.selenium.grid.config`

# 5 - External datastore

```sql
CREATE TABLE IF NOT EXISTS sessions_map(
    session_ids varchar(256),
    session_caps text,
    session_uri varchar(256),
    session_stereotype text,
    session_start varchar(256)
 );
```

* In the same directory as the `init.sql`, create a file named `docker-compose.yml` with its contents as below:

```yaml
version: '3.8'
services:
  db:
    image: postgres:9.6-bullseye
    restart: always
    environment:
      - POSTGRES_USER=seluser
      - POSTGRES_PASSWORD=seluser
      - POSTGRES_DB=selenium_sessions
    ports:
      - "5432:5432"
    volumes:
    - ./init.sql:/docker-entrypoint-initdb.d/init.sql
```

We can now start our database container by running:

```bash
docker-compose up -d
```

*Our database name is `selenium_sessions` with its username and password set to `seluser`*

If you are working with an already running PostGreSQL DB instance, then you just need to create a database named `selenium_sessions` and the table `sessions_map` using the above mentioned SQL statement.

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
implementation = "org.openqa.selenium.grid.sessionmap.jdbc.JdbcBackedSessionMap"
jdbc-url = "jdbc:postgresql://localhost:5432/selenium_sessions"
jdbc-user = "seluser"
jdbc-password = "seluser"
```

*Note:* If you plan to use an existing PostGreSQL DB instance, then replace `localhost:5432` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed Grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Sessions Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

```yaml
version: '3.8'
services:
  redis:
    image: redis:bullseye
    restart: always
    ports:
      - "6379:6379"
```

We can now start our Redis container by running:

```bash
docker-compose up -d
```

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
scheme = "redis"
implementation = "org.openqa.selenium.grid.sessionmap.redis.RedisBackedSessionMap"
hostname = "localhost"
port = 6379
```

*Note:* If you plan to use an existing Redis Cache instance, then replace `localhost` and `6379` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Session Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

* At this point the current directory should contain the following files:

  * `docker-compose.yml`
  * `sessions.toml`
  * `distributed.sh`

* You can now spawn the Grid by running `distributed.sh` shell script and quickly run a test. You will notice that the Grid now stores session information into the Redis instance. You can perhaps make use of a Redis GUI such as [TablePlus](https://tableplus.com/) to see them (Make sure that you have setup a debug point in your test, because the values will get deleted as soon as the test runs to completion).

In the line which spawns a `SessionMap` on a machine:

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/encouraged/generating_application_state/
----

# Gerando estado da aplicação

Selenium não deve ser usado para preparar um caso de teste. Tudo as ações repetitivas e preparações para um caso de teste devem ser feitas por meio de outros métodos. Por exemplo, a maioria das IUs da web tem autenticação (por exemplo, um formulário de login). Eliminar o login via navegador da web antes de cada teste irá melhorar a velocidade e estabilidade do teste. Um método deve ser criado para obter acesso à AUT\* (por exemplo, usando uma API para fazer login e definir um cookie). Além disso, a criação de métodos para pré-carregar dados para o teste não deve ser feito usando Selenium. Como dito anteriormente, APIs existentes devem ser aproveitadas para criar dados para a AUT \*.

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/discouraged/performance_testing/
----

# Teste de performance/desempenho

Teste de desempenho usando Selenium e WebDriver geralmente não é recomendado. Não porque é incapaz, mas porque não é otimizado para o trabalho e é improvável que você obtenha bons resultados.

Pode parecer ideal para teste de desempenho no contexto do usuário, mas um conjunto de testes WebDriver estão sujeitos a muitos pontos de fragilidade externa e interna que estão além do seu controle; por exemplo, velocidade de inicialização do navegador, velocidade dos servidores HTTP, resposta de servidores de terceiros que hospedam JavaScript ou CSS, e a penalidade de instrumentação da própria implementação do WebDriver. A variação nesses pontos causará variação em seus resultados. É difícil separar a diferença entre o desempenho do seu site e o desempenho de recursos externos, e também é difícil dizer qual é a penalidade de desempenho para usar WebDriver no navegador, especialmente se você estiver injetando scripts.

A outra atração potencial é “economizar tempo” - execução de testes funcionais e de desempenho ao mesmo tempo. No entanto, os testes funcionais e de desempenho têm objetivos opostos. Para testar a funcionalidade, um testador pode precisar ser paciente e aguarde o carregamento, mas isso irá turvar os resultados do teste de desempenho e vice-versa.

Para melhorar o desempenho do seu site, você precisará ser capaz de analisar o desempenho geral independente das diferenças de ambiente, identificar práticas de código ruins, repartição do desempenho de recursos individuais (ou seja, CSS ou JavaScript), para saber o que melhorar. Existem ferramentas de teste de desempenho disponíveis que podem fazer este trabalho, que fornecem relatórios e análises, e podem até fazer sugestões de melhorias.

Pacotes de exemplo (código aberto) a serem usados ​​são: [JMeter](/pt-br/)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/actions_api/mouse/
----

# 鼠标操作

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L22-L25)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L14-L17)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L11-L14)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    let clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.move({origin: clickable}).press().perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/clickAndHold.spec.js#L14-L16)

##### /examples/javascript/test/actionsApi/mouse/clickAndHold.spec.js

```js
const {By, Builder} = require('selenium-webdriver');

describe('Click and hold', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and mouseDown on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    let clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.move({origin: clickable}).press().perform();
  });
});
```

```kt
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L23-L26)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L34-L37)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L26-L29)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L30-L33)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L22-L25)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    let click = driver.findElement(By.id("click"));
    const actions = driver.actions({async: true});
    await actions.move({origin: click}).click().perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/clickAndRelease.spec.js#L14-L16)

##### /examples/javascript/test/actionsApi/mouse/clickAndRelease.spec.js

```js
const {By,Builder} = require('selenium-webdriver');

describe('Click and release', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    let click = driver.findElement(By.id("click"));
    const actions = driver.actions({async: true});
    await actions.move({origin: click}).click().perform();
  });
});
```

```kt
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L35-L38)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L46-L49)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L37-L40)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L43-L46)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L34-L37)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.contextClick(clickable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/rightClick.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/rightClick.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Right click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and right click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.contextClick(clickable).perform();

    await driver.sleep(500);
    const clicked = await driver.findElement(By.id('click-status')).getText();
    assert.deepStrictEqual(clicked, `context-clicked`)
  });
});
```

```kt
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L47-L50)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L60-L66)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L51-L54)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L59-L63)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L47-L50)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js#L19-L20)

##### /examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js

```js
const {By, Button, Browser, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Should be able to perform BACK click and FORWARD click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Back click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)

    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)
  });

  it('Forward click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();
    await driver.navigate().back();

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)

    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L61-L67)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L78-L84)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L65-L68)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L77-L81)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L61-L64)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js#L32-L33)

##### /examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js

```js
const {By, Button, Browser, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Should be able to perform BACK click and FORWARD click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Back click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)

    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)
  });

  it('Forward click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();
    await driver.navigate().back();

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)

    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L79-L85)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L93-L96)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L76-L79)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L91-L94)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L73-L76)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.doubleClick(clickable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/doubleClick.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/doubleClick.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Double click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Double-click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.doubleClick(clickable).perform();

    await driver.sleep(500);
    const status = await driver.findElement(By.id('click-status')).getText();
    assert.deepStrictEqual(status, `double-clicked`)
  });
});
```

```kt
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L94-L97)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L105-L108)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L87-L90)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L104-L107)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L84-L87)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const hoverable = driver.findElement(By.id("hover"));
    const actions = driver.actions({async: true});
    await actions.move({origin: hoverable}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveToElement.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/moveToElement.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Move to element', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move into an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const hoverable = driver.findElement(By.id("hover"));
    const actions = driver.actions({async: true});
    await actions.move({origin: hoverable}).perform();

    const status = await driver.findElement(By.id('move-status')).getText();
    assert.deepStrictEqual(status, `hovered`)
  });
});
```

```kt
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L106-L109)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L118-L121)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L98-L101)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L132-L135)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L97-L100)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L119-L122)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L131-L136)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L110-L112)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L146-L150)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      driver.action
            .move_to_location(8, 12)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L114-L116)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L27-L28)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L132-L137)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L153-L155)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L126-L128)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L167-L169)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      driver.action
            .move_by(13, 15)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L128-L130)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L40)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L154-L156)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L166-L170)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L139-L143)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L181-L185)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L141-L145)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js#L27-L30)

##### /examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Drag and Drop', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('By Offset', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });

  it('Onto Element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });
});
```

```kt
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L167-L171)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L179-L184)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L151-L156)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L195-L200)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L153-L158)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js#L15-L19)

##### /examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Drag and Drop', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('By Offset', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });

  it('Onto Element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });
});
```

```kt
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L180-L185)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

----
url: https://www.selenium.dev/pt-br/_print/documentation/test_practices/encouraged/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/test_practices/encouraged/).

# Diretrizes e recomendações

Guias e recomendações ao preparar soluções de testes com o projecto Selenium.

* 1: [Modelos de objetos de página](#pg-fa4eae362230005dc133eaccc8f3c3e8)
* 2: [Linguagem específica de domínio (DSL)](#pg-4343e59eb52d202f26ceb385a8b56fa6)
* 3: [Gerando estado da aplicação](#pg-edd30564b73abba307b40f4351d2b249)
* 4: [Simulação de serviços externos](#pg-58945a8c3e84861fda4825f09e9cd2e0)
* 5: [Relatórios melhorados](#pg-c6cc073467223ae721b34c947936cbf9)
* 6: [Evite compartilhamento de estado](#pg-f155e13b0c999e5f3c5f56fef53fc47b)
* 7: [Tips on working with locators](#pg-51a63c6ce7dd64b1ecddf236663ecb74)
* 8: [Independência de Testes](#pg-a43c32fda8a8fa76d1487e152b4c1998)
* 9: [Considere usar uma API fluente](#pg-1ae8894e692552d092b8b8a00eee7702)
* 10: [Navegador novo por teste](#pg-eae471af628f9dd496b080eac9d94ac8)

Uma nota sobre “Melhores práticas”: evitamos intencionalmente a frase “Melhores Práticas” nesta documentação. Nenhuma abordagem funciona para todas as situações. Preferimos a ideia de “Diretrizes e Recomendações”. Nós encorajamos que você leia e decida cuidadosamente quais abordagens funcionarão para você em seu ambiente específico.

O teste funcional é difícil de acertar por muitos motivos. Como se o estado, a complexidade e as dependências do aplicativo não tornassem o teste suficientemente difícil, lidar com navegadores (especialmente com incompatibilidades entre navegadores) torna a escrita de bons testes um desafio.

Selenium fornece ferramentas para facilitar a interação funcional do usuário, mas não o ajuda a escrever suítes de teste bem arquitetadas. Neste capítulo, oferecemos conselhos, diretrizes e recomendações sobre como abordar a automação funcional de páginas da web.

Este capítulo registra os padrões de design de software populares entre muitos dos usuários do Selenium que tiveram sucesso ao longo dos anos.

# 1 - Modelos de objetos de página

```java
/***
 * Tests login feature
 */
public class Login {

  public void testLogin() {
    // fill login data on sign-in page
    driver.findElement(By.name("user_name")).sendKeys("userName");
    driver.findElement(By.name("password")).sendKeys("my supersecret password");
    driver.findElement(By.name("sign-in")).click();

    // verify h1 tag is "Hello userName" after login
    driver.findElement(By.tagName("h1")).isDisplayed();
    assertThat(driver.findElement(By.tagName("h1")).getText(), is("Hello userName"));
  }
}
```

There are two problems with this approach.

* There is no separation between the test method and the AUT’s locators (IDs in this example); both are intertwined in a single method. If the AUT’s UI changes its identifiers, layout, or how a login is input and processed, the test itself must change.
* The ID-locators would be spread in multiple tests, in all tests that had to use this login page.

Applying the page object model, this example could be rewritten like this in the following example of a page object for a Sign-in page.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Sign-in page.
 */
public class SignInPage {
  protected WebDriver driver;

  // <input name="user_name" type="text" value="">
  private By usernameBy = By.name("user_name");
  // <input name="password" type="password" value="">
  private By passwordBy = By.name("password");
  // <input name="sign_in" type="submit" value="SignIn">
  private By signinBy = By.name("sign_in");

  public SignInPage(WebDriver driver){
    this.driver = driver;
     if (!driver.getTitle().equals("Sign In Page")) {
      throw new IllegalStateException("This is not Sign In Page," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Login as valid user
    *
    * @param userName
    * @param password
    * @return HomePage object
    */
  public HomePage loginValidUser(String userName, String password) {
    driver.findElement(usernameBy).sendKeys(userName);
    driver.findElement(passwordBy).sendKeys(password);
    driver.findElement(signinBy).click();
    return new HomePage(driver);
  }
}
```

and page object for a Home page could look like this.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Home Page
 */
public class HomePage {
  protected WebDriver driver;

  // <h1>Hello userName</h1>
  private By messageBy = By.tagName("h1");

  public HomePage(WebDriver driver){
    this.driver = driver;
    if (!driver.getTitle().equals("Home Page of logged in user")) {
      throw new IllegalStateException("This is not Home Page of logged in user," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Get message (h1 tag)
    *
    * @return String message text
    */
  public String getMessageText() {
    return driver.findElement(messageBy).getText();
  }

  public HomePage manageProfile() {
    // Page encapsulation to manage profile functionality
    return new HomePage(driver);
  }
  /* More methods offering the services represented by Home Page
  of Logged User. These methods in turn might return more Page Objects
  for example click on Compose mail button could return ComposeMail class object */
}
```

So now, the login test would use these two page objects as follows.

```java
/***
 * Tests login feature
 */
public class TestLogin {

  @Test
  public void testLogin() {
    SignInPage signInPage = new SignInPage(driver);
    HomePage homePage = signInPage.loginValidUser("userName", "password");
    assertThat(homePage.getMessageText(), is("Hello userName"));
  }

}
```

```html
<!-- Products Page -->
<div class="header_container">
    <span class="title">Products</span>
</div>

<div class="inventory_list">
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
</div>
```

Each product is a component of the Products page.

```html
<!-- Inventory Item -->
<div class="inventory_item">
    <div class="inventory_item_name">Backpack</div>
    <div class="pricebar">
        <div class="inventory_item_price">$29.99</div>
        <button id="add-to-cart-backpack">Add to cart</button>
    </div>
</div>
```

The Products page HAS-A list of products. This object relationship is called Composition. In simpler terms, something is *composed of* another thing.

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

// Page Object
public class ProductsPage extends BasePage {
    public ProductsPage(WebDriver driver) {
        super(driver);
        // No assertions, throws an exception if the element is not loaded
        new WebDriverWait(driver, Duration.ofSeconds(3))
            .until(d -> d.findElement(By.className​("header_container")));
    }

    // Returning a list of products is a service of the page
    public List<Product> getProducts() {
        return driver.findElements(By.className​("inventory_item"))
            .stream()
            .map(e -> new Product(e)) // Map WebElement to a product component
            .toList();
    }

    // Return a specific product using a boolean-valued function (predicate)
    // This is the behavioral Strategy Pattern from GoF
    public Product getProduct(Predicate<Product> condition) {
        return getProducts()
            .stream()
            .filter(condition) // Filter by product name or price
            .findFirst()
            .orElseThrow(() -> new RuntimeException("Product not found")); // Error thrown during actual test run
    }
}
```

The Product component object is used inside the Products page object.

```java
public abstract class BaseComponent {
    protected WebElement root;

    public BaseComponent(WebElement root) {
        this.root = root;
    }
}

// Page Component Object
public class Product extends BaseComponent {
    // The root element contains the entire component
    public Product(WebElement root) {
        super(root); // inventory_item
    }

    public String getName() {
        // Locating an element begins at the root of the component
        return root.findElement(By.className("inventory_item_name")).getText();
    }

    public BigDecimal getPrice() {
        return new BigDecimal(
                root.findElement(By.className("inventory_item_price"))
                    .getText()
                    .replace("$", "")
            ).setScale(2, RoundingMode.UNNECESSARY); // Sanitation and formatting
    }

    public void addToCart() {
        root.findElement(By.id("add-to-cart-backpack")).click();
    }
}
```

So now, the products test would use the page object and the page component object as follows.

```java
public class ProductsTest {
    @Test
    public void testProductInventory() {
        var productsPage = new ProductsPage(driver); // page object
        var products = productsPage.getProducts();
        assertEquals(6, products.size()); // expected, actual
    }
    
    @Test
    public void testProductPrices() {
        var productsPage = new ProductsPage(driver);

        // Pass a lambda expression (predicate) to filter the list of products
        // The predicate or "strategy" is the behavior passed as parameter
        var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); // page component object
        var bikeLight = productsPage.getProduct(p -> p.getName().equals("Bike Light"));

        assertEquals(new BigDecimal("29.99"), backpack.getPrice());
        assertEquals(new BigDecimal("9.99"), bikeLight.getPrice());
    }
}
```

```java
public class LoginPage {
    public HomePage loginAs(String username, String password) {
        // ... clever magic happens here
    }
    
    public LoginPage loginAsExpectingError(String username, String password) {
        //  ... failed login here, maybe because one or both of the username and password are wrong
    }
    
    public String getErrorMessage() {
        // So we can verify that the correct error is shown
    }
}
```

The code presented above shows an important point: the tests, not the Page Objects, should be responsible for making assertions about the state of a page. For example:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    inbox.assertMessageWithSubjectIsUnread("I like cheese");
    inbox.assertMessageWithSubjectIsNotUnread("I'm not fond of tofu");
}
```

could be re-written as:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    assertTrue(inbox.isMessageWithSubjectIsUnread("I like cheese"));
    assertFalse(inbox.isMessageWithSubjectIsUnread("I'm not fond of tofu"));
}
```

```java
public class LoginPage {
    private final WebDriver driver;

    public LoginPage(WebDriver driver) {
        this.driver = driver;

        // Check that we're on the right page.
        if (!"Login".equals(driver.getTitle())) {
            // Alternatively, we could navigate to the login page, perhaps logging out first
            throw new IllegalStateException("This is not the login page");
        }
    }

    // The login page contains several HTML elements that will be represented as WebElements.
    // The locators for these elements should only be defined once.
        By usernameLocator = By.id("username");
        By passwordLocator = By.id("passwd");
        By loginButtonLocator = By.id("login");

    // The login page allows the user to type their username into the username field
    public LoginPage typeUsername(String username) {
        // This is the only place that "knows" how to enter a username
        driver.findElement(usernameLocator).sendKeys(username);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to type their password into the password field
    public LoginPage typePassword(String password) {
        // This is the only place that "knows" how to enter a password
        driver.findElement(passwordLocator).sendKeys(password);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to submit the login form
    public HomePage submitLogin() {
        // This is the only place that submits the login form and expects the destination to be the home page.
        // A seperate method should be created for the instance of clicking login whilst expecting a login failure. 
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the login page ever
        // go somewhere else (for example, a legal disclaimer) then changing the method signature
        // for this method will mean that all tests that rely on this behaviour won't compile.
        return new HomePage(driver);	
    }

    // The login page allows the user to submit the login form knowing that an invalid username and / or password were entered
    public LoginPage submitLoginExpectingFailure() {
        // This is the only place that submits the login form and expects the destination to be the login page due to login failure.
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the user ever be navigated to the home page after submiting a login with credentials 
        // expected to fail login, the script will fail when it attempts to instantiate the LoginPage PageObject.
        return new LoginPage(driver);	
    }

    // Conceptually, the login page offers the user the service of being able to "log into"
    // the application using a user name and password. 
    public HomePage loginAs(String username, String password) {
        // The PageObject methods that enter username, password & submit login have already defined and should not be repeated here.
        typeUsername(username);
        typePassword(password);
        return submitLogin();
    }
}
```

# 2 - Linguagem específica de domínio (DSL)

```java
/**
 * Recebe um username e password, prrenche os campos, e clica em "login".
 * @return Uma instância de AccountPage
 */
public AccountPage loginAsUser(String username, String password) {
  WebElement loginField = driver.findElement(By.id("loginField"));
  loginField.clear();
  loginField.sendKeys(username);

  // Preenche o campo password. O localizador que estamos usando é "By.id", e devemos
  // definí-lo em algum outro lugar dentro da Classe.
  WebElement passwordField = driver.findElement(By.id("password"));
  passwordField.clear();
  passwordField.sendKeys(password);

  // Clica o botão de login, que possui o id "submit".
  driver.findElement(By.id("submit")).click();

  // Cria e retorna uma nova instância de AccountPage (via o Selenium
  // PageFactory embutido).
  return PageFactory.newInstance(AccountPage.class);
}
```

Este método abstrai completamente os conceitos de campos de entrada, botões, cliques e até páginas do seu código de teste. Usando este abordagem, tudo o que o testador precisa fazer é chamar esse método. Isto dá uma vantagem de manutenção: se os campos de login mudaram, você teria apenas que alterar esse método - não seus testes.

```java
public void loginTest() {
    loginAsUser("cbrown", "cl0wn3");

    // Agora que estamos logados, fazemos alguma outra coisa--como usamos uma DSL para suportar
    // nossos testadores, é apenas escolher um dos métodos disponíveis.
    do.something();
    do.somethingElse();
    Assert.assertTrue("Algo deveria ter sido feito!", something.wasDone());

    // Note que ainda não nos referimos a nenhum botão ou web control nesse
    // script...
}
```

Vale a pena repetir: um de seus principais objetivos deve ser escrever um API que permite que seus testes resolvam **o problema em questão, e NÃO o problema da IU**. A IU é uma preocupação secundária para o seu usuários - eles não se importam com a interface do usuário, eles apenas querem fazer seu trabalho feito. Seus scripts de teste devem ser lidos como uma lista de itens sujos que o usuário deseja FAZER e as coisas que deseja SABER. Os testes não devem se preocupar com COMO a interface do usuário exige que você vá sobre isso.

\***AUT**: Application under test

# 3 - Gerando estado da aplicação

Selenium não deve ser usado para preparar um caso de teste. Tudo as ações repetitivas e preparações para um caso de teste devem ser feitas por meio de outros métodos. Por exemplo, a maioria das IUs da web tem autenticação (por exemplo, um formulário de login). Eliminar o login via navegador da web antes de cada teste irá melhorar a velocidade e estabilidade do teste. Um método deve ser criado para obter acesso à AUT\* (por exemplo, usando uma API para fazer login e definir um cookie). Além disso, a criação de métodos para pré-carregar dados para o teste não deve ser feito usando Selenium. Como dito anteriormente, APIs existentes devem ser aproveitadas para criar dados para a AUT \*.

\***AUT**: Application under test

# 4 - Simulação de serviços externos

Eliminar as dependências de serviços externos melhorará muito a velocidade e estabilidade de seus testes.

# 5 - Relatórios melhorados

O Selenium não foi projetado para relatar sobre o status de casos de teste. Aproveitar os recursos de relatórios integrados de frameworks de teste unitários é um bom começo. A maioria dos frameworks de teste unitários podem gerar relatórios formatados em xUnit ou HTML. Relatórios xUnit são populares para importar resultados para um servidor de integração contínua (CI) como Jenkins, Travis, Bamboo, etc. Aqui estão alguns links para obter mais informações sobre resultados de relatórios em vários idiomas.

[NUnit 3 Console Runner](//github.com/nunit/docs/wiki/Console-Runner)

[NUnit 3 Console Command Line](//github.com/nunit/docs/wiki/Console-Command-Line)

[xUnit getting test results in TeamCity](//xunit.net/docs/getting-test-results-in-teamcity)

[xUnit getting test results in CruiseControl.NET](//xunit.net/docs/getting-test-results-in-ccnet)

[xUnit getting test results in Azure DevOps](//xunit.net/docs/getting-test-results-in-azure-devops)

# 6 - Evite compartilhamento de estado

Embora mencionado em vários lugares, vale a pena mencionar novamente. Garanta que os testes são isolados uns dos outros.

* Não compartilhe dados de teste. Imagine vários testes em que cada um consulta o banco de dados para pedidos válidos antes de escolher um para executar uma ação. Caso dois testes peguem a mesma ordem, provavelmente você obterá um comportamento inesperado.

* Limpe dados desatualizados no aplicativo que podem ser obtidos por outro teste, por exemplo registros de pedidos inválidos.

* Crie uma nova instância do WebDriver por teste. Isso ajuda a garantir o isolamento do teste e torna a paralelização mais simples.

  * If you choose [pytest](https://pytest.org/) as your test runner, this can be easily done by yielding your driver in a global fixture. This way each test gets its own driver instance, and you can ensure that drivers always quit after a test is finished (pass or fail).

# 7 - Tips on working with locators

# 8 - Independência de Testes

Escreva cada teste como sua própria unidade. Escreva os testes de uma forma que não seja dependente de outros testes para concluir:

Digamos que existe um sistema de gerenciamento de conteúdo com o qual você pode criar algum conteúdo personalizado que então aparece em seu site como um módulo após publicação, e pode levar algum tempo para sincronizar entre o CMS e a aplicação.

Uma maneira errada de testar seu módulo é que o conteúdo seja criado e publicado em um teste e, em seguida, verificar o módulo em outro teste. Este teste não é viável, pois o conteúdo pode não estar disponível imediatamente para o outro teste após a publicação.

Em vez disso, você pode criar um conteúdo stub que pode ser ligado e desligado dentro do teste e use-o para validar o módulo. Contudo, para a criação de conteúdo, você ainda pode ter um teste separado.

# 9 - Considere usar uma API fluente

Martin Fowler cunhou o termo [“API Fluent”](//www.martinfowler.com/bliki/FluentInterface.html). Selenium já implementa algo assim em sua classe `FluentWait`, que é pretende ser uma alternativa à classe padrão `Wait`. Você pode habilitar o padrão de design de API fluente em seu objeto de página e, em seguida, consulte a página de pesquisa do Google com um snippet de código como este:

```java
driver.get( "http://www.google.com/webhp?hl=en&amp;tab=ww" );
GoogleSearchPage gsp = new GoogleSearchPage(driver);
gsp.setSearchString().clickSearchButton();
```

A classe de objeto da página do Google com este comportamento fluente pode ser assim:

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

public class GoogleSearchPage extends BasePage {
    public GoogleSearchPage(WebDriver driver) {
        super(driver);
        // Generally do not assert within pages or components.
        // Effectively throws an exception if the lambda condition is not met.
        new WebDriverWait(driver, Duration.ofSeconds(3)).until(d -> d.findElement(By.id("logo")));
    }

    public GoogleSearchPage setSearchString(String sstr) {
        driver.findElement(By.id("gbqfq")).sendKeys(sstr);
        return this;
    }

    public void clickSearchButton() {
        driver.findElement(By.id("gbqfb")).click();
    }
}
```

# 10 - Navegador novo por teste

Comece cada teste a partir de um estado limpo conhecido. Idealmente, ligue uma nova máquina virtual para cada teste. Se ligar uma nova máquina virtual não for prático, pelo menos inicie um novo WebDriver para cada teste. Most browser drivers like GeckoDriver and ChromeDriver will start with a clean known state with a new user profile, by default.

```java
WebDriver driver = new FirefoxDriver();
```

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/bidi/w3c/log/
----

# BiDirectional API (W3C compliant)

```java
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L33-L39)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/logInspector.spec.js#L23-37)

##### /examples/javascript/test/bidirectional/logInspector.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const LogInspector = require('selenium-webdriver/bidi/logInspector');
const {Builder} = require("selenium-webdriver");


describe('Log Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test listen to console log', async function () {
    let logEntry = null
    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)

    await inspector.close()
  })

  it('test listen to javascript error log', async function () {
    let logEntry = null
    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')

    await inspector.close()
  })

  it('test retrieve stack trace for a log', async function () {
    let logEntry = null
    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()

    const stackTrace = logEntry.stackTrace
    assert.notEqual(stackTrace, null)
    assert.equal(stackTrace.callFrames.length, 3)

    await inspector.close()
  })

  it('test listen to logs with multiple consumers', async function () {
    let logEntry1 = null
    let logEntry2 = null
    const inspector = await LogInspector(driver)
    await inspector.onJavascriptException(function (log) {
      logEntry1 = log
    })
    await inspector.onJavascriptException(function (log) {
      logEntry2 = log
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    await driver.findElement({id: 'jsException'}).click()

    assert.equal(logEntry1.text, 'Error: Not working')
    assert.equal(logEntry1.type, 'javascript')
    assert.equal(logEntry1.level, 'error')

    assert.equal(logEntry2.text, 'Error: Not working')
    assert.equal(logEntry2.type, 'javascript')
    assert.equal(logEntry2.level, 'error')

    await inspector.close()
  })
})
```

```java
            logInspector.onJavaScriptException(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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L73-L78)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/logInspector.spec.js#L44-54)

##### /examples/javascript/test/bidirectional/logInspector.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const LogInspector = require('selenium-webdriver/bidi/logInspector');
const {Builder} = require("selenium-webdriver");


describe('Log Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test listen to console log', async function () {
    let logEntry = null
    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)

    await inspector.close()
  })

  it('test listen to javascript error log', async function () {
    let logEntry = null
    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')

    await inspector.close()
  })

  it('test retrieve stack trace for a log', async function () {
    let logEntry = null
    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()

    const stackTrace = logEntry.stackTrace
    assert.notEqual(stackTrace, null)
    assert.equal(stackTrace.callFrames.length, 3)

    await inspector.close()
  })

  it('test listen to logs with multiple consumers', async function () {
    let logEntry1 = null
    let logEntry2 = null
    const inspector = await LogInspector(driver)
    await inspector.onJavascriptException(function (log) {
      logEntry1 = log
    })
    await inspector.onJavascriptException(function (log) {
      logEntry2 = log
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    await driver.findElement({id: 'jsException'}).click()

    assert.equal(logEntry1.text, 'Error: Not working')
    assert.equal(logEntry1.type, 'javascript')
    assert.equal(logEntry1.level, 'error')

    assert.equal(logEntry2.text, 'Error: Not working')
    assert.equal(logEntry2.type, 'javascript')
    assert.equal(logEntry2.level, 'error')

    await inspector.close()
  })
})
```

```java
            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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L55-L60)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

最后修改 December 16, 2024: [\[java\] Remove a wrong code example and update code lines (#2104) (6b3cccc0e32)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/6b3cccc0e32b97a2a88350983e4b7c73836e0733)

----
url: https://www.selenium.dev/zh-cn/_print/documentation/ie_driver_server/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/ie_driver_server/).

# IE驱动服务器

Internet Explorer驱动是一种实现WebDriver规范的单机服务器.

* 1: [Internet Explorer Driver Internals](#pg-ba2a70d400adfd913cd1fc223657f3dd)

| 开关                   | 释义                                                                      |
| -------------------- | ----------------------------------------------------------------------- |
| –port=`<端口号>`        | 指定IE驱动程序的HTTP服务器将在其上侦听来自语言绑定的命令的端口. 默认值为5555.                           |
| –host=`<主机IP地址>`     | 指定主机适配器的IP地址, IE驱动程序的HTTP服务器将在其上侦听来自语言绑定的命令. 默认值为127.0.0.1.             |
| –log-level=`<日志级别>`  | 指定日志消息的输出级别. 有效值包括 FATAL, ERROR, WARN, INFO, DEBUG, 以及 TRACE. 默认为FATAL. |
| –log-file=`<日志文件>`   | 指定日志文件的完整路径和文件名. 默认为标准输出.                                               |
| –extract-path=`<路径>` | 指定用于提取服务器使用的支持文件的目录的完整路径. 如果未指定, 则默认为临时目录.                              |
| –silent              | 在服务器启动时抑制诊断输出.                                                          |

## 重要的系统属性

以下系统属性用于 `InternetExplorerDriver` (在Java代码中使用 `System.getProperty()` 读取并使用`System.setProperty()` 进行设置, 或者 在命令行标识 “`-DpropertyName=value`”) :

| **属性**                            | **含义**                                                                  |
| --------------------------------- | ----------------------------------------------------------------------- |
| `webdriver.ie.driver`             | IE驱动程序二进制文件的位置.                                                         |
| `webdriver.ie.driver.host`        | 指定IE驱动程序将在其上侦听的主机适配器的IP地址.                                              |
| `webdriver.ie.driver.loglevel`    | 指定日志消息的输出级别. 有效值包括 FATAL, ERROR, WARN, INFO, DEBUG, 以及 TRACE. 默认为FATAL. |
| `webdriver.ie.driver.logfile`     | 指定日志文件的完整路径和文件名.                                                        |
| `webdriver.ie.driver.silent`      | 在IE驱动程序启动时抑制诊断输出.                                                       |
| `webdriver.ie.driver.extractpath` | 指定用于提取服务器使用的支持文件的目录的完整路径. 如果未指定, 则默认为临时目录.                              |

----
url: https://www.selenium.dev/ja/_print/documentation/grid/configuration/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/grid/configuration/).

# コンポーネントの構成

ここでは、各コンポーネントを、共通の設定とコンポーネント固有の設定で個別に設定する方法を確認できます。

* 1: [構成ヘルプ](#pg-12759b62a0129dd593b35c93c9ce349e)
* 2: [Selenium GridのCLI オプション](#pg-4ed8bf1ae4585a0e8d21dbdfce81afb8)
* 3: [Toml オプション](#pg-e617239c5efb3fbc97f69447f5ba5981)

# 1 - 構成ヘルプ

```shell
java -jar selenium-server-<version>.jar info config
```

### セキュリティ

安全な通信とノード登録のためのグリッドサーバーの設定の詳細を取得するには、以下を実行します。

```shell
java -jar selenium-server-<version>.jar info security
```

### セッションマップの設定

デフォルトでは、グリッドはローカルセッションマップを使用してセッション情報を保存します。 グリッドは、Redis や JDBC-SQL がサポートするデータベースなどの追加のストレージオプションをサポートしています。 別のセッションストレージをセットアップするには、次のコマンドを使用してセットアップ手順を取得します。

```shell
java -jar selenium-server-<version>.jar info sessionmap
```

### OpenTelemetry と Jaeger を使用したトレースの設定

デフォルトでは、トレースは有効になっています。 トレースをエクスポートして Jaeger 経由で視覚化するには、次のコマンドを使用して手順を実行します。

```shell
java -jar selenium-server-<version>.jar info tracing
```

## SeleniumGrid コマンドを一覧表示する

```shell
java -jar selenium-server-<version>.jar --config-help
```

使用可能なすべてのコマンドとそれぞれの説明が表示されます。

## コンポーネントヘルプコマンド

Selenium ロールの後に–help config オプションを渡して、コンポーネント固有の構成情報を取得します。

### スタンドアロン

```shell
java -jar selenium-server-<version>.jar standalone --help
```

### ハブ

```shell
java -jar selenium-server-<version>.jar hub --help
```

### セッション

```shell
java -jar selenium-server-<version>.jar sessions --help
```

### 新規セッションキュー

```shell
java -jar selenium-server-<version>.jar sessionqueue --help
```

### ディストリビューター

```shell
java -jar selenium-server-<version>.jar distributor --help
```

### ルーター

```shell
java -jar selenium-server-<version>.jar router --help
```

### ノード

```shell
java -jar selenium-server-<version>.jar node --help
```

# 2 - Selenium GridのCLI オプション

全てのGridコンポーネントのCLIオプション詳細

Grid の設定には、さまざまなセクションが用意されています。 各セクションには、コマンドライン引数で設定可能なオプションがあります。コマンドライン引数で設定できます。

コンポーネントとセクションの対応は以下の通りです。

オプションが変更、または追加されたが文書化されていない場合、 このドキュメントは古くなる可能性があることに注意してください。 もしそのような状況を見つけたら、[“構成ヘルプ”](https://www.selenium.dev/ja/documentation/grid/configuration/help/)を確認し、 ドキュメントを更新するプルリクエストを気軽に送ってください。

## セクション

|                               | スタンドアロン | ハブ | ノード | ディストリビューター | ルーター | セッション | 新規セッションキュー |
| ----------------------------- | ------- | -- | --- | ---------- | ---- | ----- | ---------- |
| [Distributor](#distributor)   | **      | ** |     | **         | **   |       |            |
| [Docker](#docker)             | **      |    | **  |            |      |       |            |
| [Events](#events)             |         | ** | **  | **         |      | **    | **         |
| [Logging](#logging)           | **      | ** | **  | **         | **   | **    | **         |
| [Network](#network)           | **      | ** |     |            | **   |       |            |
| [Node](#node)                 | **      |    | **  |            |      |       |            |
| [Router](#router)             | **      | ** |     |            | **   |       |            |
| [Relay](#relay)               | **      |    | **  |            |      |       |            |
| [Server](#server)             | **      | ** | **  | **         | **   | **    | **         |
| [SessionQueue](#sessionqueue) | **      | ** |     | **         | **   |       | **         |
| [Sessions](#sessions)         |         |    |     | **         | **   | **    |            |

### Distributor

| オプション                          | 型       | 値/例                                                                 | 概要                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ------------------------------ | ------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--healthcheck-interval`       | int     | `120`                                                               | 全てのノードに対してヘルスチェックを実行する頻度（秒）を指定します。これにより、サーバーは全てのノードに対して正常に ping を送信できるようになります。                                                                                                                                                                                                                                                                                                                                                                      |
| `--distributor`                | uri     | `http://localhost:5553`                                             | ディストリビューターの URL。                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `--distributor-host`           | string  | `localhost`                                                         | ディストリビューターがリッスンするホスト名。                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `--distributor-implementation` | string  | `org.openqa.selenium.grid.distributor.local.LocalDistributor`       | デフォルトでないディストリビューター実装の完全なクラス名。                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `--distributor-port`           | int     | `5553`                                                              | ディストリビューターがリッスンするポート番号。                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `--reject-unsupported-caps`    | boolean | `false`                                                             | Grid がサポートしていない capabilities をリクエストされた時、ディストリビューターがリクエストを即座に今日できるようにします。これはオンデマンドでノードを立ち上げをしない Grid の設定に適しています。                                                                                                                                                                                                                                                                                                                                     |
| `--slot-matcher`               | string  | `org.openqa.selenium.grid.data.DefaultSlotMatcher`                  | デフォルト以外で使用するスロットマッチャーの完全なクラス名。これはノードが特定のセッションをサポートできるかを判断するために使用されます。                                                                                                                                                                                                                                                                                                                                                                               |
| `--slot-selector`              | string  | `org.openqa.selenium.grid.distributor.selector.DefaultSlotSelector` | デフォルト以外のスロットセレクターの完全なクラス名。これは、ノードがマッチした後ノード内のスロットを選択するために使用されます。                                                                                                                                                                                                                                                                                                                                                                                    |
| `--newsession-threadpool-size` | int     | `24`                                                                | The Distributor uses a fixed-sized thread pool to create new sessions as it consumes new session requests from the queue. This allows configuring the size of the thread pool. The default value is no. of available processors \* 3. Note: If the no. of threads is way greater than the available processors it will not always increase the performance. A high number of threads causes more context switching which is an expensive operation. |
| `--purge-nodes-interval`       | int     | `30`                                                                | How often, in seconds, will the Distributor purge Nodes that have been down for a while. This is calculated based on the heartbeat received from a particular node.                                                                                                                                                                                                                                                                                 |

### Docker

| オプション                       | 型         | 値/例                                                               | 概要                                                                                                                                                                                                                                                                                          |
| --------------------------- | --------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--docker-assets-path`      | string    | `/opt/selenium/assets`                                            | アセットが保存される絶対パス。                                                                                                                                                                                                                                                                             |
| `--docker-`                 | string\[] | `selenium/standalone-firefox:latest '{"browserName": "firefox"}'` | イメージとステレオタイプの capabilities を対応付ける Docker 設定 (例 \`-D selenium/standalone-firefox:latest ‘{“browserName”: “firefox”}’)                                                                                                                                                                        |
| `--docker-devices`          | string\[] | `/dev/kvm:/dev/kvm`                                               | コンテナに対してデバイスを公開します。各デバイスマッピングは、ホストとコンテナの両方のデバイスへのパスを、コロンで区切って保つ必要があります。例: /device/path/in/host:/device/path/in/container                                                                                                                                                                    |
| `--docker-host`             | string    | `localhost`                                                       | Docker デーモンが動作しているホスト名。                                                                                                                                                                                                                                                                     |
| `--docker-port`             | int       | `2375`                                                            | Docker デーモンが動作しているポート名。                                                                                                                                                                                                                                                                     |
| `--docker-url`              | string    | `http://localhost:2375`                                           | Docker デーモンに接続するための URL。                                                                                                                                                                                                                                                                    |
| `--docker-video-image`      | string    | `selenium/video:latest`                                           | ビデオレコーディングが有効になっているときに利用される Docker イメージ。                                                                                                                                                                                                                                                    |
| `--docker-host-config-keys` | string\[] | `Dns DnsOptions DnsSearch ExtraHosts Binds`                       | Specify which docker host configuration keys should be passed to browser containers. Keys name can be found in the Docker API [documentation](https://docs.docker.com/engine/api/v1.41/#tag/Container/operation/ContainerCreate), or by running `docker inspect` the node-docker container. |

### Events

| オプション                     | 型       | 値/例                                                | 概要                                                                                                                                                |
| ------------------------- | ------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--bind-bus`              | boolean | `false`                                            | 接続をバインドするかコネクトするかを指定します。 true の場合、コンポーネントはイベントバスにバインドされます（イベントバスもコンポーネントによって起動されます、通常はディストリビューターとハブによって起動されます）。 false の場合、コンポーネントがイベントバスにコネクトします。 |
| `--events-implementation` | string  | `org.openqa.selenium.events.zeromq.ZeroMqEventBus` | デフォルトでないイベントバス実装の完全なクラス名。                                                                                                                         |
| `--publish-events`        | string  | `tcp://*:4442`                                     | イベントをイベントバスに配信するための接続文字列。                                                                                                                         |
| `--subscribe-events`      | string  | `tcp://*:4443`                                     | イベントをイベントバスから購読するための接続文字列。                                                                                                                        |

### Logging

| オプション                    | 型       | 値/例                                                                                                                                      | 概要                                                                                                                                       |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `--http-logs`            | boolean | `false`                                                                                                                                  | http ログを有効にします。http ログを記録するには、トレースを有効にする必要があります。                                                                                         |
| `--log-encoding`         | string  | `UTF-8`                                                                                                                                  | ログのエンコーディング。                                                                                                                             |
| `--log`                  | string  | Windows パスの例: `'\path\to\file\gridlog.log'` or `'C:\path\path\to\file\gridlog.log'` Linux/Unix/MacOS パスの例: `'/path/to/file/gridlog.log'` | ログを出力するファイル。OS のファイルパスと互換性があることを確認してください。                                                                                                |
| `--log-level`            | string  | `“INFO”`                                                                                                                                 | ログレベル。デフォルトは INFO です。 ログレベルはこちらを参照してください。 <https://docs.oracle.com/en/java/javase/11/docs/api/java.logging/java/util/logging/Level.html> |
| `--plain-logs`           | boolean | `true`                                                                                                                                   | プレーンなログを使用します。                                                                                                                           |
| `--structured-logs`      | boolean | `false`                                                                                                                                  | 構造化ログを使用します。                                                                                                                             |
| `--tracing`              | boolean | `true`                                                                                                                                   | トレースを有効にします。                                                                                                                             |
| `--log-timestamp-format` | string  | `HH:mm:ss.SSS`                                                                                                                           | ログのタイムスタンプ形式を設定できます。                                                                                                                     |

### Network

| オプション            | 型       | 値/例     | 概要                                                  |
| ---------------- | ------- | ------- | --------------------------------------------------- |
| `--relax-checks` | boolean | `false` | 受信リクエストのオリジンヘッダーとコンテンツタイプに対する、厳格な W3C 準拠の検証をを緩和します。 |

### Node

| オプション                            | 型         | 値/例                                                                                                                                                                                                                                                                        | 概要                                                                                                                                                                                                                                                                                                                                                                             |
| -------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--detect-drivers`               | boolean   | `true`                                                                                                                                                                                                                                                                     | 現在のシステム上で利用可能なドライバーを自動で検出してノードに追加します。                                                                                                                                                                                                                                                                                                                                          |
| `--driver-configuration`         | string\[] | `display-name="Firefox Nightly" max-sessions=2 webdriver-path="/usr/local/bin/geckodriver" stereotype="{\"browserName\": \"firefox\", \"browserVersion\": \"86\", \"moz:firefoxOptions\": {\"binary\":\"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"` | ノードがサポートするドライバーの一覧。可読性向上のため TOML ファイルで設定することを推奨します。                                                                                                                                                                                                                                                                                                                            |
| `--driver-factory`               | string\[] | `org.openqa.selenium.example.LynxDriverFactory '{"browserName": "lynx"}'`                                                                                                                                                                                                  | 完全修飾クラス名と、そのクラスが対応するブラウザの設定とのマッピング。                                                                                                                                                                                                                                                                                                                                            |
| `--driver-implementation`        | string\[] | `"firefox"`                                                                                                                                                                                                                                                                | チェックされるドライバー。指定された場合、自動設定はスキップされます。                                                                                                                                                                                                                                                                                                                                            |
| `--node-implementation`          | string    | `"org.openqa.selenium.grid.node.local.LocalNodeFactory"`                                                                                                                                                                                                                   | デフォルトでないノード実装の完全なクラス名。これはセッションのライフサイクルを管理するために使用されます。                                                                                                                                                                                                                                                                                                                          |
| `--grid-url`                     | string    | `https://grid.example.com`                                                                                                                                                                                                                                                 | Grid 全体のパブリックな URL (通常ハブかルーターのアドレスです)。                                                                                                                                                                                                                                                                                                                                         |
| `--heartbeat-period`             | int       | `60`                                                                                                                                                                                                                                                                       | ノードが生存していることを知らせるため、ノードがディストリビューターに送るハードビートを、どのくらいの頻度（秒）で送るか。                                                                                                                                                                                                                                                                                                                  |
| `--max-sessions`                 | int       | `8`                                                                                                                                                                                                                                                                        | 最大同時接続セッション数。デフォルトは利用可能なプロセッサーの数です。                                                                                                                                                                                                                                                                                                                                            |
| `--override-max-sessions`        | boolean   | `false`                                                                                                                                                                                                                                                                    | 利用可能なプロセッサーの数は、推奨される最大セッション数（プロセッサーごとに 1 つのブラウザセッション）です。このフラグを true に設定すると、推奨される最大値を上書きすることができます。セッションの安定性と信頼性が損なわれ、ホストがリソースを使い果たす可能性があります。                                                                                                                                                                                                                                    |
| `--register-cycle`               | int       | `10`                                                                                                                                                                                                                                                                       | ノードがディストリビューターに初回登録を試みる頻度(秒)。                                                                                                                                                                                                                                                                                                                                                  |
| `--register-period`              | int       | `120`                                                                                                                                                                                                                                                                      | ノードが初めてディストリビューターに初回登録を試みるのにかかる時間(秒)。この時間が経過すると、ノードは再登録を試みない。                                                                                                                                                                                                                                                                                                                  |
| `--session-timeout`              | int       | `300`                                                                                                                                                                                                                                                                      | X をセッションタイムアウト(秒)としたとき、 ノード は、過去 X 秒間に何の活動もなかったセッションを自動的に終了させます。 これにより他のテストが利用できるようスロットを解放します。                                                                                                                                                                                                                                                                                 |
| `--vnc-env-var`                  | string\[] | `SE_START_XVFB SE_START_VNC SE_START_NO_VNC`                                                                                                                                                                                                                               | VNC ストリームが利用可能かどうかを判断するために利用する環境変数。                                                                                                                                                                                                                                                                                                                                            |
| `--no-vnc-port`                  | int       | `7900`                                                                                                                                                                                                                                                                     | VNC が利用可能な場合、ローカルの noVNC ストリームを取得できるポートを設定します。                                                                                                                                                                                                                                                                                                                                 |
| `--drain-after-session-count`    | int       | `1`                                                                                                                                                                                                                                                                        | X 個のセッションが実行された後に、ノードをドレインしてシャットダウンします。 Kubernetes のような環境で有用です。 0 より大きい値を指定すると、この機能が有効になります。                                                                                                                                                                                                                                                                                   |
| `--hub`                          | string    | `http://localhost:4444`                                                                                                                                                                                                                                                    | ハブ・ノード構成におけるハブのアドレスを指定します。ホスト名か IP アドレスが指定できます。この場合、ハブは `http://hostname:4444` とみなされ、 `--grid-url` は同じものになります。 `--publish-events` は `tcp://hostname:4442` 、`--subscribe-events` は `tcp://hostname:4443` となります。 `hostname` にポート番号が含まれている場合は、それが `--grid-url` に使用されますが、イベントバスの URI は変更されません。これらのデフォルト値は、適切なフラグを設定することでオーバーライドすることができます。ホスト名にプロトコル(`https`のような)が含まれる場合もそれが利用されます。 |
| `--enable-cdp`                   | boolean   | `true`                                                                                                                                                                                                                                                                     | Grid 内で CDP プロキシーを有効にします。もしネットワークが web socket を許可していない場合、Grid 管理者は CDP を無効にできます。デフォルトは true です。                                                                                                                                                                                                                                                                                |
| `--enable-managed-downloads`     | boolean   | `false`                                                                                                                                                                                                                                                                    | This causes the Node to auto manage files downloaded for a given session on the Node.                                                                                                                                                                                                                                                                                          |
| `--selenium-manager`             | boolean   | `false`                                                                                                                                                                                                                                                                    | When drivers are not available on the current system, use Selenium Manager. False by default.                                                                                                                                                                                                                                                                                  |
| `--connection-limit-per-session` | int       | `10`                                                                                                                                                                                                                                                                       | Let X be the maximum number of websocket connections per session.This will ensure one session is not able to exhaust the connection limit of the host.                                                                                                                                                                                                                         |

### Relay

| オプション                        | 型         | 値/例                                                                                                               | 概要                                                                                                              |
| ---------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `--service-url`              | string    | `http://localhost:4723`                                                                                           | Appium サーバーやクラウドサービスなど、WebDriver コマンドをサポートするサービスに接続するための URL です。                                                |
| `--service-host`             | string    | `localhost`                                                                                                       | WebDriver コマンドをサポートしてるサービスが稼働しているホスト名。                                                                          |
| `--service-port`             | int       | `4723`                                                                                                            | WebDriver コマンドをサポートしてるサービスが稼働しているポート番号。                                                                         |
| `--service-status-endpoint`  | string    | `/status`                                                                                                         | WebDriver サービスの状態を問い合わせるエンドポイント、オプショナルです。HTTP 200 レスポンスが期待されます。                                                 |
| `--service-protocol-version` | string    | `HTTP/1.1`                                                                                                        | Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status |
| `--service-configuration`    | string\[] | `max-sessions=2 stereotype='{"browserName": "safari", "platformName": "iOS", "appium:platformVersion": "14.5"}}'` | 呼び出しの中継先となるサービスの設定。可読性向上のため、TOML ファイルで設定することを推奨します。                                                             |

### Router

| オプション          | 型       | 値/例                        | 概要                                                                                            |
| -------------- | ------- | -------------------------- | --------------------------------------------------------------------------------------------- |
| `--password`   | string  | `myStrongPassword`         | クライアントがサーバーに接続する際に使用するパスワード。このパスワードとユーザー名の両方が設定されていないと使用できません。                                |
| `--username`   | string  | `admin`                    | クライアントがサーバーに接続する際に使用するユーザー名。このユーザー名とパスワードの両方が設定されていないと使用できません。                                |
| `--sub-path`   | string  | `my_company/selenium_grid` | A sub-path that should be considered for all user facing routes on the Hub/Router/Standalone. |
| `--disable-ui` | boolean | `true`                     | Disable the Grid UI.                                                                          |

### Server

| オプション                 | 型       | 値/例                  | 概要                                                                                                                                               |
| --------------------- | ------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--allow-cors`        | boolean | `true`               | Selenium サーバーが任意のホストからのウェブブラウザ接続を許可するかどうか。                                                                                                       |
| `--host`              | string  | `localhost`          | サーバーの IP もしくはホスト名、通常自動的に決定されます。                                                                                                                  |
| `--bind-host`         | boolean | `true`               | サーバがホストアドレス/ホスト名にバインドするか、あるいは到達可能な URL を知らせるためだけに使用するかを指定します。複雑なネットワーク構成で、サーバが現在の IP やホスト名ではなく、 外部の IP やホスト名で自分自身を公開する場合に有用です (例: Docker コンテナ内)。 |
| `--https-certificate` | path    | `/path/to/cert.pem`  | HTTPS のためのサーバー証明書。詳細は “java -jar selenium-server.jar info security” を実行してください。                                                                   |
| `--https-private-key` | path    | `/path/to/key.pkcs8` | HTTPS のための秘密鍵。 詳細は “java -jar selenium-server.jar info security” を実行してください。                                                                      |
| `--max-threads`       | int     | `24`                 | リスナースレッドの最大数。デフォルトは、有効なプロセッサーの \* 3 です。                                                                                                          |
| `--port`              | int     | `4444`               | リッスンポート。このパラメータは異なるコンポーネントによって使用されるため、デフォルトはありません。例えば、ルータ/ハブ/スタンドアロンは 4444 を使用し、ノードは 5555 を使用します。                                                |

### SessionQueue

| オプション                       | 型      | 値/例                     | 概要                                                                                                                                                      |
| --------------------------- | ------ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--sessionqueue`            | uri    | `http://localhost:1237` | 新規セッションキューサーバーのアドレス。                                                                                                                                    |
| `-sessionqueue-host`        | string | `localhost`             | 新規セッションキューがリッスンするホスト。                                                                                                                                   |
| `--sessionqueue-port`       | int    | `1234`                  | 新規セッションキューがリッスンするポート                                                                                                                                    |
| `--session-request-timeout` | int    | `300`                   | タイムアウト(秒)。 新規セッションリクエストはキューに追加され、設定された時間以上キューに残っているリクエストはタイムアウトします。                                                                                     |
| `--session-retry-interval`  | int    | `5`                     | リトライ間隔(秒)。すべてのスロットがビジーな場合、 新規セッションリクエストはこの時間の間隔をおいてからリトライされます。                                                                                          |
| `--maximum-response-delay`  | int    | `8`                     | How often, in seconds, will the the SessionQueue response in case there is no data, to reduce the http requests while polling for new session requests. |

### Sessions

| オプション             | 型      | 値/例                     | 概要                      |
| ----------------- | ------ | ----------------------- | ----------------------- |
| `--sessions`      | uri    | `http://localhost:1234` | セッションマップサーバーのアドレス。      |
| `--sessions-host` | string | `localhost`             | セッションマップサーバーがリッスンするホスト。 |
| `--sessions-port` | int    | `1234`                  | セッションマップサーバーがリッスンするポート。 |

## 設定例

上記のオプションはすべて、Grid コンポーネントを起動する際に使用することができます。 Grid の適切な設定を模索するのに利用してください。

[TOML ファイル](https://www.selenium.dev/ja/documentation/grid/configuration/toml_options/) を使用して Grid を設定することをおすすめします。 設定ファイルは読みやすく、コード管理できます。

必要に応じて TOML ファイルと CLI オプションを併用することができます。

### コマンドラインフラグ

コマンドラインフラグとしてオプションを渡すには、適切なコンポーネントを特定し以下のテンプレートのようにします。

```
java -jar selenium-server-<version>.jar <component> --<option> value
```

#### スタドアロン、最大セッションとメインポートを設定する

```
java -jar selenium-server-<version>.jar standalone --max-sessions 4 --port 4444
```

#### ハブ、新規セッションリクエストのタイムアウト、メインポートを設定し、トレースを無効にする

```
java -jar selenium-server-<version>.jar hub --session-request-timeout 500 --port 3333 --tracing false
```

#### ノード、最大 4 セッション、デバッグログ、ポート 7777, FireFox と Edge のみ

```
java -jar selenium-server-<version>.jar node --max-sessions 4 --log-level "fine" --port 7777 --driver-implementation "firefox" --driver-implementation "edge"
```

#### ディストリビューター、セッションマップ・新規セッションキューの URL を指定、バスを無効にする

```
java -jar selenium-server-<version>.jar distributor --sessions http://localhost:5556 --sessionqueue http://localhost:5559 --bind-bus false
```

#### 特定ノードにカスタム capabilities を設定する

**重要:** カスタム capabilities は全てのノードに設定される必要があります。 また全てのセッションリクエストに含まれなければいけません。

##### ハブの起動

```
java -jar selenium-server-<version>.jar hub
```

##### customcap に `true` をセットしてノード A を起動する

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":true}' --port 6161
```

##### customcap に `false` をセットしてノード B を起動する

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":false}' --port 6262
```

##### ノード A とマッチ

```java
ChromeOptions options = new ChromeOptions();
options.setCapability("gsg:customcap", true);
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

ノード B とマッチさせるにはカスタム capability を `false` に設定します。

#### Enabling Managed downloads by the Node

At times a test may need to access files that were downloaded by it on the Node. To retrieve such files, following can be done.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node with manage downloads enabled

```
java -jar selenium-server-<version>.jar node --enable-managed-downloads true
```

##### Set the capability at the test level

Tests that want to use this feature should set the capability `"se:downloadsEnabled"`to `true`

```java
options.setCapability("se:downloadsEnabled", true);
```

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

In the response the list of file names appear under the key `names`.

##### Dowloading a file:

* The endpoint to `POST` from is `/session/<sessionId>/se/files` with a payload of the form `{"name": "fileNameGoesHere}`
* The session needs to be active in order for the command to work.
* The raw response looks like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "Base64EncodedStringContentsOfDownloadedFileAsZipGoesHere"
  }
}
```

* The response blob contains two keys,

  * `filename` - The file name that was downloaded.
  * `contents` - Base64 encoded zipped contents of the file.

* The file contents are Base64 encoded and they need to be unzipped.

##### List files that can be downloaded

The below mentioned `curl` example can be used to list all the files that were downloaded by the current session in the Node, and which can be retrieved locally.

```bash
curl -X GET "http://localhost:4444/session/90c0149a-2e75-424d-857a-e78734943d4c/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

##### Retrieve a downloaded file

Assuming the downloaded file is named `Red-blue-green-channel.jpg`, and using `curl`, the file could be downloaded with the following command:

```bash
curl -H "Accept: application/json" \
-H "Content-Type: application/json; charset=utf-8" \
-X POST -d '{"name":"Red-blue-green-channel.jpg"}' \
"http://localhost:4444/session/18033434-fa4f-4d11-a7df-9e6d75920e19/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "UEsDBBQACAgIAJpagVYAAAAAAAAAAAAAAAAaAAAAUmVkLWJsAAAAAAAAAAAAUmVkLWJsdWUtZ3JlZW4tY2hhbm5lbC5qcGdQSwUGAAAAAAEAAQBIAAAAcNkAAAAA"
  }
}
```

##### Complete sample code in Java

Below is an example in Java that does the following:

* Sets the capability to indicate that the test requires automatic managing of downloaded files.
* Triggers a file download via a browser.
* Lists the files that are available for retrieval from the remote node (These are essentially files that were downloaded in the current session)
* Picks one file and downloads the file from the remote node to the local machine.

```java
import com.google.common.collect.ImmutableMap;

import org.openqa.selenium.By;
import org.openqa.selenium.io.Zip;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.io.File;
import java.net.URL;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import static org.openqa.selenium.remote.http.Contents.asJson;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.HttpMethod.GET;
import static org.openqa.selenium.remote.http.HttpMethod.POST;

public class DownloadsSample {

  public static void main(String[] args) throws Exception {
    // Assuming the Grid is running locally.
    URL gridUrl = new URL("http://localhost:4444");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("se:downloadsEnabled", true);
    RemoteWebDriver driver = new RemoteWebDriver(gridUrl, options);
    try {
      demoFileDownloads(driver, gridUrl);
    } finally {
      driver.quit();
    }
  }

	private static void demoFileDownloads(RemoteWebDriver driver, URL gridUrl) throws Exception {
		driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
		// Download the two available files on the page
		driver.findElement(By.id("file-1")).click();
		driver.findElement(By.id("file-2")).click();

		// The download happens in a remote Node, which makes it difficult to know when the file
		// has been completely downloaded. For demonstration purposes, this example uses a
		// 10-second sleep which should be enough time for a file to be downloaded.
		// We strongly recommend to avoid hardcoded sleeps, and ideally, to modify your
		// application under test, so it offers a way to know when the file has been completely
		// downloaded.
		TimeUnit.SECONDS.sleep(10);

		//This is the endpoint which will provide us with list of files to download and also to
		//let us download a specific file.
		String downloadsEndpoint = String.format("/session/%s/se/files", driver.getSessionId());

		String fileToDownload;

		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To list all files that are were downloaded on the remote node for the current session
			// we trigger GET request.
			HttpRequest request = new HttpRequest(GET, downloadsEndpoint);
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			@SuppressWarnings("unchecked")
			List<String> names = (List<String>) value.get("names");
			// Let's say there were "n" files downloaded for the current session, we would like
			// to retrieve ONLY the first file.
			fileToDownload = names.get(0);
		}

		// Now, let's download the file
		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To retrieve a specific file from one or more files that were downloaded by the current session
			// on a remote node, we use a POST request.
			HttpRequest request = new HttpRequest(POST, downloadsEndpoint);
			request.setContent(asJson(ImmutableMap.of("name", fileToDownload)));
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			// The returned map would contain 2 keys,
			// filename - This represents the name of the file (same as what was provided by the test)
			// contents - Base64 encoded String which contains the zipped file.
			String zippedContents = value.get("contents").toString();
			// The file contents would always be a zip file and has to be unzipped.
			File downloadDir = Zip.unzipToTempDir(zippedContents, "download", "");
			// Read the file contents
			File downloadedFile = Optional.ofNullable(downloadDir.listFiles()).orElse(new File[]{})[0];
			String fileContent = String.join("", Files.readAllLines(downloadedFile.toPath()));
			System.out.println("The file which was "
					+ "downloaded in the node is now available in the directory: "
					+ downloadDir.getAbsolutePath() + " and has the contents: " + fileContent);
		}
	}


}
```

# 3 - Toml オプション

```toml
[section1]
option1="value"

[section2]
option2=["value1","value2"]
option3=true
```

TOML ファイルで設定された Grid コンポーネントを起動するには以下のように起動できます:

```
java -jar selenium-server-<version>.jar <component> --config /path/to/file/<file-name>.toml
```

### スタンドアロン

ポート 4449 で動作し、新規セッションリクエストのタイムアウトが 500 秒のスタンドアロンサーバー。

```toml
[server]
port = 4449

[sessionqueue]
session-request-timeout = 500
```

### 特定のブラウザとセッションの上限

Firefox と Chrome のみがデフォルトで有効になっているスタンドアロンサーバー、またはノード

```toml
[node]
drivers = ["chrome", "firefox"]
max-sessions = 3
```

### ドライバーのカスタマイズと設定

Firefox Beta や Nightly のような、異なるブラウザのバージョンを持つことができるカスタマイズされた ドライバを用いた、スタンドアロン、またはノード。

```toml
[node]
detect-drivers = false
[[node.driver-configuration]]
max-sessions = 100
display-name = "Firefox Nightly"
stereotype = "{\"browserName\": \"firefox\", \"browserVersion\": \"93\", \"platformName\": \"MAC\", \"moz:firefoxOptions\": {\"binary\": \"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"
[[node.driver-configuration]]
display-name = "Chrome Beta"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"94\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta\"}}"
[[node.driver-configuration]]
display-name = "Chrome Dev"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"95\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev\"}}"
webdriver-executable = '/path/to/chromedriver/95/chromedriver'
```

### Docker を利用したスタンドアロン、またはノード

Docker コンテナでセッションを実行できるスタンドアロン、またはノードサーバー。 ドライバを検出を無効にし、最大 2 つの同時セッションを持ちます。 ステレオタイプは、Docker イメージにマッピングされる必要があり、 Docker デーモンが http/tcp で公開されている必要があります。 また、`devices`プロパティを用いて、ホスト上でアクセス可能なデバイスファイルを、コンテナで利用できるようにすることも可能です。 Docker デバイスをマッピングする詳しい方法は[docker](https://docs.docker.com/engine/reference/commandline/run/#add-host-device-to-container---device) を参照してください。

```toml
[node]
detect-drivers = false
max-sessions = 2

[docker]
configs = [
    "selenium/standalone-chrome:93.0", "{\"browserName\": \"chrome\", \"browserVersion\": \"91\"}",
    "selenium/standalone-firefox:92.0", "{\"browserName\": \"firefox\", \"browserVersion\": \"92\"}"
]
#Optionally define all device files that should be mapped to docker containers
#devices = [
#    "/dev/kvm:/dev/kvm"
#]
url = "http://localhost:2375"
video-image = "selenium/video:latest"
```

### WebDriver をサポートするサービスエンドポイントへのコマンド中継

WebDriver をサポートする外部サービスを Selenium Grid に接続すると便利です。 例えばクラウドプロバイダーや Appium サーバーなどです。 Grid はローカルに存在しないプラットフォームやバージョンなどを幅広くカバーできるようになります。

以下は Appium サーバーを Grid に接続する例です。

```toml
[node]
detect-drivers = false

[relay]
# Default Appium/Cloud server endpoint
url = "http://localhost:4723/wd/hub"
status-endpoint = "/status"
# Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status (e.g. HTTP/1.1, HTTP/2)
protocol-version = "HTTP/1.1"
# Stereotypes supported by the service. The initial number is "max-sessions", and will allocate
# that many test slots to that particular configuration
configs = [
  "5", "{\"browserName\": \"chrome\", \"platformName\": \"android\", \"appium:platformVersion\": \"11\"}"
]
```

### Basic 認証の有効化

ルーター、ハブ、スタンドアロンにユーザー名とパスワードを設定することで、 Basic 認証で Grid を保護することができます。 このユーザーとパスワードは、Grid UI を読み込む時や 新しいセッションを開始する時に必要になります。

```toml
[router]
username = "admin"
password = "myStrongPassword"
```

Java でユーザーとパスワードを使ってセッションを開始する方法の例です。

```java
ClientConfig clientConfig = ClientConfig.defaultConfig()
  .baseUrl(new URL("http://localhost:4444"))
  .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"));
HttpCommandExecutor executor = new HttpCommandExecutor(clientConfig);
RemoteWebDriver driver = new RemoteWebDriver(executor, new ChromeOptions());
```

In other languages, you can use the URL http\://admin:myStrongPassword\@localhost:4444

### 特定のノードにマッチするカスタム capabilities の設定

**重要**: カスタム capabilities は全てのノードで設定する必要があります。 また全てのセッションリクエストで常に含まれる必要があります。

```toml
[node]
detect-drivers = false

[[node.driver-configuration]]
display-name = "firefox"
stereotype = '{"browserName": "firefox", "platformName": "macOS", "browserVersion":"96", "networkname:applicationName":"node_1", "nodename:applicationName":"app_1" }'
max-sessions = 5
```

Java でノードにマッチさせる方法の例です。

```java
FirefoxOptions options = new FirefoxOptions();
options.setCapability("networkname:applicationName", "node_1");
options.setCapability("nodename:applicationName", "app_1");
options.setBrowserVersion("96");
options.setPlatformName("macOS");
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

### Enabling Managed downloads by the Node.

The Node can be instructed to manage downloads automatically. This will cause the Node to save all files that were downloaded for a particular session into a temp directory, which can later be retrieved from the node. To turn this capability on, use the below configuration:

```toml
[node]
enable-managed-downloads = true
```

Refer to the [CLI section](https://www.selenium.dev/ja/documentation/grid/configuration/cli_options/#enabling-managed-downloads-by-the-node) for a complete example.

----
url: https://www.selenium.dev/documentation/webdriver/interactions/virtual_authenticator/
----

# Virtual Authenticator

```java
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L55-L61)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L48-55)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L40-L46)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setHasUserVerification(true);
    options.setIsUserConsenting(true);
    options.setTransport(Transport['USB']);
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    assert(Object.keys(options).length === 6);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticatorOptions.spec.js#L11-L17)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticatorOptions.spec.js

```js
const {VirtualAuthenticatorOptions, Transport, Protocol} = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')


describe('Virtual authenticator options', function () {
  let options;

  it('Virtual options', async function () {
    options = new VirtualAuthenticatorOptions();
    options.setIsUserVerified(true);
    options.setHasUserVerification(true);
    options.setIsUserConsenting(true);
    options.setTransport(Transport['USB']);
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    assert(Object.keys(options).length === 6);
  });

  it('User verified', async function () {
    options.setIsUserVerified(true);

    assert(options.toDict()['isUserVerified']);
  });
});
```

```java
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L68-L73)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L63-71)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L53-L58)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L51-L55)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L86)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#80-86)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L68-L74)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L62-L63)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L100-L103)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#103-107)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L89-L97)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L80-L94)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L143-L145)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L145-148)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L140-L147)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L136-L140)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L137-L146)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L139-150)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.add_credential(credential)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L150)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L131-L142)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L157-L171)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L162-178)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    credential_list = driver.get_credentials()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L183)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L154-L170)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L181-L190)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L189-198)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.remove_credential(credential.id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L209)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```java
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L196-L205)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L207-216)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.remove_all_credentials()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L239)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L181-L190)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L211-L212)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L224-225)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L245-L247)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setIsUserVerified(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L197-L197)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/discouraged/captchas/
----

# 验证码

验证码 (CAPTCHA), 是 *全自动区分计算机和人类的图灵测试* *(Completely Automated Public Turing test to tell Computers and Humans Apart)* 的简称, 是被明确地设计用于阻止自动化的, 所以不要尝试!\
规避验证码的检查, 主要有两个策略:

* 在测试环境中禁用验证码
* 添加钩子以允许测试绕过验证码

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/encouraged/mock_external_services/
----

# 模拟外部服务

消除对外部服务的依赖性将大大提高测试的速度和稳定性.

----
url: https://www.selenium.dev/ja/documentation/legacy/selenium_3/grid_components/
----

# グリッドのコンポーネント

----
url: https://www.selenium.dev/documentation/grid/advanced_features/graphql_support/
----

# GraphQL query support

```shell
{
    session(id: "<session-id>") : {
        id,
        capabilities,
        startTime,
        uri,
        nodeId,
        nodeUri,
        sessionDurationMillis
        slot : {
            id,
            stereotype,
            lastStarted
        }
    }
    grid: {
        uri,
        totalSlots,
        nodeCount,
        maxSession,
        sessionCount,
        version,
        sessionQueueSize
    }
    sessionsInfo: {
        sessionQueueRequests,
        sessions: [
            {
                id,
                capabilities,
                startTime,
                uri,
                nodeId,
                nodeUri,
                sessionDurationMillis
                slot : {
                    id,
                    stereotype,
                    lastStarted
                }
            }
        ]
    }
    nodesInfo: {
        nodes : [
            {
                id,
                uri,
                status,
                maxSession,
                slotCount,
                sessions: [
                    {
                        id,
                        capabilities,
                        startTime,
                        uri,
                        nodeId,
                        nodeUri,
                        sessionDurationMillis
                        slot : {
                            id,
                            stereotype,
                            lastStarted
                        }
                    }
                ],
                sessionCount,
                stereotypes,
                version,
                osInfo: {
                    arch,
                    name,
                    version
                }
            }
        ]
    }
}
```

## Querying GraphQL

The best way to query GraphQL is by using `curl` requests. The query is interpreted as JSON. Ensure double quotes are properly escaped to avoid unexpected errors. GraphQL allows you to fetch only the data that you want, nothing more nothing less.

Some of the example GraphQL queries are given below. You can build your own queries as you like.

### Querying the number of `maxSession` and `sessionCount` in the grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ grid { maxSession, sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

Generally on local machine the `<LINK_TO_GRAPHQL_ENDPOINT>` would be `http://localhost:4444/graphql`

### Querying all details for session, node and the Grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { uri, maxSession, sessionCount }, nodesInfo { nodes { id, uri, status, sessions { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } }, slotCount, sessionCount }} }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the current session count in the Grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the max session count in the Grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { maxSession } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting all session details for all nodes in the Grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, capabilities, startTime, uri, nodeId, nodeId, sessionDurationMillis } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query to get slot information for all sessions in each Node in the Grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, slot { id, stereotype, lastStarted } } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query to get session information for a given session:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ session (id: \"<session-id>\") { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } } } "}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Querying the capabilities of each node in the grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { stereotypes } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Querying the status of each node in the grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { status } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Querying the URI of each node and the grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { uri } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the current requests in the New Session Queue:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessionQueueRequests } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the New Session Queue size :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionQueueSize } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

Last modified January 24, 2022: [Properly parse quotes for GraphQl query's session id (#941) \[deploy site\] (548fa83a491)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/548fa83a491330341485e5667d5053743f8e313c)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/elements/
----

# Elemento Web

Identificando e trabalhando com elementos no DOM.

A maioria do código que é escrito recorrendo às bibliotecas Selenium envolve trabalhar com elementos.

***

##### [Encontrando Elementos Web](/pt-br/documentation/webdriver/elements/finders/)

Localizando elementos com base nos valores providenciados pelo localizador.

##### [Interacting with web elements](/pt-br/documentation/webdriver/elements/interactions/)

A high-level instruction set for manipulating form controls.

##### [Information about web elements](/pt-br/documentation/webdriver/elements/information/)

What you can learn about an element.

##### [Localizando elementos](/pt-br/documentation/webdriver/elements/locators/)

Formas de identificar um ou mais elementos no DOM.

##### [File Upload](/pt-br/documentation/webdriver/elements/file_upload/)

Como subir arquivos com Selenium

Última modificação April 4, 2023: [Updated PT translation for elements (wip)\[deploy site\] (42a6cc67d41)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/42a6cc67d419258a4de4079fd615447e5d3d69b0)

----
url: https://www.selenium.dev/pt-br/documentation/grid/components/
----

# Componentes

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/elements/file_upload/
----

# 文件上传

```java
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/FileUploadTest.java#L17-L19)

##### /examples/java/src/test/java/dev/selenium/elements/FileUploadTest.java

```java
package dev.selenium.elements;

import dev.selenium.BaseChromeTest;
import java.io.File;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

public class FileUploadTest extends BaseChromeTest {

  @Test
  public void fileUploadTest() {
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }
}
```

```py
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_file_upload.py#L12-L14)

##### /examples/python/tests/elements/test\_file\_upload.py

```py
import os

from selenium import webdriver
from selenium.webdriver.common.by import By


def test_uploads(driver):
    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"
```

```cs
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/FileUploadTest.cs#L21-L23)

##### /examples/dotnet/SeleniumDocs/Elements/FileUploadTest.cs

```cs
using System;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;

namespace SeleniumDocs.Elements
{
    [TestClass]
    public class FileUploadTest : BaseChromeTest
    {
        [TestMethod]
        public void Uploads()
        {
            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }
    }
}
```

```rb
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/file_upload_spec.rb#L12-L14)

##### /examples/ruby/spec/elements/file\_upload\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'File Upload' do
  let(:driver) { start_session }

  it 'uploads' do
    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    file_name = driver.find_element(id: 'uploaded-files')
    expect(file_name.text).to eq 'selenium-snapshot.png'
  end
end
```

```js
    await driver.get('https://the-internet.herokuapp.com/upload');
    // Upload snapshot
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/fileUpload.spec.js#L24-L25)

##### /examples/javascript/test/elements/fileUpload.spec.js

```js

const {Browser, By, until, Builder} = require("selenium-webdriver");
const path = require("path");
const assert = require('node:assert');


describe('File Upload Test', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async() => await driver.quit());

  it('Should be able to upload a file successfully', async function() {
    const image = path.resolve('./test/resources/selenium-snapshot.png')

    await driver.manage().setTimeouts({implicit: 5000});

    // Navigate to URL
    await driver.get('https://the-internet.herokuapp.com/upload');
    // Upload snapshot
    await driver.findElement(By.id("file-upload")).sendKeys(image);
    await driver.findElement(By.id("file-submit")).submit();

    const revealed = await driver.findElement(By.id('uploaded-files'))
    await driver.wait(until.elementIsVisible(revealed), 2000);
    const data = await driver.findElement(By.css('h3'));

    assert.equal(await data.getText(), `File Uploaded!`);
  });
});
```

[Move Code](/documentation/about/contributing/#moving-examples)

\`\`\`java import org.openqa.selenium.By import org.openqa.selenium.chrome.ChromeDriver fun main() { val driver = ChromeDriver() driver.get("https\://the-internet.herokuapp.com/upload") driver.findElement(By.id("file-upload")).sendKeys("selenium-snapshot.jpg") driver.findElement(By.id("file-submit")).submit() if(driver.pageSource.contains("File Uploaded!")) { println("file uploaded") } else{ println("file not uploaded") } } \`\`\`

最后修改 October 30, 2025: [modified link weight for file upload to come in logical order for element (#2491) (f297c0685df)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/f297c0685df60e4c7aaebca746612ee8c659a886)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/bidi/w3c/network/
----

# Network

```java
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L36-L38)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    assert.notEqual(intercept, null)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L29)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L46-L50)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L34-L35)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                    responseDetails ->
                            network.continueWithAuth(
                                    responseDetails.getRequest().getRequestId(),
                                    new UsernameAndPassword("admin", "admin")));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L57-L64)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L42-L46)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                            // Does not handle the alert
                            network.continueWithAuthNoCredentials(responseDetails.getRequest().getRequestId()));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L74-L80)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L56-L60)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                            network.cancelAuth(responseDetails.getRequest().getRequestId()));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L90-L96)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L71-L75)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
            }
    }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L104-L108)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L30-L35)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L23-L29)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L45-L51)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L82-L88)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L62-L68)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L96-L102)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L101-L106)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

最后修改 May 27, 2025: [Update dependency selenium-webdriver to v4.33.0 (#2316) (5f5285aba17)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/5f5285aba177977a839ac8377929dc999623a4bb)

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/discouraged/two_factor_authentication/
----

# 双因素认证

双因素认证通常简写成 *2FA* 是一种一次性密码（OTP）通常用在移动应用上例如“谷歌认证器”， “微软认证器”等等，或者通过短信或者邮件来认证。在Selenium自动化中这些都是影响有效自动化 的极大挑战。虽然也有一些方法可以自动化这些过程，但是同样对于Selenium自动化也引入了很多不安全因素。 所以你应该要避免对2FA自动化。

这里有一些对于如何绕过2FA校验的建议：

* 在测试环境中对特定用户禁止2FA校验，这样对于这些特定用户可以直接进行自动化测试。
* 禁止2FA校验在测试环境中。
* 对于特定IP区域禁止2FA校验，这样我们可以配置测试机器的IP在这些白名单区域中。

----
url: https://www.selenium.dev/ja/documentation/webdriver/waits/
----

# 待機

Perhaps the most common challenge for browser automation is ensuring that the web application is in a state to execute a particular Selenium command as desired. The processes often end up in a *race condition* where sometimes the browser gets into the right state first (things work as intended) and sometimes the Selenium code executes first (things do not work as intended). This is one of the primary causes of *flaky tests*.

All navigation commands wait for a specific `readyState` value based on the [page load strategy](https://www.selenium.dev/ja/documentation/webdriver/drivers/options/#pageloadstrategy) (the default value to wait for is `"complete"`) before the driver returns control to the code. The `readyState` only concerns itself with loading assets defined in the HTML, but loaded JavaScript assets often result in changes to the site, and elements that need to be interacted with may not yet be on the page when the code is ready to execute the next Selenium command.

Similarly, in a lot of single page applications, elements get dynamically added to a page or change visibility based on a click. An element must be both present and [displayed](https://www.selenium.dev/ja/documentation/webdriver/elements/information/#is-displayed) on the page in order for Selenium to interact with it.

Take this page for example: <https://www.selenium.dev/selenium/web/dynamic.html> When the “Add a box!” button is clicked, a “div” element that does not exist is created. When the “Reveal a new input” button is clicked, a hidden text field element is displayed. In both cases the transition takes a couple seconds. If the Selenium code is to click one of these buttons and interact with the resulting element, it will do so before that element is ready and fail.

The first solution many people turn to is adding a sleep statement to pause the code execution for a set period of time. Because the code can’t know exactly how long it needs to wait, this can fail when it doesn’t sleep long enough. Alternately, if the value is set too high and a sleep statement is added in every place it is needed, the duration of the session can become prohibitive.

Selenium provides two different mechanisms for synchronization that are better.

## Implicit waits

Selenium has a built-in way to automatically wait for elements called an *implicit wait*. An implicit wait value can be set either with the [timeouts](https://www.selenium.dev/ja/documentation/webdriver/drivers/options/#timeouts) capability in the browser options, or with a driver method (as shown below).

```java
    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L50)

##### /examples/java/src/test/java/dev/selenium/waits/WaitsTest.java

```java
package dev.selenium.waits;

import dev.selenium.BaseTest;
import java.time.Duration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.ElementNotInteractableException;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

public class WaitsTest extends BaseTest {
  @Test
  public void fails() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Assertions.assertThrows(
        NoSuchElementException.class,
        () -> {
          driver.findElement(By.id("box0"));
        });
  }

  @Test
  public void sleep() throws InterruptedException {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Thread.sleep(1000);

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void implicit() {
    startChromeDriver(new ChromeOptions());

    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void explicit() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    wait.until(d -> revealed.isDisplayed());

    revealed.sendKeys("Displayed");
    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }

  @Test
  public void explicitWithOptions() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait =
        new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(2))
            .pollingEvery(Duration.ofMillis(300))
            .ignoring(ElementNotInteractableException.class);

    wait.until(
        d -> {
          revealed.sendKeys("Displayed");
          return true;
        });

    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }
}
```

```py
    driver.implicitly_wait(2)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/waits/test_waits.py#L27)

##### /examples/python/tests/waits/test\_waits.py

```py
import pytest
import time
from selenium.common import NoSuchElementException, ElementNotInteractableException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


def test_fails(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    with pytest.raises(NoSuchElementException):
        driver.find_element(By.ID, 'box0')


def test_sleep(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    time.sleep(2)
    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_implicit(driver):
    driver.implicitly_wait(2)
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_explicit(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(lambda _ : revealed.is_displayed())

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"


def test_explicit_options(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    errors = [NoSuchElementException, ElementNotInteractableException]
    wait = WebDriverWait(driver, timeout=2, poll_frequency=.2, ignored_exceptions=errors)
    wait.until(lambda _ : revealed.send_keys("Displayed") or True)

    assert revealed.get_property("value") == "Displayed"
```

```cs
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L39)

##### /examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs

```cs
using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Waits
{
    [TestClass]
    public class WaitsTest : BaseChromeTest
    {
        [TestMethod]
        public void Fails()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Assert.ThrowsException<NoSuchElementException>(
                () => driver.FindElement(By.Id("box0"))
            );
        }

        [TestMethod]
        public void Sleep()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Thread.Sleep(1000);

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Implicit()
        {
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
            
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Explicit()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2));
            wait.Until(d => revealed.Displayed);

            revealed.SendKeys("Displayed");
            Assert.AreEqual("Displayed", revealed.GetDomProperty("value"));
        }

        [TestMethod]
        public void ExplicitOptions()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2))
            {
                PollingInterval = TimeSpan.FromMilliseconds(300),
            };
            wait.IgnoreExceptionTypes(typeof(ElementNotInteractableException));

            wait.Until(d => {
                revealed.SendKeys("Displayed");
                return true;
            });

            Assert.AreEqual("input", revealed.TagName);
        }
    }
}
```

```rb
    driver.manage.timeouts.implicit_wait = 2
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/waits/waits_spec.rb#L28)

##### /examples/ruby/spec/waits/waits\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Waits' do
  let(:driver) { start_session }

  it 'fails' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    expect {
      driver.find_element(id: 'box0')
    }.to raise_error(Selenium::WebDriver::Error::NoSuchElementError)
  end

  it 'sleeps' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    sleep 1
    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'implicit' do
    driver.manage.timeouts.implicit_wait = 2
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    wait = Selenium::WebDriver::Wait.new
    wait.until { revealed.displayed? }

    revealed.send_keys('Displayed')
    expect(revealed.property(:value)).to eq('Displayed')
  end

  it 'options with explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    errors = [Selenium::WebDriver::Error::NoSuchElementError,
              Selenium::WebDriver::Error::ElementNotInteractableError]
    wait = Selenium::WebDriver::Wait.new(timeout: 2,
                                         interval: 0.3,
                                         ignore: errors)

    wait.until { revealed.send_keys('Displayed') || true }

    expect(revealed.property(:value)).to eq('Displayed')
  end
end
```

```js
        await driver.manage().setTimeouts({ implicit: 2000 });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/waits/waits.spec.js#L39)

##### /examples/javascript/test/waits/waits.spec.js

```js

const { By, Browser, until, Builder} = require('selenium-webdriver');
const assert = require("node:assert");


describe('Waits', function () {
    let driver;

    before(async function () {
        driver = new Builder()
          .forBrowser(Browser.CHROME)
          .build();
    });

    after(async () => await driver.quit());

    it('fail', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        await assert.rejects(async () => {
              await driver.findElement(By.id("box0"))
          },
          Error
        )
    });

    it('sleep', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        await driver.sleep(2000);
        let added = await driver.findElement(By.id("box0"));

        assert.equal(await added.getAttribute('class'), "redbox")
    });

    it('implicit', async function () {
        await driver.manage().setTimeouts({ implicit: 2000 });
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        let added = await driver.findElement(By.id("box0"));

        assert.equal(await added.getAttribute('class'), "redbox")
    });

    it('explicit', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        let revealed = await driver.findElement(By.id("revealed"));
        await driver.findElement(By.id("reveal")).click();
        await driver.wait(until.elementIsVisible(revealed), 2000);
        await revealed.sendKeys("Displayed");
        assert.equal(await revealed.getAttribute("value"), "Displayed")
    })
});
```

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk/examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt#L19)

##### examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt

```kt
```

This example shows the condition being waited for as a *lambda*. Java also supports [Expected Conditions](https://www.selenium.dev/ja/documentation/webdriver/support_features/expected_conditions/)

```java
    Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    wait.until(d -> revealed.isDisplayed());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L67-L68)

##### /examples/java/src/test/java/dev/selenium/waits/WaitsTest.java

```java
package dev.selenium.waits;

import dev.selenium.BaseTest;
import java.time.Duration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.ElementNotInteractableException;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

public class WaitsTest extends BaseTest {
  @Test
  public void fails() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Assertions.assertThrows(
        NoSuchElementException.class,
        () -> {
          driver.findElement(By.id("box0"));
        });
  }

  @Test
  public void sleep() throws InterruptedException {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Thread.sleep(1000);

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void implicit() {
    startChromeDriver(new ChromeOptions());

    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void explicit() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    wait.until(d -> revealed.isDisplayed());

    revealed.sendKeys("Displayed");
    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }

  @Test
  public void explicitWithOptions() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait =
        new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(2))
            .pollingEvery(Duration.ofMillis(300))
            .ignoring(ElementNotInteractableException.class);

    wait.until(
        d -> {
          revealed.sendKeys("Displayed");
          return true;
        });

    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }
}
```

This example shows the condition being waited for as a *lambda*. Python also supports [Expected Conditions](https://www.selenium.dev/ja/documentation/webdriver/support_features/expected_conditions/)

```py
    wait = WebDriverWait(driver, timeout=2)
    wait.until(lambda _ : revealed.is_displayed())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/waits/test_waits.py#L41-L42)

##### /examples/python/tests/waits/test\_waits.py

```py
import pytest
import time
from selenium.common import NoSuchElementException, ElementNotInteractableException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


def test_fails(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    with pytest.raises(NoSuchElementException):
        driver.find_element(By.ID, 'box0')


def test_sleep(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    time.sleep(2)
    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_implicit(driver):
    driver.implicitly_wait(2)
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_explicit(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(lambda _ : revealed.is_displayed())

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"


def test_explicit_options(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    errors = [NoSuchElementException, ElementNotInteractableException]
    wait = WebDriverWait(driver, timeout=2, poll_frequency=.2, ignored_exceptions=errors)
    wait.until(lambda _ : revealed.send_keys("Displayed") or True)

    assert revealed.get_property("value") == "Displayed"
```

```cs
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2));
            wait.Until(d => revealed.Displayed);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L56-L57)

##### /examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs

```cs
using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Waits
{
    [TestClass]
    public class WaitsTest : BaseChromeTest
    {
        [TestMethod]
        public void Fails()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Assert.ThrowsException<NoSuchElementException>(
                () => driver.FindElement(By.Id("box0"))
            );
        }

        [TestMethod]
        public void Sleep()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Thread.Sleep(1000);

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Implicit()
        {
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
            
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Explicit()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2));
            wait.Until(d => revealed.Displayed);

            revealed.SendKeys("Displayed");
            Assert.AreEqual("Displayed", revealed.GetDomProperty("value"));
        }

        [TestMethod]
        public void ExplicitOptions()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2))
            {
                PollingInterval = TimeSpan.FromMilliseconds(300),
            };
            wait.IgnoreExceptionTypes(typeof(ElementNotInteractableException));

            wait.Until(d => {
                revealed.SendKeys("Displayed");
                return true;
            });

            Assert.AreEqual("input", revealed.TagName);
        }
    }
}
```

```rb
    wait = Selenium::WebDriver::Wait.new
    wait.until { revealed.displayed? }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/waits/waits_spec.rb#L42-L43)

##### /examples/ruby/spec/waits/waits\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Waits' do
  let(:driver) { start_session }

  it 'fails' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    expect {
      driver.find_element(id: 'box0')
    }.to raise_error(Selenium::WebDriver::Error::NoSuchElementError)
  end

  it 'sleeps' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    sleep 1
    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'implicit' do
    driver.manage.timeouts.implicit_wait = 2
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    wait = Selenium::WebDriver::Wait.new
    wait.until { revealed.displayed? }

    revealed.send_keys('Displayed')
    expect(revealed.property(:value)).to eq('Displayed')
  end

  it 'options with explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    errors = [Selenium::WebDriver::Error::NoSuchElementError,
              Selenium::WebDriver::Error::ElementNotInteractableError]
    wait = Selenium::WebDriver::Wait.new(timeout: 2,
                                         interval: 0.3,
                                         ignore: errors)

    wait.until { revealed.send_keys('Displayed') || true }

    expect(revealed.property(:value)).to eq('Displayed')
  end
end
```

JavaScript also supports [Expected Conditions](https://www.selenium.dev/ja/documentation/webdriver/support_features/expected_conditions/)

```js
        await driver.wait(until.elementIsVisible(revealed), 2000);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/waits/waits.spec.js#L52)

##### /examples/javascript/test/waits/waits.spec.js

```js

const { By, Browser, until, Builder} = require('selenium-webdriver');
const assert = require("node:assert");


describe('Waits', function () {
    let driver;

    before(async function () {
        driver = new Builder()
          .forBrowser(Browser.CHROME)
          .build();
    });

    after(async () => await driver.quit());

    it('fail', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        await assert.rejects(async () => {
              await driver.findElement(By.id("box0"))
          },
          Error
        )
    });

    it('sleep', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        await driver.sleep(2000);
        let added = await driver.findElement(By.id("box0"));

        assert.equal(await added.getAttribute('class'), "redbox")
    });

    it('implicit', async function () {
        await driver.manage().setTimeouts({ implicit: 2000 });
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        let added = await driver.findElement(By.id("box0"));

        assert.equal(await added.getAttribute('class'), "redbox")
    });

    it('explicit', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        let revealed = await driver.findElement(By.id("revealed"));
        await driver.findElement(By.id("reveal")).click();
        await driver.wait(until.elementIsVisible(revealed), 2000);
        await revealed.sendKeys("Displayed");
        assert.equal(await revealed.getAttribute("value"), "Displayed")
    })
});
```

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk/examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt#L36-L37)

##### examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt

```kt
```

```java
    Wait<WebDriver> wait =
        new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(2))
            .pollingEvery(Duration.ofMillis(300))
            .ignoring(ElementNotInteractableException.class);

    wait.until(
        d -> {
          revealed.sendKeys("Displayed");
          return true;
        });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L82-L92)

##### /examples/java/src/test/java/dev/selenium/waits/WaitsTest.java

```java
package dev.selenium.waits;

import dev.selenium.BaseTest;
import java.time.Duration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.ElementNotInteractableException;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

public class WaitsTest extends BaseTest {
  @Test
  public void fails() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Assertions.assertThrows(
        NoSuchElementException.class,
        () -> {
          driver.findElement(By.id("box0"));
        });
  }

  @Test
  public void sleep() throws InterruptedException {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Thread.sleep(1000);

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void implicit() {
    startChromeDriver(new ChromeOptions());

    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void explicit() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    wait.until(d -> revealed.isDisplayed());

    revealed.sendKeys("Displayed");
    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }

  @Test
  public void explicitWithOptions() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait =
        new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(2))
            .pollingEvery(Duration.ofMillis(300))
            .ignoring(ElementNotInteractableException.class);

    wait.until(
        d -> {
          revealed.sendKeys("Displayed");
          return true;
        });

    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }
}
```

```py
    errors = [NoSuchElementException, ElementNotInteractableException]
    wait = WebDriverWait(driver, timeout=2, poll_frequency=.2, ignored_exceptions=errors)
    wait.until(lambda _ : revealed.send_keys("Displayed") or True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/waits/test_waits.py#L53-L55)

##### /examples/python/tests/waits/test\_waits.py

```py
import pytest
import time
from selenium.common import NoSuchElementException, ElementNotInteractableException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


def test_fails(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    with pytest.raises(NoSuchElementException):
        driver.find_element(By.ID, 'box0')


def test_sleep(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    time.sleep(2)
    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_implicit(driver):
    driver.implicitly_wait(2)
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_explicit(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(lambda _ : revealed.is_displayed())

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"


def test_explicit_options(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    errors = [NoSuchElementException, ElementNotInteractableException]
    wait = WebDriverWait(driver, timeout=2, poll_frequency=.2, ignored_exceptions=errors)
    wait.until(lambda _ : revealed.send_keys("Displayed") or True)

    assert revealed.get_property("value") == "Displayed"
```

```cs
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2))
            {
                PollingInterval = TimeSpan.FromMilliseconds(300),
            };
            wait.IgnoreExceptionTypes(typeof(ElementNotInteractableException));

            wait.Until(d => {
                revealed.SendKeys("Displayed");
                return true;
            });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L70-L79)

##### /examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs

```cs
using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Waits
{
    [TestClass]
    public class WaitsTest : BaseChromeTest
    {
        [TestMethod]
        public void Fails()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Assert.ThrowsException<NoSuchElementException>(
                () => driver.FindElement(By.Id("box0"))
            );
        }

        [TestMethod]
        public void Sleep()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Thread.Sleep(1000);

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Implicit()
        {
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
            
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Explicit()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2));
            wait.Until(d => revealed.Displayed);

            revealed.SendKeys("Displayed");
            Assert.AreEqual("Displayed", revealed.GetDomProperty("value"));
        }

        [TestMethod]
        public void ExplicitOptions()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2))
            {
                PollingInterval = TimeSpan.FromMilliseconds(300),
            };
            wait.IgnoreExceptionTypes(typeof(ElementNotInteractableException));

            wait.Until(d => {
                revealed.SendKeys("Displayed");
                return true;
            });

            Assert.AreEqual("input", revealed.TagName);
        }
    }
}
```

```rb
    errors = [Selenium::WebDriver::Error::NoSuchElementError,
              Selenium::WebDriver::Error::ElementNotInteractableError]
    wait = Selenium::WebDriver::Wait.new(timeout: 2,
                                         interval: 0.3,
                                         ignore: errors)

    wait.until { revealed.send_keys('Displayed') || true }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/waits/waits_spec.rb#L54-L60)

##### /examples/ruby/spec/waits/waits\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Waits' do
  let(:driver) { start_session }

  it 'fails' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    expect {
      driver.find_element(id: 'box0')
    }.to raise_error(Selenium::WebDriver::Error::NoSuchElementError)
  end

  it 'sleeps' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    sleep 1
    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'implicit' do
    driver.manage.timeouts.implicit_wait = 2
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    wait = Selenium::WebDriver::Wait.new
    wait.until { revealed.displayed? }

    revealed.send_keys('Displayed')
    expect(revealed.property(:value)).to eq('Displayed')
  end

  it 'options with explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    errors = [Selenium::WebDriver::Error::NoSuchElementError,
              Selenium::WebDriver::Error::ElementNotInteractableError]
    wait = Selenium::WebDriver::Wait.new(timeout: 2,
                                         interval: 0.3,
                                         ignore: errors)

    wait.until { revealed.send_keys('Displayed') || true }

    expect(revealed.property(:value)).to eq('Displayed')
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk/examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt#L51-L60)

##### examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt

```kt
```

最終更新 October 31, 2025: [Added Kotlin Code Examples (#2499) (e49b07e4f68)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e49b07e4f68275d61faff820b9b2b640e9d16fb3)

----
url: https://www.selenium.dev/pt-br/_print/documentation/grid/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/grid/).

# Grid

Pretende executar testes em paralelo em várias máquinas? Então a Grid é para si.

* 1: [Configurando a sua](#pg-75ab41fb11e05c56b77cec734372ce26)
* 2: [Quando usar a Grid](#pg-473c3ba9a1648a779746261bd023b3f4)
* 3: [Componentes](#pg-b523d0ca8ce055224f37be89f8083fc0)
* 4: [Configurando componentes](#pg-b1c6192513676fb6014aaa94cca41a86)
* * 4.1: [Ajuda de configuração](#pg-87c07f7cc7b198a46952084fd2e170cb)
  * 4.2: [Opções CLI](#pg-fb1445fa9df303a9961b39fa99116b7a)
  * 4.3: [Toml Options](#pg-b112688e72f40f34b417d747cee9d825)
  5: [Arquitectura da Grid](#pg-cf345e864afd2cccb282c4c5d3e03055)
* 6: [Características avançadas](#pg-0a55bd7bbf52302fce2db52de9355fdd)
  * 6.1: [Observabilidade](#pg-0559dcb12b1e3ebb50211585a83e0be8)
  * 6.2: [Suporte a buscas em GraphQL](#pg-2c82ff996091dc1dd2f15b718d6b1ede)
  * 6.3: [Rotas da Grid](#pg-d2d54c4f08eb016972465f2a03ead126)
  * 6.4: [Personalizando um Nó](#pg-f1b80d80b2bcdc1e194f0d4fc033093e)
  * 6.5: [External datastore](#pg-538b88406bce5817973473bd612380c3)

Selenium Grid permite a execucão de scripts WebDriver em máquinas remotas, passando os comandos recebidos pelo cliente para a instância remotas do navegador.

O objectivo da Grid é:

* Providenciar uma forma fácil de executar testes em paralelo em multiplas máquinas
* Permitir testes em versões diferentes de navegadores
* Permitir testes em várias plataformas

Está interessado? Enão siga lendo as próximas secções para entender como a Grid funciona e também como montar a sua.

# 1 - Configurando a sua

Instruções para criar uma Selenium Grid simples

## Início rápido

1. Pré-requisitos

   * Java 11 ou superior instalado

   * Navegador(es) instalados

   * Drivers do(s) navegador(es)

     * [Selenium Manager](https://www.selenium.dev/pt-br/documentation/selenium_manager/) will configure the drivers automatically if you add `--selenium-manager true`.
     * [Installed and on the `PATH`](https://www.selenium.dev/pt-br/documentation/webdriver/troubleshooting/errors/driver_location/#use-the-path-environment-variable)

```shell
java -jar selenium-server-<version>.jar standalone
```

```shell
java -jar selenium-server-<version>.jar hub
```

Por omissão, o servidor irá estar à escuta por pedidos de sessão `RemoteWebDriver` em <http://localhost:4444>.

#### Node

Ao iniciar, o **Node** irá detectar os drivers disponíveis através do [`PATH`](https://www.selenium.dev/pt-br/documentation/webdriver/troubleshooting/errors/driver_location/#3-a-variável-de-ambiente--path).

O comando exemplo seguinte assume que o **Node** está a executar na mesma máquina onde o **Hub** está em execução.

```shell
java -jar selenium-server-<version>.jar node
```

##### Mais do que um Node na mesma máquina

**Node** 1

```shell
java -jar selenium-server-<version>.jar node --port 5555
```

**Node** 2

```shell
java -jar selenium-server-<version>.jar node --port 6666
```

##### Node e Hub em máquinas diferentes

A comunicação entre **Hub** e **Nodes** ocorre via HTTP. Para iniciar o processo de registo, o **Node** envia uma mensagem para o **Hub** através do [**Event Bus**](https://www.selenium.dev/pt-br/documentation/grid/components/#event-bus) (o **Event Bus** reside dentro do **Hub**). Quando o **Hub** recebe a mensagem, tenta comunicar com o **Node** para confirmar a sua existencia.

Para que um **Node** se consiga registar no **Hub**, é importante que as portas do **Event Bus** sejam expostas na máquina **Hub**. As portas por omissão são 4442 e 4443 para o **Event Bus** e 4444 para o **Hub**.

Se o **Hub** estiver a usar as portas por omissão, pode usar a flag `--hub` para registar o **Node**

```shell
java -jar selenium-server-<version>.jar node --hub http://<hub-ip>:4444
```

Quando o **Hub** não estiver a usar as portas por omissão, necessita usar as flags`--publish-events` e `--subscribe-events`.

Por exemplo, se o **Hub** usar as portas`8886`, `8887`, e `8888`

```shell
java -jar selenium-server-<version>.jar hub --publish-events tcp://<hub-ip>:8886 --subscribe-events tcp://<hub-ip>:8887 --port 8888
```

O **Node** necessita de especificar as portas para conseguir registar-se com sucesso

```shell
java -jar selenium-server-<version>.jar node --publish-events tcp://<hub-ip>:8886 --subscribe-events tcp://<hub-ip>:8887
```

### Distribuida

Quando usar uma Grid distribuida, cada componente é iniciado separadamente e preferencialmente em máquinas diferentes.

É de extrema importância expor todas as portas necessárias de forma a que a comunicação flua correctamente entre todos os componentes.

1. **Event Bus**: permite comunicação interna entre os diferentes componentes da Grid.

As portas por omissão são: `4442`, `4443`, and `5557`.

```shell
java -jar selenium-server-<version>.jar event-bus --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --port 5557
```

2. **New Session Queue**: adiciona novos pedidos de sessão a uma queue, que serão consultadas pelo Distributor

A porta por omissão é `5559`.

```shell
java -jar selenium-server-<version>.jar sessionqueue --port 5559
```

3. **Session Map**: estabelece um mapa entre id de sessão e o **Node** onde a sessão está a executar

A porta por omissão é `5556`. **Session Map** interage com o **Event Bus**.

```shell
java -jar selenium-server-<version>.jar sessions --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --port 5556
```

4. **Distributor**: consulta **New Session Queue** para novos pedidos de sessão, que entrega ao um **Node** quando encontra um capacidade correspondente. **Nodes** registam-se no **Distributor** da mesma forma como numa Grid do tipo **Hub/Node**.

A porta por omissão é `5553`. **Distributor** interage com **New Session Queue**, **Session Map**, **Event Bus**, e **Node(s)**.

```shell
java -jar selenium-server-<version>.jar distributor --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --sessions http://<sessions-ip>:5556 --sessionqueue http://<new-session-queue-ip>:5559 --port 5553 --bind-bus false
```

5. **Router**: redirecciona novos pedidos de sessão para a queue, e redirecciona pedidos de sessões para o **Node** que estiver a executar a sessão.

A porta por omissão é `4444`. **Router** interage com **New Session Queue**, **Session Map**, e **Distributor**.

```shell
java -jar selenium-server-<version>.jar router --sessions http://<sessions-ip>:5556 --distributor http://<distributor-ip>:5553 --sessionqueue http://<new-session-queue-ip>:5559 --port 4444
```

6. **Node(s)**

A porta por omissão é `5555`.

```shell
java -jar selenium-server-<version>.jar node --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443
```

## Adicionar Metadata nos testes

Adicione Metadata aos testes, através de [GraphQL](https://www.selenium.dev/pt-br/documentation/grid/advanced_features/graphql_support/) ou visualize parcialmente (como `se:name`) através da Selenium Grid UI.

Metadata pode ser adicionada como uma capacidade com o prefixo `se:`. Eis um pequeno exemplo em Java.

```java
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setCapability("browserVersion", "100");
chromeOptions.setCapability("platformName", "Windows");
// Mostrando na Grid UI o nome de um teste ao invés de uma session id
chromeOptions.setCapability("se:name", "My simple test"); 
// Outros tipos de metadara podem ser visualizados na Grid UI 
// ao clicar na informação de sessão ou via GraphQL
chromeOptions.setCapability("se:sampleMetadata", "Valor exemplo de Metadata"); 
WebDriver driver = new RemoteWebDriver(new URL("http://gridUrl:4444"), chromeOptions);
driver.get("http://www.google.com");
driver.quit();
```

```bash
java -Dwebdriver.http.factory=jdk-http-client -jar selenium-server-<version>.jar --ext selenium-http-jdk-client-<version>.jar standalone
```

Uma alternativa a baixar o ficheiro jar `selenium-http-jdk-client` é usar [Coursier](https://get-coursier.io/docs/cli-installation).

```bash
java -Dwebdriver.http.factory=jdk-http-client -jar selenium-server-<version>.jar --ext $(coursier fetch -p org.seleniumhq.selenium:selenium-http-jdk-client:<version>) standalone
```

# 2 - Quando usar a Grid

```
   15      *       45s        /        1        =      11m 15s   // Sem Grid
   15      *       45s        /        5        =      2m 15s    // Grid com 5 Nodes
   15      *       45s        /        15       =      45s       // Grid com 15 Nodes
  100      *       120s       /        15       =      13m 20s   // Demoraria mais de 3 horas sem Grid
```

À medida que a bateria de testes executa, a Grid vai alocando os testes contra estes navegadores como está definido nos testes.

Uma configuração deste tipo pode acelerar bastante o tempo de execução mesmo no caso de baterias de testes grandes.

A Selenium Grid é uma parte integrante do projecto Selenium e é mantida em paralelo pela mesma equipa de developers que desenvolvem o resto das funcionalidades base do projecto. Dada a importância da velocidade e desempenho da execução dos testes, a Grid tem sido considerada desde o início como uma parte crítica e fundamental ao projecto.

# 3 - Componentes

# 4 - Configurando componentes

Leia aqui como pode configurar cada um dos componentes Grid com base em valores comuns ou específicos para o componente.

# 4.1 - Ajuda de configuração

```shell
java -jar selenium-server-<version>.jar info config
```

### Segurança

Para obter detalhes em como configurar os servidores Grid para comunicação segura e para o registo de **Nodes**:

```shell
java -jar selenium-server-<version>.jar info security
```

### Configuração Session Map

Por omissão, a Grid usa um `local session map` para armazenar informação de sessões. A Grid permite armazenamento opcional em Redis ou bancos de dados JDBC SQL. Para obter informação de como usar, use o seguinte comando:

```shell
java -jar selenium-server-<version>.jar info sessionmap
```

### Traceamento com OpenTelemetry e Jaeger

Por omissao, traceamento está activo. Para exportar e visualizar através de Jaeger, use o comando seguinte para instruções de como o efectuar:

```shell
java -jar selenium-server-<version>.jar info tracing
```

## Lista de comandos Selenium Grid

Irá mostrar todos os comandos disponíveis e também a descrição de cada um.

```shell
java -jar selenium-server-<version>.jar --config-help
```

## Comandos de ajuda para componente

Adicione `--help` após o Selenium role para obter informação específica de configuração do componente.

### Standalone

```shell
java -jar selenium-server-<version>.jar standalone --help
```

### Hub

```shell
java -jar selenium-server-<version>.jar hub --help
```

### Sessions

```shell
java -jar selenium-server-<version>.jar sessions --help
```

### New Session Queue

```shell
java -jar selenium-server-<version>.jar sessionqueue --help
```

### Distributor

```shell
java -jar selenium-server-<version>.jar distributor --help
```

### Router

```shell
java -jar selenium-server-<version>.jar router --help
```

### Node

```shell
java -jar selenium-server-<version>.jar node --help
```

# 4.2 - Opções CLI

Todas os detalhes das opções CLI de cada componente Grid.

Diferentes secções estão disponíveis para configurar uma Grid. Cada secção tem opções que podem ser configuradas através de opções CLI.

Pode ver abaixo um mapeamento entre o componente e a secção respectiva.

Note que esta documentação pode estar desactualizada se uma opção foi adicionada ou modificada, mas ainda não ter havido oportunidade de actualizar a documentação. Caso depare com esta situação, verifique a secção [“ajuda de configuração”](https://www.selenium.dev/pt-br/documentation/grid/configuration/help/) e esteja à vontade para nos enviar um pull request com alterações a esta página.

## Secções

|                               | Standalone | Hub | Node | Distributor | Router | Sessions | SessionQueue |
| ----------------------------- | ---------- | --- | ---- | ----------- | ------ | -------- | ------------ |
| [Distributor](#distributor)   | **         | **  |      | **          | **     |          |              |
| [Docker](#docker)             | **         |     | **   |             |        |          |              |
| [Events](#events)             |            | **  | **   | **          |        | **       | **           |
| [Logging](#logging)           | **         | **  | **   | **          | **     | **       | **           |
| [Network](#network)           | **         | **  |      |             | **     |          |              |
| [Node](#node)                 | **         |     | **   |             |        |          |              |
| [Router](#router)             | **         | **  |      |             | **     |          |              |
| [Relay](#relay)               | **         |     | **   |             |        |          |              |
| [Server](#server)             | **         | **  | **   | **          | **     | **       | **           |
| [SessionQueue](#sessionqueue) | **         | **  |      | **          | **     |          | **           |
| [Sessions](#sessions)         |            |     |      | **          | **     | **       |              |

### Distributor

| Opção                          | Tipo    | Valor/Exemplo                                                       | Descrição                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ------------------------------ | ------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--healthcheck-interval`       | int     | `120`                                                               | Tempo em segundos em que se verifica o estado dos Nodes. Isto garante que o servidor consecontactar cada um dos Nodes com sucesso.                                                                                                                                                                                                                                                                                                                  |
| `--distributor`                | uri     | `http://localhost:5553`                                             | Url do Distributor.                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `--distributor-host`           | string  | `localhost`                                                         | Host onde o Distributor está à escuta.                                                                                                                                                                                                                                                                                                                                                                                                              |
| `--distributor-implementation` | string  | `org.openqa.selenium.grid.distributor.local.LocalDistributor`       | Nome completo da class para uma implementação não padrão do Distributor.                                                                                                                                                                                                                                                                                                                                                                            |
| `--distributor-port`           | int     | `5553`                                                              | Porta onde o Distributor está à escuta.                                                                                                                                                                                                                                                                                                                                                                                                             |
| `--reject-unsupported-caps`    | boolean | `false`                                                             | Permitir que o Distributor rejeite imediatamente um pedido de sessão se a Grid não suportar a capacidade pedida. Esta configuração é a ideal para Grid que não inicie Nodes a pedido.                                                                                                                                                                                                                                                               |
| `--slot-matcher`               | string  | `org.openqa.selenium.grid.data.DefaultSlotMatcher`                  | Nome completo da class para uma implementação não padrão do comparador de slots. Isto é usado para determinar se um Node pode suportar uma sessão em particular.                                                                                                                                                                                                                                                                                    |
| `--slot-selector`              | string  | `org.openqa.selenium.grid.distributor.selector.DefaultSlotSelector` | Nome completo da class para uma implementação não padrão do selector de slots. Isto é usado para selecionar um slot no Node caso tenha sido “matched”.                                                                                                                                                                                                                                                                                              |
| `--newsession-threadpool-size` | int     | `24`                                                                | The Distributor uses a fixed-sized thread pool to create new sessions as it consumes new session requests from the queue. This allows configuring the size of the thread pool. The default value is no. of available processors \* 3. Note: If the no. of threads is way greater than the available processors it will not always increase the performance. A high number of threads causes more context switching which is an expensive operation. |
| `--purge-nodes-interval`       | int     | `30`                                                                | How often, in seconds, will the Distributor purge Nodes that have been down for a while. This is calculated based on the heartbeat received from a particular node.                                                                                                                                                                                                                                                                                 |

### Docker

| Opção                       | Tipo      | Valor/Exemplo                                                     | Descrição                                                                                                                                                                                                                                                                                   |
| --------------------------- | --------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--docker-assets-path`      | string    | `/opt/selenium/assets`                                            | Absolute path where assets will be stored                                                                                                                                                                                                                                                   |
| `--docker-`                 | string\[] | `selenium/standalone-firefox:latest '{"browserName": "firefox"}'` | Docker configs which map image name to stereotype capabilities (example \`-D selenium/standalone-firefox:latest ‘{“browserName”: “firefox”}’)                                                                                                                                               |
| `--docker-devices`          | string\[] | `/dev/kvm:/dev/kvm`                                               | Exposes devices to a container. Each device mapping declaration must have at least the path of the device in both host and container separated by a colon like in this example: /device/path/in/host:/device/path/in/container                                                              |
| `--docker-host`             | string    | `localhost`                                                       | Host name where the Docker daemon is running                                                                                                                                                                                                                                                |
| `--docker-port`             | int       | `2375`                                                            | Port where the Docker daemon is running                                                                                                                                                                                                                                                     |
| `--docker-url`              | string    | `http://localhost:2375`                                           | URL for connecting to the Docker daemon                                                                                                                                                                                                                                                     |
| `--docker-video-image`      | string    | `selenium/video:latest`                                           | Docker image to be used when video recording is enabled                                                                                                                                                                                                                                     |
| `--docker-host-config-keys` | string\[] | `Dns DnsOptions DnsSearch ExtraHosts Binds`                       | Specify which docker host configuration keys should be passed to browser containers. Keys name can be found in the Docker API [documentation](https://docs.docker.com/engine/api/v1.41/#tag/Container/operation/ContainerCreate), or by running `docker inspect` the node-docker container. |

### Events

| Opção                     | Tipo    | Valor/Exemplo                                      | Descrição                                                                                                                                                                                                                                                                           |
| ------------------------- | ------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--bind-bus`              | boolean | `false`                                            | Whether the connection string should be bound or connected. When true, the component will be bound to the Event Bus (as in the Event Bus will also be started by the component, typically by the Distributor and the Hub). When false, the component will connect to the Event Bus. |
| `--events-implementation` | string  | `org.openqa.selenium.events.zeromq.ZeroMqEventBus` | Full class name of non-default event bus implementation                                                                                                                                                                                                                             |
| `--publish-events`        | string  | `tcp://*:4442`                                     | Connection string for publishing events to the event bus                                                                                                                                                                                                                            |
| `--subscribe-events`      | string  | `tcp://*:4443`                                     | Connection string for subscribing to events from the event bus                                                                                                                                                                                                                      |

### Logging

| Opção                    | Tipo    | Valor/Exemplo                                                                                                                                              | Descrição                                                                                                                                                              |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--http-logs`            | boolean | `false`                                                                                                                                                    | Enable http logging. Tracing should be enabled to log http logs.                                                                                                       |
| `--log-encoding`         | string  | `UTF-8`                                                                                                                                                    | Log encoding                                                                                                                                                           |
| `--log`                  | string  | Windows path example : `'\path\to\file\gridlog.log'` or `'C:\path\path\to\file\gridlog.log'` Linux/Unix/MacOS path example : `'/path/to/file/gridlog.log'` | File to write out logs. Ensure the file path is compatible with the operating system’s file path.                                                                      |
| `--log-level`            | string  | `“INFO”`                                                                                                                                                   | Log level. Default logging level is INFO. Log levels are described here <https://docs.oracle.com/en/java/javase/11/docs/api/java.logging/java/util/logging/Level.html> |
| `--plain-logs`           | boolean | `true`                                                                                                                                                     | Use plain log lines                                                                                                                                                    |
| `--structured-logs`      | boolean | `false`                                                                                                                                                    | Use structured logs                                                                                                                                                    |
| `--tracing`              | boolean | `true`                                                                                                                                                     | Enable trace collection                                                                                                                                                |
| `--log-timestamp-format` | string  | `HH:mm:ss.SSS`                                                                                                                                             | Allows the configure log timestamp format                                                                                                                              |

### Network

| Opção            | Tipo    | Valor/Exemplo | Descrição                                                                                                            |
| ---------------- | ------- | ------------- | -------------------------------------------------------------------------------------------------------------------- |
| `--relax-checks` | boolean | `false`       | Relax checks on origin header and content type of incoming requests, in contravention of strict W3C spec compliance. |

### Node

| Opção                            | Tipo      | Valor/Exemplo                                                                                                                                                                                                                                                              | Descrição                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |   |
| -------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - |
| `--detect-drivers`               | boolean   | `true`                                                                                                                                                                                                                                                                     | Autodetect which drivers are available on the current system, and add them to the Node.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |   |
| `--driver-configuration`         | string\[] | `display-name="Firefox Nightly" max-sessions=2 webdriver-path="/usr/local/bin/geckodriver" stereotype="{\"browserName\": \"firefox\", \"browserVersion\": \"86\", \"moz:firefoxOptions\": {\"binary\":\"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"` | List of configured drivers a Node supports. It is recommended to provide this type of configuration through a toml config file to improve readability                                                                                                                                                                                                                                                                                                                                                                                                                                                   |   |
| `--driver-factory`               | string\[] | `org.openqa.selenium.example.LynxDriverFactory '{"browserName": "lynx"}'`                                                                                                                                                                                                  | Mapping of fully qualified class name to a browser configuration that this matches against.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |   |
| `--driver-implementation`        | string\[] | `"firefox"`                                                                                                                                                                                                                                                                | Drivers that should be checked. If specified, will skip autoconfiguration.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |   |
| `--node-implementation`          | string    | `"org.openqa.selenium.grid.node.local.LocalNodeFactory"`                                                                                                                                                                                                                   | Full classname of non-default Node implementation. This is used to manage a session’s lifecycle.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |   |
| `--grid-url`                     | string    | `https://grid.example.com`                                                                                                                                                                                                                                                 | Public URL of the Grid as a whole (typically the address of the Hub or the Router)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |   |
| `--heartbeat-period`             | int       | `60`                                                                                                                                                                                                                                                                       | How often, in seconds, will the Node send heartbeat events to the Distributor to inform it that the Node is up.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |   |
| `--max-sessions`                 | int       | `8`                                                                                                                                                                                                                                                                        | Maximum number of concurrent sessions. Default value is the number of available processors.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |   |
| `--override-max-sessions`        | boolean   | `false`                                                                                                                                                                                                                                                                    | The # of available processors is the recommended max sessions value (1 browser session per processor). Setting this flag to true allows the recommended max value to be overwritten. Session stability and reliability might suffer as the host could run out of resources.                                                                                                                                                                                                                                                                                                                             |   |
| `--register-cycle`               | int       | `10`                                                                                                                                                                                                                                                                       | How often, in seconds, the Node will try to register itself for the first time to the Distributor.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |   |
| `--register-period`              | int       | `120`                                                                                                                                                                                                                                                                      | How long, in seconds, will the Node try to register to the Distributor for the first time. After this period is completed, the Node will not attempt to register again.                                                                                                                                                                                                                                                                                                                                                                                                                                 |   |
| `--session-timeout`              | int       | `300`                                                                                                                                                                                                                                                                      | Let X be the session-timeout in seconds. The Node will automatically kill a session that has not had any activity in the last X seconds. This will release the slot for other tests.                                                                                                                                                                                                                                                                                                                                                                                                                    |   |
| `--vnc-env-var`                  | string\[] | `SE_START_XVFB SE_START_VNC SE_START_NO_VNC`                                                                                                                                                                                                                               | Environment variable to check in order to determine if a vnc stream is available or not.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |   |
| `--no-vnc-port`                  | int       | `7900`                                                                                                                                                                                                                                                                     | If VNC is available, sets the port where the local noVNC stream can be obtained                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |   |
| `--drain-after-session-count`    | int       | `1`                                                                                                                                                                                                                                                                        | Drain and shutdown the Node after X sessions have been executed. Useful for environments like Kubernetes. A value higher than zero enables this feature.                                                                                                                                                                                                                                                                                                                                                                                                                                                |   |
| `--hub`                          | string    | `http://localhost:4444`                                                                                                                                                                                                                                                    | The address of the Hub in a Hub-and-Node configuration. Can be a hostname or IP address (`hostname`), in which case the Hub will be assumed to be `http://hostname:4444`, the `--grid-url` will be the same `--publish-events` will be `tcp://hostname:4442` and `--subscribe-events` will be `tcp://hostname:4443`. If `hostname` contains a port number, that will be used for `--grid-url` but the URIs for the event bus will remain the same. Any of these default values may be overridden but setting the correct flags. If the hostname has a protocol (such as `https`) that will be used too. |   |
| `--enable-cdp`                   | boolean   | `true`                                                                                                                                                                                                                                                                     | Enable CDP proxying in Grid. A Grid admin can disable CDP if the network does not allow websockets. True by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |   |
| `--enable-managed-downloads`     | boolean   | `false`                                                                                                                                                                                                                                                                    | This causes the Node to auto manage files downloaded for a given session on the Node.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |   |
| `--selenium-manager`             | boolean   | `false`                                                                                                                                                                                                                                                                    | When drivers are not available on the current system, use Selenium Manager. False by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |   |
| `--connection-limit-per-session` | int       | `10`                                                                                                                                                                                                                                                                       | Let X be the maximum number of websocket connections per session.This will ensure one session is not able to exhaust the connection limit of the host.                                                                                                                                                                                                                                                                                                                                                                                                                                                  |   |

### Relay

| Opção                        | Tipo      | Valor/Exemplo                                                                                                     | Descrição                                                                                                                                                                |
| ---------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--service-url`              | string    | `http://localhost:4723`                                                                                           | URL for connecting to the service that supports WebDriver commands like an Appium server or a cloud service.                                                             |
| `--service-host`             | string    | `localhost`                                                                                                       | Host name where the service that supports WebDriver commands is running                                                                                                  |
| `--service-port`             | int       | `4723`                                                                                                            | Port where the service that supports WebDriver commands is running                                                                                                       |
| `--service-status-endpoint`  | string    | `/status`                                                                                                         | Optional, endpoint to query the WebDriver service status, an HTTP 200 response is expected                                                                               |
| `--service-protocol-version` | string    | `HTTP/1.1`                                                                                                        | Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status                                                          |
| `--service-configuration`    | string\[] | `max-sessions=2 stereotype='{"browserName": "safari", "platformName": "iOS", "appium:platformVersion": "14.5"}}'` | Configuration for the service where calls will be relayed to. It is recommended to provide this type of configuration through a toml config file to improve readability. |

### Router

| Opção          | Tipo    | Valor/Exemplo              | Descrição                                                                                                           |
| -------------- | ------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `--password`   | string  | `myStrongPassword`         | Password clients must use to connect to the server. Both this and the username need to be set in order to be used.  |
| `--username`   | string  | `admin`                    | User name clients must use to connect to the server. Both this and the password need to be set in order to be used. |
| `--sub-path`   | string  | `my_company/selenium_grid` | A sub-path that should be considered for all user facing routes on the Hub/Router/Standalone.                       |
| `--disable-ui` | boolean | `true`                     | Disable the Grid UI.                                                                                                |

### Server

| Opção                 | Tipo    | Valor/Exemplo        | Descrição                                                                                                                                                                                                                                                                             |
| --------------------- | ------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--allow-cors`        | boolean | `true`               | Whether the Selenium server should allow web browser connections from any host                                                                                                                                                                                                        |
| `--host`              | string  | `localhost`          | Server IP or hostname: usually determined automatically.                                                                                                                                                                                                                              |
| `--bind-host`         | boolean | `true`               | Whether the server should bind to the host address/name, or only use it to" report its reachable url. Helpful in complex network topologies where the server cannot report itself with the current IP/hostname but rather an external IP or hostname (e.g. inside a Docker container) |
| `--https-certificate` | path    | `/path/to/cert.pem`  | Server certificate for https. Get more detailed information by running “java -jar selenium-server.jar info security”                                                                                                                                                                  |
| `--https-private-key` | path    | `/path/to/key.pkcs8` | Private key for https. Get more detailed information by running “java -jar selenium-server.jar info security”                                                                                                                                                                         |
| `--max-threads`       | int     | `24`                 | Maximum number of listener threads. Default value is: (available processors) \* 3.                                                                                                                                                                                                    |
| `--port`              | int     | `4444`               | Port to listen on. There is no default as this parameter is used by different components, for example, Router/Hub/Standalone will use 4444 and Node will use 5555.                                                                                                                    |

### SessionQueue

| Opção                       | Tipo   | Valor/Exemplo           | Descrição                                                                                                                                                 |
| --------------------------- | ------ | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--sessionqueue`            | uri    | `http://localhost:1237` | Address of the session queue server.                                                                                                                      |
| `-sessionqueue-host`        | string | `localhost`             | Host on which the session queue server is listening.                                                                                                      |
| `--sessionqueue-port`       | int    | `1234`                  | Port on which the session queue server is listening.                                                                                                      |
| `--session-request-timeout` | int    | `300`                   | Timeout in seconds. A new incoming session request is added to the queue. Requests sitting in the queue for longer than the configured time will timeout. |
| `--session-retry-interval`  | int    | `5`                     | Retry interval in seconds. If all slots are busy, new session request will be retried after the given interval.                                           |
| `--maximum-response-delay`  | int    | `8`                     | How often, in seconds, will the the SessionQueue response in case there is no data, to reduce the http requests while polling for new session requests.   |

### Sessions

| Opção             | Tipo   | Valor/Exemplo           | Descrição                                          |
| ----------------- | ------ | ----------------------- | -------------------------------------------------- |
| `--sessions`      | uri    | `http://localhost:1234` | Address of the session map server.                 |
| `--sessions-host` | string | `localhost`             | Host on which the session map server is listening. |
| `--sessions-port` | int    | `1234`                  | Port on which the session map server is listening. |

## Configuration examples

All the options mentioned above can be used when starting the Grid components. They are a good way of exploring the Grid options, and trying out values to find a suitable configuration.

We recommend the use of [Toml files](https://www.selenium.dev/pt-br/documentation/grid/configuration/toml_options/) to configure a Grid. Configuration files improve readability, and you can also check them in source control.

When needed, you can combine a Toml file configuration with CLI arguments.

### Command-line flags

To pass config options as command-line flags, identify the valid options for the component and follow the template below.

```
java -jar selenium-server-<version>.jar <component> --<option> value
```

#### Standalone, setting max sessions and main port

```
java -jar selenium-server-<version>.jar standalone --max-sessions 4 --port 4444
```

#### Hub, setting a new session request timeout, a main port, and disabling tracing

```
java -jar selenium-server-<version>.jar hub --session-request-timeout 500 --port 3333 --tracing false
```

#### Node, with 4 max sessions, with debug(fine) log, 7777 as port, and only with Firefox and Edge

```
java -jar selenium-server-<version>.jar node --max-sessions 4 --log-level "fine" --port 7777 --driver-implementation "firefox" --driver-implementation "edge"
```

#### Distributor, setting Session Map server url, Session Queue server url, and disabling bus

```
java -jar selenium-server-<version>.jar distributor --sessions http://localhost:5556 --sessionqueue http://localhost:5559 --bind-bus false
```

#### Setting custom capabilities for matching specific Nodes

**Important:** Custom capabilities need to be set in the configuration in all Nodes. They also need to be included always in every session request.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node A with custom cap set to `true`

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":true}' --port 6161
```

##### Start the Node B with custom cap set to `false`

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":false}' --port 6262
```

##### Matching Node A

```java
ChromeOptions options = new ChromeOptions();
options.setCapability("gsg:customcap", true);
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

Set the custom capability to `false` in order to match the Node B.

#### Enabling Managed downloads by the Node

At times a test may need to access files that were downloaded by it on the Node. To retrieve such files, following can be done.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node with manage downloads enabled

```
java -jar selenium-server-<version>.jar node --enable-managed-downloads true
```

##### Set the capability at the test level

Tests that want to use this feature should set the capability `"se:downloadsEnabled"`to `true`

```java
options.setCapability("se:downloadsEnabled", true);
```

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

In the response the list of file names appear under the key `names`.

##### Dowloading a file:

* The endpoint to `POST` from is `/session/<sessionId>/se/files` with a payload of the form `{"name": "fileNameGoesHere}`
* The session needs to be active in order for the command to work.
* The raw response looks like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "Base64EncodedStringContentsOfDownloadedFileAsZipGoesHere"
  }
}
```

* The response blob contains two keys,

  * `filename` - The file name that was downloaded.
  * `contents` - Base64 encoded zipped contents of the file.

* The file contents are Base64 encoded and they need to be unzipped.

##### List files that can be downloaded

The below mentioned `curl` example can be used to list all the files that were downloaded by the current session in the Node, and which can be retrieved locally.

```bash
curl -X GET "http://localhost:4444/session/90c0149a-2e75-424d-857a-e78734943d4c/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

##### Retrieve a downloaded file

Assuming the downloaded file is named `Red-blue-green-channel.jpg`, and using `curl`, the file could be downloaded with the following command:

```bash
curl -H "Accept: application/json" \
-H "Content-Type: application/json; charset=utf-8" \
-X POST -d '{"name":"Red-blue-green-channel.jpg"}' \
"http://localhost:4444/session/18033434-fa4f-4d11-a7df-9e6d75920e19/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "UEsDBBQACAgIAJpagVYAAAAAAAAAAAAAAAAaAAAAUmVkLWJsAAAAAAAAAAAAUmVkLWJsdWUtZ3JlZW4tY2hhbm5lbC5qcGdQSwUGAAAAAAEAAQBIAAAAcNkAAAAA"
  }
}
```

##### Complete sample code in Java

Below is an example in Java that does the following:

* Sets the capability to indicate that the test requires automatic managing of downloaded files.
* Triggers a file download via a browser.
* Lists the files that are available for retrieval from the remote node (These are essentially files that were downloaded in the current session)
* Picks one file and downloads the file from the remote node to the local machine.

```java
import com.google.common.collect.ImmutableMap;

import org.openqa.selenium.By;
import org.openqa.selenium.io.Zip;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.io.File;
import java.net.URL;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import static org.openqa.selenium.remote.http.Contents.asJson;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.HttpMethod.GET;
import static org.openqa.selenium.remote.http.HttpMethod.POST;

public class DownloadsSample {

  public static void main(String[] args) throws Exception {
    // Assuming the Grid is running locally.
    URL gridUrl = new URL("http://localhost:4444");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("se:downloadsEnabled", true);
    RemoteWebDriver driver = new RemoteWebDriver(gridUrl, options);
    try {
      demoFileDownloads(driver, gridUrl);
    } finally {
      driver.quit();
    }
  }

	private static void demoFileDownloads(RemoteWebDriver driver, URL gridUrl) throws Exception {
		driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
		// Download the two available files on the page
		driver.findElement(By.id("file-1")).click();
		driver.findElement(By.id("file-2")).click();

		// The download happens in a remote Node, which makes it difficult to know when the file
		// has been completely downloaded. For demonstration purposes, this example uses a
		// 10-second sleep which should be enough time for a file to be downloaded.
		// We strongly recommend to avoid hardcoded sleeps, and ideally, to modify your
		// application under test, so it offers a way to know when the file has been completely
		// downloaded.
		TimeUnit.SECONDS.sleep(10);

		//This is the endpoint which will provide us with list of files to download and also to
		//let us download a specific file.
		String downloadsEndpoint = String.format("/session/%s/se/files", driver.getSessionId());

		String fileToDownload;

		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To list all files that are were downloaded on the remote node for the current session
			// we trigger GET request.
			HttpRequest request = new HttpRequest(GET, downloadsEndpoint);
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			@SuppressWarnings("unchecked")
			List<String> names = (List<String>) value.get("names");
			// Let's say there were "n" files downloaded for the current session, we would like
			// to retrieve ONLY the first file.
			fileToDownload = names.get(0);
		}

		// Now, let's download the file
		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To retrieve a specific file from one or more files that were downloaded by the current session
			// on a remote node, we use a POST request.
			HttpRequest request = new HttpRequest(POST, downloadsEndpoint);
			request.setContent(asJson(ImmutableMap.of("name", fileToDownload)));
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			// The returned map would contain 2 keys,
			// filename - This represents the name of the file (same as what was provided by the test)
			// contents - Base64 encoded String which contains the zipped file.
			String zippedContents = value.get("contents").toString();
			// The file contents would always be a zip file and has to be unzipped.
			File downloadDir = Zip.unzipToTempDir(zippedContents, "download", "");
			// Read the file contents
			File downloadedFile = Optional.ofNullable(downloadDir.listFiles()).orElse(new File[]{})[0];
			String fileContent = String.join("", Files.readAllLines(downloadedFile.toPath()));
			System.out.println("The file which was "
					+ "downloaded in the node is now available in the directory: "
					+ downloadDir.getAbsolutePath() + " and has the contents: " + fileContent);
		}
	}


}
```

# 4.3 - Toml Options

```toml
[section1]
option1="value"

[section2]
option2=["value1","value2"]
option3=true
```

Below are some examples of Grid components configured with a Toml file, the component can be started in the following way:

```
java -jar selenium-server-<version>.jar <component> --config /path/to/file/<file-name>.toml
```

### Standalone

A Standalone server, running on port 4449, and a new session request timeout of 500 seconds.

```toml
[server]
port = 4449

[sessionqueue]
session-request-timeout = 500
```

### Specific browsers and a limit of max sessions

A Standalone server or a Node which only has Firefox and Chrome enabled by default.

```toml
[node]
drivers = ["chrome", "firefox"]
max-sessions = 3
```

### Configuring and customising drivers

Standalone or Node server with customised drivers, which allows things like having Firefox Beta or Nightly, and having different browser versions.

```toml
[node]
detect-drivers = false
[[node.driver-configuration]]
max-sessions = 100
display-name = "Firefox Nightly"
stereotype = "{\"browserName\": \"firefox\", \"browserVersion\": \"93\", \"platformName\": \"MAC\", \"moz:firefoxOptions\": {\"binary\": \"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"
[[node.driver-configuration]]
display-name = "Chrome Beta"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"94\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta\"}}"
[[node.driver-configuration]]
display-name = "Chrome Dev"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"95\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev\"}}"
webdriver-executable = '/path/to/chromedriver/95/chromedriver'
```

### Standalone or Node with Docker

A Standalone or Node server that is able to run each new session in a Docker container. Disabling drivers detection, having maximum 2 concurrent sessions. Stereotypes configured need to be mapped to a Docker image, and the Docker daemon needs to be exposed via http/tcp. In addition, it is possible to define which device files, accessible on the host, will be available in containers through the `devices` property. Refer to the [docker](https://docs.docker.com/engine/reference/commandline/run/#add-host-device-to-container---device) documentation for more information about how docker device mapping works.

```toml
[node]
detect-drivers = false
max-sessions = 2

[docker]
configs = [
    "selenium/standalone-chrome:93.0", "{\"browserName\": \"chrome\", \"browserVersion\": \"91\"}", 
    "selenium/standalone-firefox:92.0", "{\"browserName\": \"firefox\", \"browserVersion\": \"92\"}"
]
#Optionally define all device files that should be mapped to docker containers
#devices = [
#    "/dev/kvm:/dev/kvm"
#]
url = "http://localhost:2375"
video-image = "selenium/video:latest"
```

### Relaying commands to a service endpoint that supports WebDriver

It is useful to connect an external service that supports WebDriver to Selenium Grid. An example of such service could be a cloud provider or an Appium server. In this way, Grid can enable more coverage to platforms and versions not present locally.

The following is an en example of connecting an Appium server to Grid.

```toml
[node]
detect-drivers = false

[relay]
# Default Appium/Cloud server endpoint
url = "http://localhost:4723/wd/hub"
status-endpoint = "/status"
# Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status (e.g. HTTP/1.1, HTTP/2)
protocol-version = "HTTP/1.1"
# Stereotypes supported by the service. The initial number is "max-sessions", and will allocate 
# that many test slots to that particular configuration
configs = [
  "5", "{\"browserName\": \"chrome\", \"platformName\": \"android\", \"appium:platformVersion\": \"11\"}"
]
```

### Basic auth enabled

It is possible to protect a Grid with basic auth by configuring the Router/Hub/Standalone with a username and password. This user/password combination will be needed when loading the Grid UI or starting a new session.

```toml
[router]
username = "admin"
password = "myStrongPassword"
```

Here is a Java example showing how to start a session using the configured user and password.

```java
ClientConfig clientConfig = ClientConfig.defaultConfig()
  .baseUrl(new URL("http://localhost:4444"))
  .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"));
HttpCommandExecutor executor = new HttpCommandExecutor(clientConfig);
RemoteWebDriver driver = new RemoteWebDriver(executor, new ChromeOptions());
```

In other languages, you can use the URL http\://admin:myStrongPassword\@localhost:4444

### Setting custom capabilities for matching specific Nodes

**Important:** Custom capabilities need to be set in the configuration in all Nodes. They also need to be included always in every session request.

```toml
[node]
detect-drivers = false

[[node.driver-configuration]]
display-name = "firefox"
stereotype = '{"browserName": "firefox", "platformName": "macOS", "browserVersion":"96", "networkname:applicationName":"node_1", "nodename:applicationName":"app_1" }'
max-sessions = 5
```

Here is a Java example showing how to match that Node

```java
FirefoxOptions options = new FirefoxOptions();
options.setCapability("networkname:applicationName", "node_1");
options.setCapability("nodename:applicationName", "app_1");
options.setBrowserVersion("96");
options.setPlatformName("macOS");
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

### Enabling Managed downloads by the Node.

The Node can be instructed to manage downloads automatically. This will cause the Node to save all files that were downloaded for a particular session into a temp directory, which can later be retrieved from the node. To turn this capability on, use the below configuration:

```toml
[node]
enable-managed-downloads = true
```

Refer to the [CLI section](https://www.selenium.dev/pt-br/documentation/grid/configuration/cli_options/#enabling-managed-downloads-by-the-node) for a complete example.

# 5 - Arquitectura da Grid

|               | Event Bus | Distributor | Node | Router | Session Map | Session Queue |
| ------------- | --------- | ----------- | ---- | ------ | ----------- | ------------- |
| Event Bus     | X         |             |      |        |             |               |
| Distributor   | ✅         | X           | ✅    |        |             | ✅             |
| Node          | ✅         |             | X    |        |             |               |
| Router        |           |             | ✅    | X      | ✅           |               |
| Session Map   |           |             |      |        | X           |               |
| Session Queue | ✅         |             |      |        |             | X             |

| Nome               | Tipo    | Descrição                                                                                                                                                                                                                                         |
| ------------------ | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| availability       | string  | Uma string com `up`, `draining`, ou `down`. A mais importante é `draining`, que indica que não devem ser enviados novos pedidos de sessão para o Node e assim que a última sessão termine, o Node irá reiniciar ou concluir.                      |
| externalUrl        | string  | Uma URI que os outros componentes da Grid se devem ligar.                                                                                                                                                                                         |
| lastSessionCreated | integer | Um timestamp da última sessão que foi criada neste Node. O Distributor irá tentar enviar novos pedidos de sessão para o Node que esteja parado há mais tempo.                                                                                     |
| maxSessionCount    | integer | Embora seja possível inferir o número máximo de sessões a partir da lista de slots disponíveis, este número é usado para determinar qual é o máximo de sessões que este Node pode executar em simultâneo antes que se considere que está “cheio”. |
| nodeId             | string  | Um identificador UUID para esta instância do Node.                                                                                                                                                                                                |
| osInfo             | object  | Um objecto contendo os campos `arch`, `name`, e `version`. Isto é usado pela Grid UI e pelas queries GraphQL.                                                                                                                                     |
| slots              | array   | Um array de objectos Slot (descritos na secção seguinte)                                                                                                                                                                                          |
| version            | string  | A versão do Node (para Selenium, será igual à versão do Selenium)                                                                                                                                                                                 |

É recomendado que todos os campos tenham valores.

### O Objecto Slot

O objecto Slot representa um slot dentro de um Node. Um “slot” é onde uma sessão consegue ser executada. É possível que um Node tenha mais do que um Slot capaz de executar ao mesmo tempo. Por exemplo, um Node pode ser capaz de executar até 10 sessões em simultâneo, mas podem ser uma qualquer combinação de Chrome, Firefox ou Edge e neste caso, o Node irá indicar 10 como o número máximo de sessões, indicando que podem ser 10 Chrome, 10 Firefox e 10 Edge.

| Nome        | Tipo   | Descrição                                                                                                                                                                                 |
| ----------- | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id          | string | Um identificador UUID para este slot                                                                                                                                                      |
| lastStarted | string | timestamp no formato ISO-8601 contendo a data em que a última sessão iniciou                                                                                                              |
| stereotype  | object | Conjunto mínimo de [capacidades](https://w3c.github.io/webdriver/#dfn-merging-capabilities) que fazem match com este slot. O exemplo mínimo será por exemplo `{"browserName": "firefox"}` |
| session     | object | O objecto Session (descrito na secção seguinte)                                                                                                                                           |

### O Objecto Session

Representa uma sessão em execução dentro de um Slot

| Nome         | Tipo   | Descrição                                                                                                                                                                                 |
| ------------ | ------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| capabilities | object | A lista de capacidades fornecidas pela sessão. Irá coincidir com o valor obtido pelo comando [nova sessão](https://w3c.github.io/webdriver/#new-session)                                  |
| startTime    | string | timestamp no formato ISO-8601 contendo a data em que a última sessão iniciou                                                                                                              |
| stereotype   | object | Conjunto mínimo de [capacidades](https://w3c.github.io/webdriver/#dfn-merging-capabilities) que fazem match com este slot. O exemplo mínimo será por exemplo `{"browserName": "firefox"}` |
| uri          | string | A URI usada pelo Node para comunicar com a sessão                                                                                                                                         |

# 6 - Características avançadas

Para obter todos os detalhes dos recursos avançados, entenda como funciona e como configurar crie o seu próprio, navegue pelas seções a seguir.

# 6.1 - Observabilidade

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar standalone --log-level FINE
```

2. Jaeger UI - OpenTelemetry fornece as APIs e SDKs para instrumentar rastreamentos no código. Enquanto o Jaeger é um sistema de rastreamento de backend que auxilia na coleta de dados de telemetria de rastreamento e oferece recursos de consulta, filtragem e visualização dos dados.

Instruções detalhadas sobre como visualizar rastreamentos usando a interface do Jaeger podem ser obtidas executando o seguinte comando:

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar info tracing
```

[Um exemplo muito bom e scripts para executar o servidor e enviar rastreamentos para o Jaeger](https://github.com/manoj9788/tracing-selenium-grid)

## Explorando logs de eventos

O rastreamento deve estar habilitado para o registro de eventos, mesmo que alguém não deseje exportar rastreamentos para visualizá-los.

**Por padrão, o rastreamento está habilitado. Não é necessário passar parâmetros adicionais para ver os logs no console.**

Todos os eventos dentro de um segmento são registrados no nível FINE. Eventos de erro são registrados no nível WARN..

| Campo               | Valor do Campo  | Descrição                                                                                                                                                                                                                    |
| ------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Hora do Evento      | eventId         | Carimbo de data/hora do registro do evento em nanossegundos desde a época.                                                                                                                                                   |
| ID de Rastreamento  | tracedId        | Cada rastreamento é identificado exclusivamente por um ID de rastreamento.                                                                                                                                                   |
| ID de Segmento      | spanId          | Cada segmento dentro de um rastreamento é identificado exclusivamente por um ID de segmento.                                                                                                                                 |
| Tipo de Segmento    | spanKind        | O tipo de segmento é uma propriedade do segmento que indica o tipo de segmento. Isso ajuda a entender a natureza da unidade de trabalho realizada pelo segmento.                                                             |
| Nome do Evento      | eventName       | Isso mapeia para a mensagem de registro.                                                                                                                                                                                     |
| Atributos do Evento | eventAttributes | Isso forma a essência dos registros de eventos, com base na operação executada, ele contém pares chave-valor formatados em JSON. Isso também inclui um atributo de classe do manipulador, para mostrar a classe do registro. |

Simples log

```
FINE [LoggingOptions$1.lambda$export$1] - {
  "traceId": "fc8aef1d44b3cc8bc09eb8e581c4a8eb",
  "spanId": "b7d3b9865d3ddd45",
  "spanKind": "INTERNAL",
  "eventTime": 1597819675128886121,
  "eventName": "Session request execution complete",
  "attributes": {
    "http.status_code": 200,
    "http.handler_class": "org.openqa.selenium.grid.router.HandleSession",
    "http.url": "\u002fsession\u002fdd35257f104bb43fdfb06242953f4c85",
    "http.method": "DELETE",
    "session.id": "dd35257f104bb43fdfb06242953f4c85"
  }
}
```

Além dos campos mencionados anteriormente, com base na [especificação do OpenTelemetry](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/exceptions.md) os registros de erro consistem nos seguintes campos: :

| Campo                   | Valor do Campo       | Descrição                                                                                                  |
| ----------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------- |
| Tipo de Exceção         | exception.type       | O nome da classe da exceção.                                                                               |
| Mensagem da Exceção     | exception.message    | Motivo da exceção.                                                                                         |
| Rastreamento de Exceção | exception.stacktrace | Imprime a pilha de chamadas no momento em que a exceção foi lançada. Ajuda a entender a origem da exceção. |

Simples error log

```
WARN [LoggingOptions$1.lambda$export$1] - {
  "traceId": "7efa5ea57e02f89cdf8de586fe09f564",
  "spanId": "914df6bc9a1f6e2b",
  "spanKind": "INTERNAL",
  "eventTime": 1597820253450580272,
  "eventName": "exception",
  "attributes": {
    "exception.type": "org.openqa.selenium.ScriptTimeoutException",
    "exception.message": "Unable to execute request: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist ..." (full message will be printed),
    "exception.stacktrace": "org.openqa.selenium.ScriptTimeoutException: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist\nBuild info: version: '4.0.0-alpha-7', revision: 'Unknown'\nSystem info: host: 'XYZ-MacBook-Pro.local', ip: 'fe80:0:0:0:10d5:b63a:bdc6:1aff%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.7'\nDriver info: driver.version: unknown ...." (full stack will be printed),
    "http.handler_class": "org.openqa.selenium.grid.distributor.remote.RemoteDistributor",
    "http.url": "\u002fsession",
    "http.method": "POST"
  }
}
```

# 6.2 - Suporte a buscas em GraphQL

```shell
{
    session(id: "<session-id>") : {
        id,
        capabilities,
        startTime,
        uri,
        nodeId,
        nodeUri,
        sessionDurationMillis
        slot : {
            id,
            stereotype,
            lastStarted
        }
    }
    grid: {
        uri,
        totalSlots,
        nodeCount,
        maxSession,
        sessionCount,
        version,
        sessionQueueSize
    }
    sessionsInfo: {
        sessionQueueRequests,
        sessions: [
            {
                id,
                capabilities,
                startTime,
                uri,
                nodeId,
                nodeUri,
                sessionDurationMillis
                slot : {
                    id,
                    stereotype,
                    lastStarted
                }
            }
        ]
    }
    nodesInfo: {
        nodes : [
            {
                id,
                uri,
                status,
                maxSession,
                slotCount,
                sessions: [
                    {
                        id,
                        capabilities,
                        startTime,
                        uri,
                        nodeId,
                        nodeUri,
                        sessionDurationMillis
                        slot : {
                            id,
                            stereotype,
                            lastStarted
                        }
                    }
                ],
                sessionCount,
                stereotypes,
                version,
                osInfo: {
                    arch,
                    name,
                    version
                }
            }
        ]
    }
}
```

## Consultando GraphQL

O melhor jeito de consultar GraphQL é utilizando requisições `curl`. GraphQL permite que você busque apenas os dados que você quer, nada mais, anda menos.

Alguns exemplos de buscas em GraphQL estão abaixo. Você pode montar as queries como quiser.

### Buscando o número total de slots (`maxSession`) e slots usados (`sessionCount`) na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ grid { maxSession, sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

Geralmente na máquina local o `<LINK_TO_GRAPHQL_ENDPOINT>` será `http://localhost:4444/graphql`

### Buscando todos os detalhes da Sessão, Nó e Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { uri, maxSession, sessionCount }, nodesInfo { nodes { id, uri, status, sessions { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } }, slotCount, sessionCount }} }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando o número de sessões atual na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando a contagem máxima de sessões na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { maxSession } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando todos os detalhes de todas as sessões de todos os nós na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, capabilities, startTime, uri, nodeId, nodeId, sessionDurationMillis } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando informações dos slots de todas as sessões de cada Nó na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, slot { id, stereotype, lastStarted } } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando informação da sessão para uma sessão específica:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ session (id: \"<session-id>\") { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } } } "}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando os recursos de cada nó na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { stereotypes } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando o status de cada Nó na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { status } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando a URI de cada Nó e da Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { uri } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the current requests in the New Session Queue:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessionQueueRequests } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the New Session Queue size :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionQueueSize } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

# 6.3 - Rotas da Grid

## Grid

### Status da Grid

O status da Grid fornece o estado atual da grid. Consiste em detalhes sobre cada nó registrado. Para cada nó, o status inclui informações sobre a disponibilidade, sessões e slots do nó.

```shell
curl --request GET 'http://localhost:4444/status'
```

### Deletar sessão

A exclusão da sessão encerra a sessão do WebDriver, fecha o driver e o remove do mapa de sessões ativas. Qualquer solicitação usando o id de sessão removido ou reutilizando a instância do driver gerará um erro.

```shell
curl --request DELETE 'http://localhost:4444/session/<session-id>'
```

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret> '
```

No modo totalmente distribuído, a URL é o endereço do servidor Router.

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

Se nenhum segredo de registro foi configurado durante a configuração da Grid, use

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET;'
```

### Drenar Nó

O comando de drenagem de nó é para desligamento normal de nó. A drenagem para o Node após a conclusão de todas as sessões em andamento. No entanto, ele não aceita novas solicitações de sessão.

No modo Standalone, a URL do distribuidor é o endereço do servidor Standalone.

No modo Hub-Node, a URL do Distribuidor é o endereço do servidor Hub.

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret> '
```

No modo totalmente distribuído, a URL é o endereço do servidor Router.

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

Se nenhum segredo de registro foi configurado durante a configuração da Grid, use

```shell
curl --request POST 'http://<Router-URL>/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET;'
```

## Nó

Os terminais nesta seção são aplicáveis ao modo Hub-Node e ao modo Grid totalmente distribuída, onde o Nó é executado de forma independente. A URL do Nó padrão é http\://localhost:5555 no caso de um Nó. No caso de vários Nós, use [Grid status](/pt-br/documentation/grid/advanced_features/endpoints/#grid-status) para obter todos os detalhes do Nó e localizar o endereço do Nó.

### Status

O status do Nó é essencialmente uma verificação de integridade do Nó. O distribuidor executa ping no status do Nó em intervalos regulares e atualiza o modelo de Grid de acordo. O status inclui informações sobre disponibilidade, sessões e slots.

```shell
curl --request GET 'http://localhost:5555/status'
```

### Drenagem

O Distribuidor passa o comando \[drain]\(# drain-node) para o Nó apropriado identificado pelo ID do Nó. Para drenar o Nó diretamente, use o comando curl listado abaixo. Ambos as rotas são válidas e produzem o mesmo resultado. Drenar termina as sessões em andamento antes de interromper o Nó.

```shell
curl --request POST 'http://localhost:5555/se/grid/node/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

Se nenhum segredo de registro foi configurado durante a configuração da Grid, use

```shell
curl --request POST 'http://<node-URL>/se/grid/node/drain' --header 'X-REGISTRATION-SECRET;'
```

### Checar dono da sessão

Para verificar se uma sessão pertence a um Nó, use o comando curl listado abaixo.

```shell
curl --request GET 'http://localhost:5555/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

Se nenhum segredo de registro foi configurado durante a configuração da Grid, use

```shell
curl --request GET 'http://<node-URL>/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

Ele retornará true se a sessão pertencer ao Nó, caso contrário, retornará false.

### Deletar sessão

A exclusão da sessão encerra a sessão do WebDriver, fecha o driver e o remove do mapa de sessões ativas. Qualquer solicitação usando o id de sessão removido ou reutilizando a instância do driver gerará um erro.

```shell
curl --request DELETE 'http://localhost:5555/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

Se nenhum segredo de registro foi configurado durante a configuração da Grid, use

```shell
curl --request DELETE 'http://<node-URL>/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

## Fila de Sessão

### Limpar a Fila de Sessão

A Fila de Sessão contém as novas solicitações de sessão. Para limpar a fila, use o comando curl listado abaixo. Limpar a fila rejeita todas as solicitações na fila. Para cada solicitação, o servidor retorna uma resposta de erro ao respectivo cliente. O resultado do comando clear é o número total de solicitações excluídas.

No modo Standalone, a URL Queue é o endereço do servidor Standalone.

No modo Hub-Node, a URL do enfileirador é o endereço do servidor Hub.

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

No modo totalmente distribuído, a URL do enfileirador é o endereço do servidor do Enfileirador de Sessões.

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET;'
```

### Obter novos pedidos da Fila de Sessão

Novos pedidos da Fila de Sessão contém os novos pedidos de sessão. Para obter os pedidos na Fila, utiliza o comando curl listado abaixo. É retornado o número total de pedidos na Fila.

No modo Standalone, a URL é a do servidor, em modo Grid, a URL será a do HUB.

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

No modo totalmente distribuido, a URL da Fila é a porta do servidor de Fila.

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

# 6.4 - Personalizando um Nó

```bash
java -jar custom_node-server.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

```bash
java -jar selenium-server-4.6.0.jar \
--ext custom_node-1.0-SNAPSHOT.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

Aqui está um exemplo que apenas imprime algumas mensagens no console sempre que houver uma atividade de interesse (sessão criada, sessão excluída, execução de um comando do webdriver, etc.) no Node.

Sample customized node

```java
package org.seleniumhq.samples;

import java.net.URI;
import java.util.UUID;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.NoSuchSessionException;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.grid.config.Config;
import org.openqa.selenium.grid.data.CreateSessionRequest;
import org.openqa.selenium.grid.data.CreateSessionResponse;
import org.openqa.selenium.grid.data.NodeId;
import org.openqa.selenium.grid.data.NodeStatus;
import org.openqa.selenium.grid.data.Session;
import org.openqa.selenium.grid.log.LoggingOptions;
import org.openqa.selenium.grid.node.HealthCheck;
import org.openqa.selenium.grid.node.Node;
import org.openqa.selenium.grid.node.local.LocalNodeFactory;
import org.openqa.selenium.grid.security.Secret;
import org.openqa.selenium.grid.security.SecretOptions;
import org.openqa.selenium.grid.server.BaseServerOptions;
import org.openqa.selenium.internal.Either;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
import org.openqa.selenium.remote.tracing.Tracer;

public class DecoratedLoggingNode extends Node {

  private Node node;

  protected DecoratedLoggingNode(Tracer tracer, NodeId nodeId, URI uri, Secret registrationSecret, Duration sessionTimeout) {
    super(tracer, nodeId, uri, registrationSecret, sessionTimeout);
  }

  public static Node create(Config config) {
    LoggingOptions loggingOptions = new LoggingOptions(config);
    BaseServerOptions serverOptions = new BaseServerOptions(config);
    URI uri = serverOptions.getExternalUri();
    SecretOptions secretOptions = new SecretOptions(config);
    NodeOptions nodeOptions = new NodeOptions(config);
    Duration sessionTimeout = nodeOptions.getSessionTimeout();

    // Refer to the foot notes for additional context on this line.
    Node node = LocalNodeFactory.create(config);

    DecoratedLoggingNode wrapper = new DecoratedLoggingNode(loggingOptions.getTracer(),
        node.getId(),
        uri,
        secretOptions.getRegistrationSecret(),
        sessionTimeout);
    wrapper.node = node;
    return wrapper;
  }

  @Override
  public Either<WebDriverException, CreateSessionResponse> newSession(
      CreateSessionRequest sessionRequest) {
    System.out.println("Before newSession()");
    try {
      return this.node.newSession(sessionRequest);
    } finally {
      System.out.println("After newSession()");
    }
  }

  @Override
  public HttpResponse executeWebDriverCommand(HttpRequest req) {
    try {
      System.out.println("Before executeWebDriverCommand(): " + req.getUri());
      return node.executeWebDriverCommand(req);
    } finally {
      System.out.println("After executeWebDriverCommand()");
    }
  }

  @Override
  public Session getSession(SessionId id) throws NoSuchSessionException {
    try {
      System.out.println("Before getSession()");
      return node.getSession(id);
    } finally {
      System.out.println("After getSession()");
    }
  }

  @Override
  public HttpResponse uploadFile(HttpRequest req, SessionId id) {
    try {
      System.out.println("Before uploadFile()");
      return node.uploadFile(req, id);
    } finally {
      System.out.println("After uploadFile()");
    }
  }

  @Override
  public void stop(SessionId id) throws NoSuchSessionException {
    try {
      System.out.println("Before stop()");
      node.stop(id);
    } finally {
      System.out.println("After stop()");
    }
  }

  @Override
  public boolean isSessionOwner(SessionId id) {
    try {
      System.out.println("Before isSessionOwner()");
      return node.isSessionOwner(id);
    } finally {
      System.out.println("After isSessionOwner()");
    }
  }

  @Override
  public boolean isSupporting(Capabilities capabilities) {
    try {
      System.out.println("Before isSupporting");
      return node.isSupporting(capabilities);
    } finally {
      System.out.println("After isSupporting()");
    }
  }

  @Override
  public NodeStatus getStatus() {
    try {
      System.out.println("Before getStatus()");
      return node.getStatus();
    } finally {
      System.out.println("After getStatus()");
    }
  }

  @Override
  public HealthCheck getHealthCheck() {
    try {
      System.out.println("Before getHealthCheck()");
      return node.getHealthCheck();
    } finally {
      System.out.println("After getHealthCheck()");
    }
  }

  @Override
  public void drain() {
    try {
      System.out.println("Before drain()");
      node.drain();
    } finally {
      System.out.println("After drain()");
    }

  }

  @Override
  public boolean isReady() {
    try {
      System.out.println("Before isReady()");
      return node.isReady();
    } finally {
      System.out.println("After isReady()");
    }
  }
}
```

***Notas de Rodapé:***

No exemplo acima, a linha `Node node = LocalNodeFactory.create(config);` cria explicitamente um `LocalNode`.

Basicamente, existem 2 tipos de implementações *visíveis para o usuário* de `org.openqa.selenium.grid.node.Node` disponíveis.

Essas classes são bons pontos de partida para aprender como criar um Node personalizado e também para compreender os detalhes internos de um Node.

* `org.openqa.selenium.grid.node.local.LocalNode` - Usado para representar um Node de execução contínua e é a implementação padrão que é usada quando você inicia um `node`.

  * Pode ser criado chamando `LocalNodeFactory.create(config);`, onde:

    * `LocalNodeFactory` pertence a `org.openqa.selenium.grid.node.local`
    * `Config` pertence a `org.openqa.selenium.grid.config`

* `org.openqa.selenium.grid.node.k8s.OneShotNode` - Esta é uma implementação de referência especial em que o Node encerra-se graciosamente após atender a uma sessão de teste. Esta classe atualmente não está disponível como parte de nenhum artefato Maven pré-construído.

  * Você pode consultar o código-fonte [aqui](https://github.com/SeleniumHQ/selenium/blob/trunk/java/src/org/openqa/selenium/grid/node/k8s/OneShotNode.java) para entender seus detalhes internos.

  * Para construí-lo localmente, consulte [aqui](https://github.com/SeleniumHQ/selenium/blob/trunk/deploys/k8s/README.md).

  * Pode ser criado chamando `OneShotNode.create(config)`, onde:

    * `OneShotNode` pertence a `org.openqa.selenium.grid.node.k8s`
    * `Config` pertence a `org.openqa.selenium.grid.config`

# 6.5 - External datastore

```sql
CREATE TABLE IF NOT EXISTS sessions_map(
    session_ids varchar(256),
    session_caps text,
    session_uri varchar(256),
    session_stereotype text,
    session_start varchar(256)
 );
```

* In the same directory as the `init.sql`, create a file named `docker-compose.yml` with its contents as below:

```yaml
version: '3.8'
services:
  db:
    image: postgres:9.6-bullseye
    restart: always
    environment:
      - POSTGRES_USER=seluser
      - POSTGRES_PASSWORD=seluser
      - POSTGRES_DB=selenium_sessions
    ports:
      - "5432:5432"
    volumes:
    - ./init.sql:/docker-entrypoint-initdb.d/init.sql
```

We can now start our database container by running:

```bash
docker-compose up -d
```

*Our database name is `selenium_sessions` with its username and password set to `seluser`*

If you are working with an already running PostGreSQL DB instance, then you just need to create a database named `selenium_sessions` and the table `sessions_map` using the above mentioned SQL statement.

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
implementation = "org.openqa.selenium.grid.sessionmap.jdbc.JdbcBackedSessionMap"
jdbc-url = "jdbc:postgresql://localhost:5432/selenium_sessions"
jdbc-user = "seluser"
jdbc-password = "seluser"
```

*Note:* If you plan to use an existing PostGreSQL DB instance, then replace `localhost:5432` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed Grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Sessions Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

```yaml
version: '3.8'
services:
  redis:
    image: redis:bullseye
    restart: always
    ports:
      - "6379:6379"
```

We can now start our Redis container by running:

```bash
docker-compose up -d
```

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
scheme = "redis"
implementation = "org.openqa.selenium.grid.sessionmap.redis.RedisBackedSessionMap"
hostname = "localhost"
port = 6379
```

*Note:* If you plan to use an existing Redis Cache instance, then replace `localhost` and `6379` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Session Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

* At this point the current directory should contain the following files:

  * `docker-compose.yml`
  * `sessions.toml`
  * `distributed.sh`

* You can now spawn the Grid by running `distributed.sh` shell script and quickly run a test. You will notice that the Grid now stores session information into the Redis instance. You can perhaps make use of a Redis GUI such as [TablePlus](https://tableplus.com/) to see them (Make sure that you have setup a debug point in your test, because the values will get deleted as soon as the test runs to completion).

In the line which spawns a `SessionMap` on a machine:

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

----
url: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/
----

# Understanding Common Errors

***

##### [Unable to Locate Driver Error](/documentation/webdriver/troubleshooting/errors/driver_location/)

Troubleshooting missing path to driver executable.

Last modified May 12, 2026: [docs: add Selenium Wait Generator to NoSuchElementException solutions (#2627) (a25fe46dcbf)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/a25fe46dcbfe2b07ccb95ec80923b9d94eadd12b)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/getting_started/
----

# Começando

Se você é novo no Selenium, nós temos alguns recursos que podem te ajudar a se atualizar imediatamente.

***

##### [Instalando bibliotecas do Selenium](/pt-br/documentation/webdriver/getting_started/install_library/)

Configurando a biblioteca Selenium para sua linguagem de programação favorita.

##### [Programe o seu primeiro script Selenium](/pt-br/documentation/webdriver/getting_started/first_script/)

Instruções passo a passo para programar um script Selenium

##### [Organizando e executando o código Selenium](/pt-br/documentation/webdriver/getting_started/using_selenium/)

Escalonamento da execução do Selenium com um IDE e uma biblioteca do Test Runner

Última modificação May 25, 2023: [Update how Selenium Manager is described (#1390)\[deploy site\] (d0124a479c0)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/d0124a479c035a44a9aed2aedc53f28dbe1e06c6)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/interactions/navigation/
----

# Browser navigation

```java
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L14-L18)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.get("https://www.selenium.dev/selenium/web/index.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L6)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Convenient
            driver.Url = "https://selenium.dev";
            //Longer
            driver.Navigate().GoToUrl("https://selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class NavigationTest
    {
        [TestMethod]
        public void TestNavigationCommands()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            //Convenient
            driver.Url = "https://selenium.dev";
            //Longer
            driver.Navigate().GoToUrl("https://selenium.dev");
            var title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Back
            driver.Navigate().Back();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Forward
            driver.Navigate().Forward();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Refresh
            driver.Navigate().Refresh();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Quit the browser
            driver.Quit();
        }
    }
}
```

```rb

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L7-L9)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L16-L20)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
//Convenient
driver.get("https://selenium.dev")

//Longer way
driver.navigate().to("https://selenium.dev")
  
```

```java
        //Back
        driver.navigate().back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L22-L23)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.back()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L11)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Back
             driver.Navigate().Back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L24-L25)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
    driver.navigate.to 'https://www.selenium.dev/'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L15)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Back
    await driver.navigate().back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L24-L25)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().back() 
```

```java
        //Forward
        driver.navigate().forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L27-L28)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.forward()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L15)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Forward
             driver.Navigate().Forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L29-L30)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L23)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Forward
    await driver.navigate().forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L29-L30)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().forward()
```

```java
        //Refresh
        driver.navigate().refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L32-L33)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.refresh()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L19)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Refresh
             driver.Navigate().Refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L34-L35)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
  it 'refreshes the page' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L29)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Refresh
    await driver.navigate().refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L34-L35)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().refresh()
```

----
url: https://www.selenium.dev/zh-cn/documentation/grid/architecture/
----

# Grid架构

|               | Event Bus | Distributor | Node | Router | Session Map | Session Queue |
| ------------- | --------- | ----------- | ---- | ------ | ----------- | ------------- |
| Event Bus     | X         |             |      |        |             |               |
| Distributor   | ✅         | X           | ✅    |        |             | ✅             |
| Node          | ✅         |             | X    |        |             |               |
| Router        |           |             | ✅    | X      | ✅           |               |
| Session Map   |           |             |      |        | X           |               |
| Session Queue | ✅         |             |      |        |             | X             |

| Name               | Type    | Description                                                                                                                                                                                                                                  |
| ------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| availability       | string  | A string which is one of `up`, `draining`, or `down`. The important one is `draining`, which indicates that no new sessions should be sent to the Node, and once the last session on it closes, the Node will exit or restart.               |
| externalUrl        | string  | The URI that the other components in the Grid should connect to.                                                                                                                                                                             |
| lastSessionCreated | integer | The epoch timestamp of when the last session was created on this Node. The Distributor will attempt to send new sessions to the Node that has been idle longest if all other things are equal.                                               |
| maxSessionCount    | integer | Although a session count can be inferred by counting the number of available slots, this integer value is used to determine the maximum number of sessions that should be running simultaneously on the Node before it is considered “full”. |
| nodeId             | string  | A UUID used to identify this instance of the Node.                                                                                                                                                                                           |
| osInfo             | object  | An object with `arch`, `name`, and `version` fields. This is used by the Grid UI and the GraphQL queries.                                                                                                                                    |
| slots              | array   | An array of Slot objects (described below)                                                                                                                                                                                                   |
| version            | string  | The version of the Node (for Selenium, this will match the Selenium version number)                                                                                                                                                          |

It is recommended to put values in all fields.

### The Slot Object

The Slot object represents a single slot within a Node. A “slot” is where a single session may be run. It is possible that a Node will have more slots than it can run concurrently. For example, a node may be able to run up 10 sessions, but they could be any combination of Chrome, Edge, or Firefox; in this case, the Node would indicate a “max session count” of 10, and then also say it has 10 slots for Chrome, 10 for Edge, and 10 for Firefox.

| Name        | Type   | Description                                                                                                                                                                  |
| ----------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id          | string | UUID to refer to the slot                                                                                                                                                    |
| lastStarted | string | When the slot last had a session started, in ISO-8601 format                                                                                                                 |
| stereotype  | object | The minimal set of [capabilities](https://w3c.github.io/webdriver/#dfn-merging-capabilities) this slot will match against. A minimal example is `{"browserName": "firefox"}` |
| session     | object | The Session object (see below)                                                                                                                                               |

### The Session Object

This represents a running session within a slot

| Name         | Type   | Description                                                                                                                                                                  |
| ------------ | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| capabilities | object | The actual capabilities provided by the session. Will match the return value from the [new session](https://w3c.github.io/webdriver/#new-session) command                    |
| startTime    | string | The start time of the session in ISO-8601 format                                                                                                                             |
| stereotype   | object | The minimal set of [capabilities](https://w3c.github.io/webdriver/#dfn-merging-capabilities) this slot will match against. A minimal example is `{"browserName": "firefox"}` |
| uri          | string | The URI used by the Node to communicate with the session                                                                                                                     |

----
url: https://www.selenium.dev/ja/_print/documentation/about/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/about/).

# このドキュメントについて

* 1: [著作権と帰属](#pg-696d6de7a5fb46c3733749ba95fec59d)
* 2: [Seleniumのサイトとドキュメントに貢献する](#pg-98096dd4fa123b18812cc5d432dcc327)
* 3: [Style guide for Selenium documentation](#pg-486e4cde1c97c265a2449db74535c03c)

これらのドキュメントは、コード自体と同様に、Seleniumコミュニティ内のボランティアによって100％維持されます。 当初から多くの人が使用してきましたが、多くの人が短期間しか使用しておらず、新しいユーザーのオンボーディングエクスペリエンスの改善に時間を割いてきました。

ドキュメントに問題がある場合、知りたいです！ 問題を伝える最良の方法は、[https://github.com/seleniumhq/seleniumhq.github.io/issues](//github.com/seleniumhq/seleniumhq.github.io/issues)にアクセスし、問題が既に報告されているかどうかを検索することです。 そうでない場合は、自由に開いてください！

コミュニティの多くのメンバーは、[Libera.chat](https://libera.chat/) で *#selenium* Liberaチャンネルに頻繁にアクセスします。 気軽に立ち寄って質問してください。 これらのドキュメントで役立つと思われるヘルプを受け取った場合は、必ず貢献を追加してください。 これらのドキュメントを更新することはできますが、通常のコミッター以外から投稿を受け取ると、誰にとってもずっと簡単になります。

# 1 - 著作権と帰属

| Software                            | Version  | License                                                     |
| ----------------------------------- | -------- | ----------------------------------------------------------- |
| [Hugo](/ja/)                        | v0.110.0 | [Apache 2.0](//gohugo.io/about/license/)                    |
| [Docsy](//github.com/google/docsy/) | —        | [Apache 2.0](//github.com/google/docsy/blob/master/LICENSE) |

## ライセンス

Seleniumプロジェクトから作成されたすべてのコードとドキュメントは、 Apache 2.0ライセンスに基づいてライセンスされており、 [Software Freedom Conservancy](/ja/) に著作権があります。

ライセンスは便宜上ここに含まれていますが、 [Apache FoundationのWebサイト](//apache.org/licenses/LICENSE-2.0.html)でも見つけることができます。

```markdown
                                 Apache License
                           Version 2.0, 2004年1月
                        http://www.apache.org/licenses/

   使用、複製、および頒布に関する条項

   1. 定義 　

      「ライセンス」とは、このドキュメントの第1項から第9項までで定義している、
      使用、複製、および頒布に関する条項を指します。

      「ライセンサー」とは、著作権所有者、あるいは著作権所有者が
      ライセンス付与対象として認めた者を指します。

      「法人」とは、行為者と、行為者を管理するか行為者により管理されるか
      行為者共通の管理下にある他のすべての者とから成る連合体を指します。
      この定義における「管理」とは、
      (i) 契約またはその他により、直接または間接的にこの法人の指揮・経営を行う権限、または
      (ii) この法人の50%以上の株式の所有権 または
      (iii) 受益所有権を有することを指します。

      「あなた」とは、本ライセンスにより付与される権利を行使する個人または法人を指します。

      「ソース」形式とは、ソフトウェアのソースコード、ドキュメントソース、
      設定ファイルといった、変更を加えるのに好都合な形式を指します。

      「オブジェクト」形式とは、コンパイルされたオブジェクトコード、生成されたドキュメント、
      他のメディアへの変換物といった、ソース形式の機械的な変換により生じる形式を指します。

      「成果物」とは、ソース形式であるとオブジェクト形式であるとを問わず、
      製作物に挿入または添付される（後出の付録に例がある）著作権表示で示された著作物で、
      本ライセンスに基づいて利用が許されるものを指します。

      「派生成果物」とは、編集上の改訂、注解、推敲など、
      成果物を基にしていて全体としてオリジナル著作物と呼べるような製作物全般を指します。
      本ライセンスでは、成果物や派生成果物から分離できる製作物や、
      成果物や派生成果物のインタフェースへの単なるリンク（または名前によるバインド）を、
      派生成果物に含めません。

      「コントリビューション」とは、成果物のオリジナルバージョンならびに成果物
      または派生成果物への変更や追加も含めて、著作権所有者あるいは著作権所有者が認めた
      個人または法人による成果物への組み込みを意図してライセンサーに提出される
      著作物全般を指します。
      この定義における「提出」とは、成果物を論じたり改良するためにライセンサー
      またはその代理者により管理される電子的メーリングリスト、ソースコード管理システム、
      問題追跡システムといった、電子的方法、口頭、または書面で、
      ライセンサーまたはその代理者に情報を送ることを指します。
      ただし、著作権所有者が書面で「コントリビューションでない」と明示したものは除きます。

      「コントリビューター」とは、ライセンサーおよびその代理を務める個人または法人で、
      自分のコントリビューションがライセンサーに受領されて成果物に組み込まれた者を指します。

   2. 著作権ライセンスの付与  
      本ライセンスの条項に従って、各コントリビューターはあなたに対し、
      ソース形式であれオブジェクト形式であれ、成果物および派生成果物を複製したり、
      派生成果物を作成したり、公に表示したり、公に実行したり、サブライセンスしたり、
      頒布したりする、無期限で世界規模で非独占的で使用料無料で取り消し不能な
      著作権ライセンスを付与します。

   3. 特許ライセンスの付与  
      本ライセンスの条項に従って、各コントリビューターはあなたに対し、
      成果物を作成したり、使用したり、販売したり、販売用に提供したり、
      インポートしたり、その他の方法で移転したりする、
      無期限で世界規模で非独占的で使用料無料で取り消し不能な
      （この項で明記したものは除く）特許ライセンスを付与します。
      ただし、このようなライセンスは、コントリビューターによって
      ライセンス可能な特許申請のうち、当該コントリビューターのコントリビューションを
      単独または該当する成果物と組み合わせて用いることで必然的に侵害されるものにのみ
      適用されます。
      あなたが誰かに対し、交差請求や反訴を含めて、
      成果物あるいは成果物に組み込まれたコントリビューションが
      直接または間接的な特許侵害に当たるとして特許訴訟を起こした場合、
      本ライセンスに基づいてあなたに付与された特許ライセンスは、
      そうした訴訟が正式に起こされた時点で終了するものとします。

   4. 再頒布  
      あなたは、ソース形式であれオブジェクト形式であれ、変更の有無に関わらず、
      以下の条件をすべて満たす限りにおいて、成果物またはその派生成果物のコピーを
      複製したり頒布したりすることができます。

      (a) 成果物または派生成果物の他の受領者に本ライセンスのコピーも渡すこと。

      (b) 変更を加えたファイルについては、あなたが変更したということが
      よくわかるような告知を入れること。

      (c) ソース形式の派生成果物を頒布する場合は、ソース形式の成果物に含まれている著作権、
      特許、商標、および帰属についての告知を、派生成果物のどこにも関係しないものは除いて、
      すべて派生成果物に入れること。

      (d) 成果物の一部として「NOTICE」に相当するテキストファイルが含まれている場合は、
      そうしたNOTICEファイルに含まれている帰属告知のコピーを、
      派生成果物のどこにも関係しないものは除いて、頒布する派生成果物に入れること。
      その際、次のうちの少なくとも1箇所に挿入すること。
      (i) 派生成果物の一部として頒布するNOTICEテキストファイル、
      (ii) ソース形式またはドキュメント（派生成果物と共にドキュメントを頒布する場合）、
      (iii) 派生成果物によって生成される表示
      （こうした第三者告知を盛り込むことが標準的なやり方になっている場合）。
      NOTICEファイルの内容はあくまで情報伝達用であって、
      本ライセンスを修正するものであってはなりません。
      あなたは頒布する派生成果物に自分の帰属告知を
      （成果物からのNOTICEテキストに並べて、またはその付録として）追加できますが、
      これはそうした追加の帰属告知が本ライセンスの修正と
      解釈されるおそれがない場合に限られます。

      あなたは自分の修正物に自らの著作権表示を追加することができ、
      自分の修正物の使用、複製、または頒布について、あるいはそうした派生成果物の全体について、
      付加的なライセンス条項または異なるライセンス条項を設けることができます。
      ただし、これは成果物についてのあなたの使用、複製、および頒布が、
      それ以外の点で本ライセンスの条項に従っている場合に限られます。

   5. コントリビューションの提出  
      特に断りがない限り、あなたが成果物への組み込みを意図してライセンサーに
      提出したコントリビューションは、付加的な条項がなければ、
      本ライセンスの条項に従うものとします。
      上述の規定にかかわらず、そうしたコントリビューションに関してあなたがライセンサーと
      結んだかもしれない別のライセンス契約の条項を、ここで無効にしたり
      修正したりすることはありません。

   6. 商標  
      本ライセンスでは、成果物の出所を記述したりNOTICEファイルの内容を複製するときに
      必要になる妥当で慣習的な使い方は別として、ライセンサーの商号、商標、サービスマーク、
      または製品名の使用権を付与しません。

   7. 保証の否認  
      適用される法律または書面での同意によって命じられない限り、
      ライセンサーは成果物を（そしてコントリビューターは各自のコントリビューションを）
      「現状のまま」提供するものとし、明示黙示を問わず、タイトル、非侵害性、
      商業的な使用可能性、および特定の目的に対する適合性を含め、
      いかなる保証も条件も提供しません。
      あなたは成果物の使用や再頒布の適切性を自分で判断する責任を持つと共に、
      本ライセンスにより付与される権利を行使することに伴うすべてのリスクを負うことになります。

   8. 責任の制限  
      いかなる条件および法理論においても、不法行為（過失を含む）、契約、
      またはその他いかなる場合でも、適用される法律または書面での同意によって命じられない限り、
      コントリビューターは本ライセンスまたは成果物の使い方に関連して生じる直接損害、
      間接損害、偶発的な損害、特別損害、懲罰的損害、または結果損害を含め、
      営業権の損失、業務の停止、コンピューター障害または誤作動、
      その他の商業上の損害や損失など、いかなる損害に対しても、
      たとえそうした損害の可能性をたとえ知らされていたとしても、
      あなたに責任を負わないものとします。

   9. 保証または追加的責任の引き受け  
      成果物またはその派生成果物を再頒布する際、あなたはサポート、保証、損害補償、
      またはその他の責任や、本ライセンスに矛盾しない権利を提示し、
      これを有料にすることができます。
      ただし、そうした責任を引き受ける場合、あなたはそれを自分自身のためにだけ
      自己責任として行えるのであって、他のコントリビューターのために行うことはできません。
      また、あなたはそうした保証や追加的責任のせいで他のコントリビューターに
      責任が降りかかったり賠償要求が出されたとしても、それらのコントリビューターに
      損害が及ぶのを防ぐと共に各コントリビューターの損害を補償することに同意しなければなりません。

   使用、複製、および頒布に関する条項の終わり

   付録： Apache Licenseの適用の仕方

      あなたの製作物にApache Licenseを適用するときは、次の定型文を添付してください。
      ただし、"[]"で囲まれている部分は、あなた自身の識別情報に置き換えてください
      （その際、角括弧は取り除きます）。
      また、この文言を該当するファイル形式に合ったコメント構文で囲んでください。
      さらに、第三者アーカイブ内での識別を容易にするため、
      ファイル名またはクラス名ならびに趣旨説明が著作権表示と同じ「印刷ページ」に
      現れるようにすることをお勧めします。

   Copyright [yyyy] [著作権所有者の名前]

   Apache License Version 2.0（「本ライセンス」）に基づいてライセンスされます。
   あなたがこのファイルを使用するためには、本ライセンスに従わなければなりません。
   本ライセンスのコピーは下記の場所から入手できます。

       http://www.apache.org/licenses/LICENSE-2.0

   適用される法律または書面での同意によって命じられない限り、
   本ライセンスに基づいて頒布されるソフトウェアは、明示黙示を問わず、
   いかなる保証も条件もなしに「現状のまま」頒布されます。
   本ライセンスでの権利と制限を規定した文言については、本ライセンスを参照してください。
```

# 2 - Seleniumのサイトとドキュメントに貢献する

Seleniumのドキュメントとコード例を改善するための情報

Seleniumは大きなソフトウェアプロジェクトであり、そのサイトとドキュメントは、物事の仕組みを理解し、その可能性を活用する効果的な方法を学ぶための鍵となります。

このプロジェクトには、Seleniumのサイトとドキュメントの両方が含まれています。これは、Seleniumを効果的に使用する方法、Seleniumに参加する方法、およびSeleniumに貢献する方法に関する最新情報を提供するための継続的な取り組みです（特定のリリースを対象としていません）。

サイトおよびドキュメントへの貢献は、以下のセクションで説明されているプロセスに従います。

***

```
    {{< tab header="Ruby" >}}
    {{< gh-codeblock path="/examples/ruby/spec/browsers/chrome_spec.rb#L8-L9" >}}
    {{< /tab >}}
```

```shell
% git clone git@github.com:seleniumhq/seleniumhq.github.io.git
% cd seleniumhq.github.io
```

#### 依存関係: Hugo

[Hugo](https://gohugo.io/)と[Docsyテーマ](https://www.docsy.dev/)を使用してサイトの構築とレンダリングをしています。このサイトの作業をするには、Hugoバイナリの“拡張”Sass/SCSSバージョンが必要です。Hugo 0.148.2の使用を推奨します。

[Docsyのインストール手順](https://www.docsy.dev/docs/getting-started/#install-hugo)に従ってください。

### ステップ 2: ブランチの作成

フィーチャーブランチを作成し、ハックを開始します。:

```shell
% git checkout -b my-feature-branch
```

我々はHEADベースの開発を行っています。つまり、全ての変更はtrunkブランチ上に直接適用されます。

### ステップ 3: 変更を加える

リポジトリにはサイトとドキュメントが含まれています。 変更を加える前に、submoduleを初期化し、必要な依存関係をインストールしてください（以下のコマンドを参照）。サイトに変更を加えるには、`website_and_docs` ディレクトリで作業してください。変更のライブプレビューを確認するには、サイトのルートディレクトリで `hugo server`を実行してください。

```shell
% git submodule update --init --recursive
% cd website_and_docs
% hugo server
```

寄稿に関する規約の詳細については、 [スタイルガイド](https://www.selenium.dev/ja/documentation/about/style/) をご覧ください。

### ステップ 4: コミット

まず、gitがあなたの名前とメールアドレスを知っていることを確認してください:

```shell
% git config --global user.name 'Santa Claus'
% git config --global user.email 'santa@example.com'
```

\*\*適切なコミットメッセージを書くことは重要です。\*\*コミットメッセージには、変更された内容、理由、修正されたイシューへの参照（ある場合）を記述する必要があります。作成するときは、次のガイドラインに従ってください。:

1. 最初の行は約50文字以下で、変更の簡単な説明を含める必要があります。
2. 2行目は空白のままにします。
3. 他のすべての行を72列で折り返します。
4. `Fixes #N`を含めてください。ここでは *N* がこのコミットで修正したイシュー番号です（存在する場合）。

適切なコミットメッセージは次のようになります:

```text
explain commit normatively in one line

Body of commit message is a few lines of text, explaining things
in more detail, possibly giving some background about the issue
being fixed, etc.

The body of the commit message can be several paragraphs, and
please do proper word-wrap and keep columns shorter than about
72 characters or so. That way `git log` will show things
nicely even when it is indented.

Fixes #141
```

最初の行は`git shortlog`や`git log --oneline`を実行した際に他人が最初に目にするため、意味のあるものでなければなりません。

### ステップ 5: リベース

あなたの作業を同期するため、(`git merge`ではなく)`git rebase`を時々実行してください。

```shell
% git fetch origin
% git rebase origin/trunk
```

### ステップ 6: テスト

あなたの変更が何も問題を起こしていないことを確認するため、常に忘れずに[ローカルサーバーの実行](https://gohugo.io/getting-started/usage/#livereload)を行ってください。

### ステップ 7: プッシュ

```shell
% git push origin my-feature-branch
```

<https://github.com/yourusername/seleniumhq.github.io.git> を開き、\_Pull Request\_を押し、フォームを入力してください。 **CLAに署名したことを示してください** (ステップ7を参照)

プルリクエストは通常数日以内にレビューされます。対応すべきコメントがある場合は、新しく(できれば [fixups](http://git-scm.com/docs/git-commit)で)コミットし、同じブランチにプッシュしてください。

### ステップ 8: 統合

コードレビューが完了すると、コミッターがPRを取得し、リポジトリのtrunkブランチに統合します。 マスターブランチで履歴を線形に保持するのが好きなので、通常はブランチの履歴をスカッシュしてリベースします。

## コミュニケーション

プロジェクトのコントリビューターおよびコミュニティ全体と交流する方法については、全て <https://selenium.dev/support> で詳細が記載されています。

# 3 - Style guide for Selenium documentation

Conventions for contributions to the Selenium documentation and code examples

Read our [contributing documentation](https://www.selenium.dev/ja/documentation/about/contributing/) for complete instructions on how to add content to this documentation.

## Alerts

Alerts have been added to direct potential contributors to where specific content is missing.

```html
{{< alert-content />}}
```

or

```html
{{< alert-content >}}
Additional information about what specific content is needed
{{< /alert-content >}}
```

```java
WebDriver driver = new ChromeDriver();
```

```python
driver = webdriver.Chrome()
```

```csharp
var driver = new ChromeDriver();
```

```ruby
driver = Selenium::WebDriver.for :chrome
```

```javascript
let driver = await new Builder().forBrowser('chrome').build();
```

```kotlin
val driver = ChromeDriver()
```

To generate the above tabs, this is what you need to write. Note that the `tabpane` includes `langEqualsHeader=true`. This auto-formats the code in each tab to match the header name, and ensures that all tabs on the page with a language are set to the same thing.

```
{{< tabpane langEqualsHeader=true >}}
  {{< tab header="Java" >}}
    WebDriver driver = new ChromeDriver();
  {{< /tab >}}
  {{< tab header="Python" >}}
    driver = webdriver.Chrome()
  {{< /tab >}}
  {{< tab header="CSharp" >}}
    var driver = new ChromeDriver();
  {{< /tab >}}
  {{< tab header="Ruby" >}}
    driver = Selenium::WebDriver.for :chrome
  {{< /tab >}}
  {{< tab header="JavaScript" >}}
    let driver = await new Builder().forBrowser('chrome').build();
  {{< /tab >}}
  {{< tab header="Kotlin" >}}
    val driver = ChromeDriver()
  {{< /tab >}}
{{< /tabpane >}}
```

#### Reference GitHub Examples

To ensure that all code is kept up to date, our goal is to write the code in the repo where it can be executed when Selenium versions are updated to ensure that everything is correct.

All code examples to be in our [example directories](https://github.com/SeleniumHQ/seleniumhq.github.io/tree/dev/examples).

This code can be automatically displayed in the documentation using the `gh-codeblock` shortcode. The shortcode automatically generates its own html, so we do not want it to auto-format with the language header. If all tabs are using this shortcode, set `text=true` in the `tabpane` and remove `langEqualsHeader=true`. If only some tabs are using this shortcode, keep `langEqualsHeader=true` in the `tabpane` and add `text=true` to the `tab`. Note that the `gh-codeblock` line can not be indented at all.

One great thing about using `gh-codeblock` is that it adds a link to the full example. This means you don’t have to include any additional context code, just the line(s) that are needed, and the user can navigate to the repo to see how to use it.

A basic comparison of code looks like:

```
{{< tabpane text=true >}}
{{< tab header="Java" >}}
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-L27" >}}
{{< /tab >}}
{{< tab header="Python" >}}
{{< gh-codeblock path="/examples/python/tests/getting_started/first_script.py#L18-L19" >}}
{{< /tab >}}
{{< tab header="CSharp" >}}
{{< gh-codeblock path="/examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-L26" >}}
{{< /tab >}}
{{< tab header="Ruby" >}}
{{< gh-codeblock path="/examples/ruby/spec/getting_started/first_script.rb#L17-L18" >}}
{{< /tab >}}
{{< tab header="JavaScript" >}}
{{< gh-codeblock path="/examples/javascript/test/getting_started/firstScript.spec.js#L22-L23" >}}
{{< /tab >}}
{{< tab header="Kotlin" >}}
{{< gh-codeblock path="/examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-L32" >}}
{{< /tab >}}
{{< /tabpane >}}
```

```java
        WebElement message = driver.findElement(By.id("message"));
        message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-L27)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
message = driver.find_element(by=By.ID, value="message")
text = message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L18-L19)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-L26)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
message = driver.find_element(id: 'message')
message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L17-L18)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L22-L23)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val message = driver.findElement(By.id("message"))
        val value = message.getText()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-L32)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

### Using Markdown in a Tab

If you want your example to include something other than code (default) or html (from `gh-codeblock`), you need to first set `text=true`, then change the Hugo syntax for the `tab`to use `%` instead of `<` and `>` with curly braces:

```
{{< tabpane text=true >}}
{{% tab header="Java" %}}
1. Start the driver
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12" >}}
2. Navigate to a page
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14" >}}
3. Quit the driver
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29" >}}
{{% /tab %}}
< ... >
{{< /tabpane >}}
```

This produces:

*

1. Start the driver

   ```java
           WebDriver driver = new ChromeDriver();
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

2. Navigate to a page

   ```java
           driver.get("https://www.selenium.dev/selenium/web/web-form.html");
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

3. Quit the driver

   ```java
           driver.quit();
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

----
url: https://www.selenium.dev/documentation/webdriver/support_features/select_lists/
----

# Working with select list elements

```html
<select name="selectomatic">
    <option selected="selected" id="non_multi_option" value="one">One</option>
    <option value="two">Two</option>
    <option value="four">Four</option>
    <option value="still learning how to count, apparently">Still learning how to count, apparently</option>
</select>
```

### Multiple select

This select list allows selecting and deselecting more than one option at a time. This only applies to `<select>` elements with the `multiple` attribute.

```html
<select name="multi" id="multi" multiple="multiple">
    <option selected="selected" value="eggs">Eggs</option>
    <option value="ham">Ham</option>
    <option selected="selected" value="sausages">Sausages</option>
    <option value="onion gravy">Onion gravy</option>
</select>
```

```java
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L23-L24)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L9-L10)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L23-L24)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L13-L14)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js

  it('Select an option', async function () {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L18-L19)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L20-L21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        List<WebElement> optionList = select.getOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L51)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    option_list = select.options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L37)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            IList<IWebElement> optionList = select.Options;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L52)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    option_list = select.options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L40)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L45)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val optionList = select.getOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L48)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L54)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    selected_option_list = select.all_selected_options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L40)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L56)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    selected_option_list = select.selected_options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L43)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L51)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val selectedOptionList = select.getAllSelectedOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L51)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByVisibleText("Four");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L30)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_visible_text('Four')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L16)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByText("Four");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L30)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:text, 'Four')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L20)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L25)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByVisibleText("Four")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L27)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByValue("two");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L33)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_value('two')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L19)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByValue("two");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L33)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:value, 'two')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L23)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await fourElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L28)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByValue("two")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L30)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByIndex(3);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L36)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_index(3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L22)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByIndex(3);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L36)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:index, 3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L26)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await twoElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L31)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByIndex(3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L33)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

### Disabled options

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

Options with a `disabled` attribute may not be selected.

```html
    <select name="single_disabled">
      <option id="sinlge_disabled_1" value="enabled">Enabled</option>
      <option id="sinlge_disabled_2" value="disabled" disabled="disabled">Disabled</option>
    </select>
```

*
*
*
*
*
*

```java
        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L77-L79)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L60-L61)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L77)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L62-L64)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L73-L76)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L74-L76)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.deselectByValue("eggs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L66)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.deselect_by_value('eggs')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L49)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.DeselectByValue("eggs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L65)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.deselect_by(:value, 'eggs')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L52)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await gravyElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L63)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.deselectByValue("eggs")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

----
url: https://www.selenium.dev/documentation/test_practices/encouraged/avoid_sharing_state/
----

# Avoid sharing state

Although mentioned in several places, it is worth mentioning again. We must ensure that the tests are isolated from one another.

* Do not share test data. Imagine several tests that each query the database for valid orders before picking one to perform an action on. Should two tests pick up the same order you are likely to get unexpected behavior.

* Clean up stale data in the application that might be picked up by another test e.g. invalid order records.

* Create a new WebDriver instance per test. This helps ensure test isolation and makes parallelization simpler.

  * If you choose [pytest](https://pytest.org/) as your test runner, this can be easily done by yielding your driver in a global fixture. This way each test gets its own driver instance, and you can ensure that drivers always quit after a test is finished (pass or fail).

Last modified September 23, 2024: [Added more detail to Avoid Sharing State Documentation (#1948)\[deploy site\] (e1fa2da1696)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e1fa2da1696971bd7e22f613dce09a8934fd56ff)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/support_features/select_lists/
----

# 使用选择列表元素

```html
<select name="selectomatic">
    <option selected="selected" id="non_multi_option" value="one">One</option>
    <option value="two">Two</option>
    <option value="four">Four</option>
    <option value="still learning how to count, apparently">Still learning how to count, apparently</option>
</select>
```

### 复选

此选择列表允许同时选定和取消选择多个选项. 这仅适用于具有 `multiple` 属性的 `<select>`元素.

```html
<select name="multi" id="multi" multiple="multiple">
    <option selected="selected" value="eggs">Eggs</option>
    <option value="ham">Ham</option>
    <option selected="selected" value="sausages">Sausages</option>
    <option value="onion gravy">Onion gravy</option>
</select>
```

```java
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L23-L24)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L9-L10)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L23-L24)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L13-L14)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js

  it('Select an option', async function () {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L18-L19)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L20-L21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        List<WebElement> optionList = select.getOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L51)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    option_list = select.options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L37)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            IList<IWebElement> optionList = select.Options;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L52)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    option_list = select.options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L40)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L45)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val optionList = select.getOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L48)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L54)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    selected_option_list = select.all_selected_options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L40)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L56)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    selected_option_list = select.selected_options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L43)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L51)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val selectedOptionList = select.getAllSelectedOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L51)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByVisibleText("Four");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L30)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_visible_text('Four')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L16)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByText("Four");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L30)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:text, 'Four')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L20)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L25)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByVisibleText("Four")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L27)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByValue("two");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L33)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_value('two')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L19)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByValue("two");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L33)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:value, 'two')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L23)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await fourElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L28)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByValue("two")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L30)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByIndex(3);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L36)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_index(3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L22)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByIndex(3);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L36)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:index, 3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L26)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await twoElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L31)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByIndex(3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L33)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

### 禁用的选项

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

具有 `disabled` 属性的选项可能无法被选择.

```html
    <select name="single_disabled">
      <option id="sinlge_disabled_1" value="enabled">Enabled</option>
      <option id="sinlge_disabled_2" value="disabled" disabled="disabled">Disabled</option>
    </select>
```

*
*
*
*
*
*

```java
        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L77-L79)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L60-L61)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L77)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L62-L64)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L73-L76)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L74-L76)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.deselectByValue("eggs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L66)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.deselect_by_value('eggs')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L49)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.DeselectByValue("eggs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L65)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.deselect_by(:value, 'eggs')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L52)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await gravyElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L63)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.deselectByValue("eggs")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

----
url: https://www.selenium.dev/zh-cn/documentation/legacy/selenium_3/grid_3/
----

# 服务网格 3

Selenium Grid 3 supported WebDriver without Selenium RC code. Grid 3 was completely rewritten for the new Grid 4.

[服务网格 4](https://www.selenium.dev/zh-cn/documentation/grid/)

**Most of the documentation found in this section is still in English. Please note we are not accepting pull requests to translate this content as translating documentation of legacy components does not add value to the community nor the project.

*Selenium服务网格* 是一个能够让Selenium的测试把命令传送到一个远程浏览器实例的职能代理服务器。 他的目的是提供一个简便的方法来在多台终端上并行的执行测试任务。

在Selenium服务网格, 一台服务器作为转发器(hub)将JSON格式的测试命令转发到1台或多台注册的节点。 测试任务通过跟转发器(hub)的交互来操作远端浏览器实例。 转发器(hub)维护了一个可供使用的注册服务器列表，也允许我们通过转发器(hub)来控制这些实例。

Selenium服务网格允许我们在多台节点服务器上并行执行测试， 同时也中心化的管理多个浏览器版本，多种浏览器的配置。（以替代传统的基于个人的测试）

Selenium服务网格并不是万能的(silver bullet)。 它能够解决一些通用的代理问题和分布式的问题，但是并不能管理你的硬件，也可能不适合你的一些特殊需求。

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/encouraged/test_independency/
----

# 测试的独立性

将每个测试编写为独立的单元. 以不依赖于其他测试完成的方式编写测试:

例如有一个内容管理系统, 您可以借助其创建一些自定义内容, 这些内容在发布后作为模块显示在您的网站上, 并且CMS和应用程序之间的同步可能需要一些时间.

测试模块的一种错误方法是在测试中创建并发布内容, 然后在另一测试中检查该模块. 这是不可取的, 因为发布后内容可能无法立即用于其他测试.

与之相反的事, 您可以创建在受影响的测试中打开和关闭的打桩内容, 并将其用于验证模块. 而且, 对于内容的创建, 您仍然可以进行单独的测试.

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/
----

# 鼓励的行为

Selenium项目的一些测试指南和建议.

关于"最佳实践"的注解：我们有意在本文档中避免使用"最佳实践"的说辞. 没有一种方法可以适用于所有情况. 我们更喜欢"指南和建议"的想法. 我们鼓励您通读这些内容, 并仔细地确定哪种方法适用于您的特定环境.

由于许多原因, 功能测试很难正确完成. 即便应用程序的状态, 复杂性, 依赖还不够让测试变得 足够复杂, 操作浏览器（特别是跨浏览器的兼容性测试）就已经使得写一个好的测试变成一种挑战.

Selenium提供了一些工具使得功能测试用户更简单的操作浏览器, 但是这些工具并不能帮助你来写一个好的 架构的测试套件. 这章我们会针对怎么来做web页面的功能测试的自动化给出一些忠告, 指南和建议.

这章记录了很多历年来成功的使用Selenium的用户的常用的软件设计模式.

***

##### [测试自动化概述](/zh-cn/documentation/test_practices/overview/)

##### [设计模式和开发策略](/zh-cn/documentation/test_practices/design_strategies/)

##### [测试类型](/zh-cn/documentation/test_practices/testing_types/)

##### [指南和建议](/zh-cn/documentation/test_practices/encouraged/)

Selenium项目的一些测试指南和建议.

##### [不鼓励的行为](/zh-cn/documentation/test_practices/discouraged/)

使用Selenium自动化浏览器时应避免的事项.

----
url: https://www.selenium.dev/_print/documentation/webdriver/troubleshooting/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/webdriver/troubleshooting/).

# Troubleshooting Assistance

How to solve WebDriver problems.

* 1: [Understanding Common Errors](#pg-9106a7ac709cadefdb6e4b92e9e3ceaf)
* * 1.1: [Unable to Locate Driver Error](#pg-5a7d28a8d143d2eaa2a6727d561e2164)
  2: [Logging Selenium commands](#pg-c3c0247352991805196d78aee006d449)
* 3: [Upgrade to Selenium 4](#pg-202cde4f2eb02e51a6fc41ee11778402)

It is not always obvious the root cause of errors in Selenium.

1. The most common Selenium-related error is a result of poor synchronization. Read about [Waiting Strategies](https://www.selenium.dev/documentation/webdriver/waits/). If you aren’t sure if it is a synchronization strategy you can try *temporarily* hard coding a large sleep where you see the issue, and you’ll know if adding an explicit wait can help.

2. Note that many errors that get reported to the project are actually caused by issues in the underlying drivers that Selenium sends the commands to. You can rule out a driver problem by executing the command in multiple [browsers](https://www.selenium.dev/documentation/webdriver/browsers/).

3. If you have questions about how to do things, check out the [Support options](/support/) for ways get assistance.

4. If you think you’ve found a problem with Selenium code, go ahead and file a [Bug Report](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=I-defect%2Cneeds-triaging\&template=bug-report.yml\&title=%5B%F0%9F%90%9B+Bug%5D%3A+) on GitHub.

# 1 - Understanding Common Errors

# 1.1 - Unable to Locate Driver Error

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.bash_profile
source ~/.bash_profile
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Terminal and execute:

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.zshenv
source ~/.zshenv
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Command Prompt and execute:

```shell
echo %PATH%
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
setx PATH "%PATH%;C:\WebDriver\bin"
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver.exe --version
```

| Browser           | Supported OS                | Maintained by    | Download                                                                     | Issue Tracker                                             |
| ----------------- | --------------------------- | ---------------- | ---------------------------------------------------------------------------- | --------------------------------------------------------- |
| Chromium/Chrome   | Windows/macOS/Linux         | Google           | [Downloads](/downloads/)                                                     | [Issues](//bugs.chromium.org/p/chromedriver/issues/list)  |
| Firefox           | Windows/macOS/Linux         | Mozilla          | [Downloads](//github.com/mozilla/geckodriver/releases)                       | [Issues](//github.com/mozilla/geckodriver/issues)         |
| Edge              | Windows/macOS/Linux         | Microsoft        | [Downloads](//developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/) | [Issues](//github.com/MicrosoftEdge/EdgeWebDriver/issues) |
| Internet Explorer | Windows                     | Selenium Project | [Downloads](/downloads/)                                                     | [Issues](//github.com/SeleniumHQ/selenium/labels/D-IE)    |
| Safari            | macOS High Sierra and newer | Apple            | Built in                                                                     | [Issues](//bugreport.apple.com/logon)                     |

```java
    public void logging() throws IOException {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Java Logging is not exactly straightforward, and if you are just looking for an easy way to look at the important Selenium logs, take a look at the [Selenium Logger project](https://github.com/titusfortner/selenium-logger#selenium-logger)

Python logs are typically created per module. You can match all submodules by referencing the top level module. So to work with all loggers in selenium module, you can do this:

```py
    logger = logging.getLogger('selenium')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L5)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

You must also create and add a log handler (`StreamHandler`, `FileHandler`, etc).

To save logs to a file, you can do this:

```py
log_path = '/path/to/log'
handler = logging.FileHandler(log_path)
logger.addHandler(handler)
```

To display logs in the console, you can do this:

```py
handler = logging.StreamHandler()
logger.addHandler(handler)
```

.NET logger is managed with a static class, so all access to logging is managed simply by referencing `Log` from the `OpenQA.Selenium.Internal.Logging` namespace.

If you want to see as much debugging as possible in all the classes, you can turn on debugging globally in Ruby by setting `$DEBUG = true`.

For more fine-tuned control, Ruby Selenium created its own Logger class to wrap the default `Logger` class. This implementation provides some interesting additional features. Obtain the logger directly from the `#logger`class method on the `Selenium::WebDriver` module:

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
    logger = Selenium::WebDriver.logger
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L11)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

```javascript
const logging = require('selenium-webdriver/lib/logging')
logger = logging.getLogger('webdriver')
```

```java
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L32-L35)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Python has 6 logger levels: `CRITICAL`, `ERROR`, `WARNING`, `INFO`, `DEBUG`, and `NOTSET`. The default is `WARNING`

To change the level of the logger:

```py
    logger.setLevel(logging.DEBUG)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L7)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

Things get complicated when you use PyTest, though. By default, PyTest hides logging unless the test fails. You need to set 3 things to get PyTest to display logs on passing tests.

To always output logs with PyTest you need to run with additional arguments. First, `-s` to prevent PyTest from capturing the console. Second, `-p no:logging`, which allows you to override the default PyTest logging settings so logs can be displayed regardless of errors.

So you need to set these flags in your IDE, or run PyTest on command line like:

```bash
pytest -s -p no:logging
```

Finally, since you turned off logging in the arguments above, you now need to add configuration to turn it back on:

```py
logging.basicConfig(level=logging.WARN)
```

.NET has 6 logger levels: `Error`, `Warn`, `Info`, `Debug`, `Trace` and `None`. The default level is `Warn`.

To change the level of the logger:

```cs
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L18)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

Ruby logger has 5 logger levels: `:debug`, `:info`, `:warn`, `:error`, `:fatal`. The default is `:info`.

To change the level of the logger:

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
    logger.level = :debug
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L13)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

JavaScript has 9 logger levels: `OFF`, `SEVERE`, `WARNING`, `INFO`, `DEBUG`, `FINE`, `FINER`, `FINEST`, `ALL`. The default is `OFF`.

To change the level of the logger:

```javascript
logger.setLevel(logging.Level.INFO)
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
WARNING: this is a warning
```

Python logs actionable content at logger level — `WARNING` Details about deprecations are logged at this level.

Example:

```text
WARNING  selenium:test_logging.py:23 this is a warning
```

.NET logs actionable content at logger level `Warn`.

Example:

```text
11:04:40.986 WARN LoggingTest: this is a warning
```

Ruby logs actionable content at logger level — `:warn`. Details about deprecations are logged at this level.

For example:

```text
2023-05-08 20:53:13 WARN Selenium [:example_id] this is a warning 
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
INFO: this is useful information
```

Python logs useful information at logger level — `INFO`

Example:

```text
INFO     selenium:test_logging.py:22 this is useful information
```

.NET logs useful information at logger level `Info`.

Example:

```text
11:04:40.986 INFO LoggingTest: this is useful information
```

Ruby logs useful information at logger level — `:info`.

Example:

```text
2023-05-08 20:53:13 INFO Selenium [:example_id] this is useful information 
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
FINE: this is detailed debug information
```

Python logs debugging details at logger level — `DEBUG`

Example:

```text
DEBUG    selenium:test_logging.py:24 this is detailed debug information
```

.NET logs most debug content at logger level `Debug`.

Example:

```text
11:04:40.986 DEBUG LoggingTest: this is detailed debug information
```

Ruby only provides one level for debugging, so all details are at logger level — `:debug`.

Example:

```text
2023-05-08 20:53:13 DEBUG Selenium [:example_id] this is detailed debug information 
```

```java

      Path output = artifactsDir().resolve("selenium.xml");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L37-L38)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

By default all logs are sent to `sys.stderr`. To direct output somewhere else, you need to add a handler with either a `StreamHandler` or a `FileHandler`:

```py
    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L9-L10)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

By default all logs are sent to `System.Console.Error` output. To direct output somewhere else, you need to add a handler with a `FileLogHandler`:

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L20)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

By default, logs are sent to the console in `stdout`.\
To store the logs in a file:

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
    logger.output = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L15)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

JavaScript does not currently support sending output to a file.

To send logs to console output:

```javascript
logging.installConsoleHandler()
```

```java
        logger.addHandler(handler);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L40-L41)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Because logging is managed by module, instead of working with just "selenium", you can specify different levels for different modules:

```py
    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L12-L13)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

.NET logging is managed on a per class level, set the level you want to use on a per-class basis:

```cs

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

Ruby’s logger allows you to opt in (“allow”) or opt out (“ignore”) of log messages based on their IDs. Everything that Selenium logs includes an ID. You can also turn on or off all deprecation notices by using `:deprecations`.

These methods accept one or more symbols or an array of symbols:

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
    logger.ignore(:jwp_caps, :logger_info)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#17)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

or

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
    logger.allow(%i[selenium_manager example_id])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L18)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

# 3 - Upgrade to Selenium 4

```java
DesiredCapabilities caps = DesiredCapabilities.firefox();
caps.setCapability("platform", "Windows 10");
caps.setCapability("version", "92");
caps.setCapability("build", myTestBuild);
caps.setCapability("name", myTestName);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), caps);
```

```javascript
caps = {};
caps['browserName'] = 'Firefox';
caps['platform'] = 'Windows 10';
caps['version'] = '92';
caps['build'] = myTestBuild;
caps['name'] = myTestName;
```

```csharp
DesiredCapabilities caps = new DesiredCapabilities();
caps.SetCapability("browserName", "firefox");
caps.SetCapability("platform", "Windows 10");
caps.SetCapability("version", "92");
caps.SetCapability("build", myTestBuild);
caps.SetCapability("name", myTestName);
var driver = new RemoteWebDriver(new Uri(CloudURL), caps);
```

```rb
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L123-L130)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```python
caps = {}
caps['browserName'] = 'firefox'
caps['platform'] = 'Windows 10'
caps['version'] = '92'
caps['build'] = my_test_build
caps['name'] = my_test_name
driver = webdriver.Remote(cloud_url, desired_capabilities=caps)
```

```java
FirefoxOptions browserOptions = new FirefoxOptions();
browserOptions.setPlatformName("Windows 10");
browserOptions.setBrowserVersion("92");
Map<String, Object> cloudOptions = new HashMap<>();
cloudOptions.put("build", myTestBuild);
cloudOptions.put("name", myTestName);
browserOptions.setCapability("cloud:options", cloudOptions);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), browserOptions);
```

```javascript
capabilities = {
  browserName: 'firefox',
  browserVersion: '92',
  platformName: 'Windows 10',
  'cloud:options': {
     build: myTestBuild,
     name: myTestName,
  }
}
```

```csharp
var browserOptions = new FirefoxOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "92";
var cloudOptions = new Dictionary<string, object>();
cloudOptions.Add("build", myTestBuild);
cloudOptions.Add("name", myTestName);
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);
var driver = new RemoteWebDriver(new Uri(CloudURL), browserOptions);
```

```rb
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L38-L47)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```python
from selenium.webdriver.firefox.options import Options as FirefoxOptions
options = FirefoxOptions()
options.browser_version = '92'
options.platform_name = 'Windows 10'
cloud_options = {}
cloud_options['build'] = my_test_build
cloud_options['name'] = my_test_name
options.set_capability('cloud:options', cloud_options)
driver = webdriver.Remote(cloud_url, options=options)
```

### Find element(s) utility methods in Java

The utility methods to find elements in the Java bindings (`FindsBy` interfaces) have been removed as they were meant for internal use only. The following code samples explain this better.

Finding a single element with `findElement*`

Before

```java

driver.findElementByClassName("className");
driver.findElementByCssSelector(".className");
driver.findElementById("elementId");
driver.findElementByLinkText("linkText");
driver.findElementByName("elementName");
driver.findElementByPartialLinkText("partialText");
driver.findElementByTagName("elementTagName");
driver.findElementByXPath("xPath");
```

After

```java

driver.findElement(By.className("className"));
driver.findElement(By.cssSelector(".className"));
driver.findElement(By.id("elementId"));
driver.findElement(By.linkText("linkText"));
driver.findElement(By.name("elementName"));
driver.findElement(By.partialLinkText("partialText"));
driver.findElement(By.tagName("elementTagName"));
driver.findElement(By.xpath("xPath"));
```

Finding a multiple elements with `findElements*`

Before

```java

driver.findElementsByClassName("className");
driver.findElementsByCssSelector(".className");
driver.findElementsById("elementId");
driver.findElementsByLinkText("linkText");
driver.findElementsByName("elementName");
driver.findElementsByPartialLinkText("partialText");
driver.findElementsByTagName("elementTagName");
driver.findElementsByXPath("xPath");
```

After

```java

driver.findElements(By.className("className"));
driver.findElements(By.cssSelector(".className"));
driver.findElements(By.id("elementId"));
driver.findElements(By.linkText("linkText"));
driver.findElements(By.name("elementName"));
driver.findElements(By.partialLinkText("partialText"));
driver.findElements(By.tagName("elementTagName"));
driver.findElements(By.xpath("xPath"));
```

## Upgrading dependencies

Check the subsections below to install Selenium 4 and have your project dependencies upgraded.

### Java

The process of upgrading Selenium depends on which build tool is being used. We will cover the most common ones for Java, which are [Maven](https://maven.apache.org/) and [Gradle](https://gradle.org/). The minimum Java version required is still 8.

#### Maven

Before

```xml

<dependencies>
  <!-- more dependencies ... -->
  <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.141.59</version>
  </dependency>
  <!-- more dependencies ... -->
</dependencies>
```

After

```xml

<dependencies>
    <!-- more dependencies ... -->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.4.0</version>
    </dependency>
    <!-- more dependencies ... -->
</dependencies>
```

After making the change, you could execute `mvn clean compile` on the same directory where the `pom.xml` file is.

#### Gradle

Before

```jsonpath

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.141.59'
}
test {
    useJUnitPlatform()
}
```

After

```jsonpath

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '4.4.0'
}
test {
    useJUnitPlatform()
}
```

After making the change, you could execute `./gradlew clean build` on the same directory where the `build.gradle` file is.

To check all the Java releases, you can head to [MVNRepository](https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java).

### C\#

The place to get updates for Selenium 4 in C# is [NuGet](https://www.nuget.org/). Under the [`Selenium.WebDriver`](https://www.nuget.org/packages/Selenium.WebDriver/4.4.0) package you can get the instructions to update to the latest version. Inside of Visual Studio, through the NuGet Package Manager you can execute:

```shell
PM> Install-Package Selenium.WebDriver -Version 4.4.0
```

### Python

The most important change to use Python is the minimum required version. Selenium 4 will require a minimum Python 3.7 or higher. More details can be found at the [Python Package Index](https://pypi.org/project/selenium/4.4.3/). To upgrade from the command line, you can execute:

```shell
pip install selenium==4.4.3
```

### Ruby

The update details for Selenium 4 can be seen at the [selenium-webdriver](https://rubygems.org/gems/selenium-webdriver/versions/4.4.0) gem in RubyGems. To install the latest version, you can execute:

```shell
gem install selenium-webdriver
```

To add it to your Gemfile:

```shell
gem 'selenium-webdriver', '~> 4.4.0'
```

### JavaScript

The selenium-webdriver package can be found at the Node package manager, [npmjs](https://www.npmjs.com). Selenium 4 can be found [here](https://www.npmjs.com/package/selenium-webdriver/v/4.4.0). To install it, you could either execute:

```shell
npm install selenium-webdriver
```

Or, update your package.json and run` npm install`:

```json
{
  "name": "selenium-tests",
  "version": "1.0.0",
  "dependencies": {
    "selenium-webdriver": "^4.4.0"
  }
}
```

## Potential errors and deprecation messages

Here is a set of code examples that will help to overcome the deprecation messages you might encounter after upgrading to Selenium 4.

### Java

#### Waits and Timeout

The parameters received in Timeout have switched from expecting `(long time, TimeUnit unit)` to expect `(Duration duration)`.

Before

```java

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(2, TimeUnit.MINUTES);
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
```

After

```java

driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().timeouts().scriptTimeout(Duration.ofMinutes(2));
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
```

Waits are also expecting different parameters now. `WebDriverWait` is now expecting a `Duration` instead of a `long` for timeout in seconds and milliseconds. The `withTimeout` and `pollingEvery` utility methods from `FluentWait` have switched from expecting `(long time, TimeUnit unit)` to expect `(Duration duration)`.

Before

```java

new WebDriverWait(driver, 3)
.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(30, TimeUnit.SECONDS)
  .pollingEvery(5, TimeUnit.SECONDS)
  .ignoring(NoSuchElementException.class);
```

After

```java

new WebDriverWait(driver, Duration.ofSeconds(3))
  .until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

  Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(Duration.ofSeconds(30))
  .pollingEvery(Duration.ofSeconds(5))
  .ignoring(NoSuchElementException.class);
```

#### Merging capabilities is no longer changing the calling object

It was possible to merge a different set of capabilities into another set, and it was mutating the calling object. Now, the result of the merge operation needs to be assigned.

Before

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options.merge(capabilities);

// As a result, the `options` object was getting modified.
```

After

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options = options.merge(capabilities);

// The result of the `merge` call needs to be assigned to an object.
```

#### Firefox Legacy

Before GeckoDriver was around, the Selenium project had a driver implementation to automate Firefox (version <48). However, this implementation is not needed anymore as it does not work in recent versions of Firefox. To avoid major issues when upgrading to Selenium 4, the `setLegacy` option will be shown as deprecated. The recommendation is to stop using the old implementation and rely only on GeckoDriver. The following code will show the `setLegacy` line deprecated after upgrading.

```java
FirefoxOptions options = new FirefoxOptions();
options.setLegacy(true);
```

#### `BrowserType`

The `BrowserType` interface has been around for a long time, however it is getting deprecated in favour of the new `Browser` interface.

Before

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", BrowserType.FIREFOX);
```

After

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", Browser.FIREFOX);
```

### C\#

#### `AddAdditionalCapability` is deprecated

Instead of it, `AddAdditionalOption` is recommended. Here is an example showing this:

Before

```cs

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalCapability("cloud:options", cloudOptions, true);
```

After

```cs

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);
```

### Python

#### `executable_path has been deprecated, please pass in a Service object`

In Selenium 4, you’ll need to set the driver’s `executable_path` from a Service object to prevent deprecation warnings. (Or don’t set the path and instead make sure that the driver you need is on the System PATH.)

Before

```python

from selenium import webdriver
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(
    executable_path=CHROMEDRIVER_PATH, 
    options=options
)
```

After

```python

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
options = webdriver.ChromeOptions()
service = ChromeService(executable_path=CHROMEDRIVER_PATH)
driver = webdriver.Chrome(service=service, options=options)
```

## Summary

We went through the major changes to be taken into consideration when upgrading to Selenium 4. Covering the different aspects to cover when test code is prepared for the upgrade, including suggestions on how to prevent potential issues that can show up when using the new version of Selenium. To finalize, we also covered a set of possible issues that you can bump into after upgrading, and we shared potential fixes for those issues.

*This was originally posted at <https://saucelabs.com/resources/articles/how-to-upgrade-to-selenium-4>*

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/encouraged/avoid_sharing_state/
----

# Evite compartilhamento de estado

Embora mencionado em vários lugares, vale a pena mencionar novamente. Garanta que os testes são isolados uns dos outros.

* Não compartilhe dados de teste. Imagine vários testes em que cada um consulta o banco de dados para pedidos válidos antes de escolher um para executar uma ação. Caso dois testes peguem a mesma ordem, provavelmente você obterá um comportamento inesperado.

* Limpe dados desatualizados no aplicativo que podem ser obtidos por outro teste, por exemplo registros de pedidos inválidos.

* Crie uma nova instância do WebDriver por teste. Isso ajuda a garantir o isolamento do teste e torna a paralelização mais simples.

  * If you choose [pytest](https://pytest.org/) as your test runner, this can be easily done by yielding your driver in a global fixture. This way each test gets its own driver instance, and you can ensure that drivers always quit after a test is finished (pass or fail).

Última modificação September 23, 2024: [Added more detail to Avoid Sharing State Documentation (#1948)\[deploy site\] (e1fa2da1696)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e1fa2da1696971bd7e22f613dce09a8934fd56ff)

----
url: https://www.selenium.dev/documentation/webdriver/bidi/cdp/script/
----

# Chrome DevTools Script Features

```java
    ScriptKey key = ((JavascriptExecutor) driver).pin("return arguments;");
    List<Object> arguments =
        (List<Object>) ((JavascriptExecutor) driver).executeScript(key, 1, true, element);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/ScriptTest.java#L32-L34)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/ScriptTest.java

```java
package dev.selenium.bidi.cdp;

import static org.openqa.selenium.devtools.events.CdpEventTypes.domMutation;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.HasLogEvents;
import org.openqa.selenium.support.ui.WebDriverWait;

public class ScriptTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void pinScript() {
    driver.get("https://www.selenium.dev/selenium/web/xhtmlTest.html");
    WebElement element = driver.findElement(By.id("id1"));

    ScriptKey key = ((JavascriptExecutor) driver).pin("return arguments;");
    List<Object> arguments =
        (List<Object>) ((JavascriptExecutor) driver).executeScript(key, 1, true, element);

    Assertions.assertEquals(List.of(1L, true, element), arguments);
  }

  @Test
  public void mutatedElements() {
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    CopyOnWriteArrayList<WebElement> mutations = new CopyOnWriteArrayList<>();

    ((HasLogEvents) driver).onLogEvent(domMutation(e -> mutations.add(e.getElement())));

    driver.findElement(By.id("reveal")).click();

    wait.until(_d -> !mutations.isEmpty());
    Assertions.assertEquals(mutations.get(0), driver.findElement(By.id("revealed")));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs#L21-L22)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs

```cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class ScriptTest : BaseChromeTest
    {
        [TestMethod]
        public async Task PinScript()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/xhtmlTest.html";
            var element = driver.FindElement(By.Id("id1"));

            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);

            var expected = new List<object>
            {
                1L,
                true,
                element
            };
            CollectionAssert.AreEqual(expected, (ICollection)arguments);
        }

        [TestMethod]
        public async Task MutatedElements()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            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();

            driver.FindElement(By.Id("reveal")).Click();
            
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !mutations.IsNullOrEmpty());
            await monitor.DisableDomMutationMonitoring();
            monitor.StopEventMonitoring();

            var revealed = driver.FindElement(By.Id("revealed")); 
            Assert.AreEqual(revealed, mutations[0]);
        }
    }
}
```

```rb
    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/script_spec.rb#L12-L13)

##### /examples/ruby/spec/bidi/cdp/script\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Script' do
  let(:driver) { start_session }

  it 'pins script' do
    driver.get('https://www.selenium.dev/selenium/web/xhtmlTest.html')
    element = driver.find_element(id: 'id1')

    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)

    expect(arguments).to eq([1, true, element])
  end

  it 'gets mutated elements' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'

    mutations = []
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }

    driver.find_element(id: 'reveal').click
    Selenium::WebDriver::Wait.new(timeout: 30).until { mutations.any? }

    expect(mutations).to include(driver.find_element(id: 'revealed'))
  end
end
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).mutation_events() as event:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_script.py#L10-L11)

##### /examples/python/tests/bidi/cdp/test\_script.py

```py
import pytest
import trio
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

@pytest.mark.trio
async def test_mutation(driver):
    async with driver.bidi_connection() as session:
        async with Log(driver, session).mutation_events() as event:
            await trio.to_thread.run_sync(lambda: driver.get('https://www.selenium.dev/selenium/web/dynamic.html'))
            await trio.to_thread.run_sync(lambda: WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "reveal"))))
            await trio.to_thread.run_sync(lambda: driver.find_element(By.ID, "reveal").click())

    assert event["element"] == driver.find_element(By.ID, "revealed")
```

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs#L39-L46)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs

```cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class ScriptTest : BaseChromeTest
    {
        [TestMethod]
        public async Task PinScript()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/xhtmlTest.html";
            var element = driver.FindElement(By.Id("id1"));

            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);

            var expected = new List<object>
            {
                1L,
                true,
                element
            };
            CollectionAssert.AreEqual(expected, (ICollection)arguments);
        }

        [TestMethod]
        public async Task MutatedElements()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            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();

            driver.FindElement(By.Id("reveal")).Click();
            
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !mutations.IsNullOrEmpty());
            await monitor.DisableDomMutationMonitoring();
            monitor.StopEventMonitoring();

            var revealed = driver.FindElement(By.Id("revealed")); 
            Assert.AreEqual(revealed, mutations[0]);
        }
    }
}
```

```rb
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/script_spec.rb#L22)

##### /examples/ruby/spec/bidi/cdp/script\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Script' do
  let(:driver) { start_session }

  it 'pins script' do
    driver.get('https://www.selenium.dev/selenium/web/xhtmlTest.html')
    element = driver.find_element(id: 'id1')

    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)

    expect(arguments).to eq([1, true, element])
  end

  it 'gets mutated elements' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'

    mutations = []
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }

    driver.find_element(id: 'reveal').click
    Selenium::WebDriver::Wait.new(timeout: 30).until { mutations.any? }

    expect(mutations).to include(driver.find_element(id: 'revealed'))
  end
end
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Add Example](/documentation/about/contributing/#creating-examples)

Last modified November 5, 2024: [Add examples for Drivers HTTP Client in Java and Python (#2041) (2ce6752bfc8)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/2ce6752bfc8a0d1643519fbbe6934f903e33d097)

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/discouraged/gmail_email_and_facebook_logins/
----

# Login via Gmail, email e Facebook

Por vários motivos, fazer login em sites como Gmail e Facebook usando do WebDriver não é recomendado. Além de ser contra os termos de uso desses sites (onde você corre o risco de ter a conta encerrada), é lento e não confiável.

A prática ideal é usar as APIs que os provedores de e-mail oferecem, ou no caso do Facebook, o serviço de ferramentas para desenvolvedores que expõe uma API para criar contas de teste, amigos e assim por diante. Embora usar uma API possa parecer um pouco trabalhoso, você será recompensado em velocidade, confiabilidade e estabilidade. A API também não deve mudar, enquanto as páginas da web e os localizadores de HTML mudam frequentemente e exigem que você atualize sua estrutura de teste.

Login em sites de terceiros usando WebDriver em qualquer ponto do seu teste aumenta o risco de seu teste falhar porque torna o teste mais longo. Uma regra geral é que testes mais longos são mais frágeis e não confiáveis.

Implementações WebDriver que estão [em conformidade com W3C](//w3c.github.io/webdriver/webdriver-spec.html) também anotam o objeto `navigator` com uma propriedade `WebDriver` para que os ataques de negação de serviço possam ser mitigados.

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/getting_started/
----

# 入门指南

如果你是Selenium的新手, 我们有一些资源帮助你快速入门.

***

##### [安装Selenium类库](/zh-cn/documentation/webdriver/getting_started/install_library/)

配置自动化的浏览器.

##### [编写第一个Selenium脚本](/zh-cn/documentation/webdriver/getting_started/first_script/)

逐步构建一个Selenium脚本的说明

##### [组织和执行Selenium代码](/zh-cn/documentation/webdriver/getting_started/using_selenium/)

使用IDE和Test Runner库组织Selenium的执行

最后修改 June 21, 2024: [update feature/getting\_started\_20240621 (#1772) (cc1bdc8b77c)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/cc1bdc8b77cdbf7c9e06b861d8f4dddb6bde27d9)

----
url: https://www.selenium.dev/zh-cn/documentation/grid/applicability/
----

# 什么时候应该使用Grid

```
   15      *       45s        /        1        =      11m 15s   // 没有Grid
   15      *       45s        /        5        =      2m 15s    // 5节点的Grid
   15      *       45s        /        15       =      45s       // 15节点的Grid
  100      *       120s       /        15       =      13m 20s   // 如果没有Grid, 需要3个多小时
```

在测试案例执行时，`Grid` 会按照测试配置将测试分配到相应的浏览器上运行.

即使对于比较复杂的 `Selenium` 测试案例，这样的配置也可以极大地加快执行时间.

`Selenium Grid` 是 `Selenium` 项目中的重要组成部分，由同一团队的核心Selenium开发人员并行维护. 由于意识到测试执行速度的重要性，`Grid` 自设计之初就成为 `Selenium` 项目的关键部分.

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/discouraged/file_downloads/
----

# 文件下载

虽然可以通过在Selenium的控制下单击浏览器的链接来开始下载, 但是API并不会暴露下载进度, 因此这是一种不理想的测试下载文件的方式. 因为下载文件并非模拟用户与Web平台交互的重要方面. 取而代之的是, 应使用Selenium(以及任何必要的cookie)查找链接, 并将其传递给例如[curl](/zh-cn/)这样的HTTP请求库.

[HtmlUnit driver](https://github.com/SeleniumHQ/htmlunit-driver) 可以通过实现[AttachmentHandler](https://htmlunit.sourceforge.io/apidocs/com/gargoylesoftware/htmlunit/attachment/AttachmentHandler.html) 接口将附件作为输入流进行访问来下载附件. 可以将AttachmentHandler添加到 [HtmlUnit](https://htmlunit.sourceforge.io/) WebClient.

----
url: https://www.selenium.dev/ja/documentation/test_practices/discouraged/file_downloads/
----

# ファイルダウンロード

Seleniumの管理下にあるブラウザーでリンクをクリックしてダウンロードを開始することは可能ですが、APIはダウンロードの進行状況を公開しないため、ダウンロードしたファイルのテストには理想的ではありません。 これは、ファイルのダウンロードは、Webプラットフォームとのユーザーインタラクションをエミュレートする重要な側面とは見なされないためです。 代わりに、Selenium（および必要なCookie）を使用してリンクを見つけ、 [curl](https://curl.se/) などのHTTPリクエストライブラリに渡します。

[HtmlUnitドライバー](https://github.com/SeleniumHQ/htmlunit-driver)は、 [AttachmentHandler](https://htmlunit.sourceforge.io/apidocs/com/gargoylesoftware/htmlunit/attachment/AttachmentHandler.html) インターフェイスを実装することで、 入力ストリームとして添付ファイルにアクセスすることによって、添付ファイルをダウンロードできます。 AttachmentHandlerは、[HtmlUnit](https://htmlunit.sourceforge.io/) に追加できます。

----
url: https://www.selenium.dev/documentation/grid/advanced_features/customize_node/
----

# Customizing a Node

```bash
java -jar custom_node-server.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

```bash
java -jar selenium-server-4.6.0.jar \
--ext custom_node-1.0-SNAPSHOT.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

Below is a sample that just prints some messages on to the console whenever there’s an activity of interest (session created, session deleted, a webdriver command executed etc.,) on the Node.

Sample customized node

```java
package org.seleniumhq.samples;

import java.io.IOException;
import java.net.URI;
import java.util.UUID;
import java.util.function.Supplier;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.NoSuchSessionException;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.grid.config.Config;
import org.openqa.selenium.grid.data.CreateSessionRequest;
import org.openqa.selenium.grid.data.CreateSessionResponse;
import org.openqa.selenium.grid.data.NodeId;
import org.openqa.selenium.grid.data.NodeStatus;
import org.openqa.selenium.grid.data.Session;
import org.openqa.selenium.grid.log.LoggingOptions;
import org.openqa.selenium.grid.node.HealthCheck;
import org.openqa.selenium.grid.node.Node;
import org.openqa.selenium.grid.node.local.LocalNodeFactory;
import org.openqa.selenium.grid.security.Secret;
import org.openqa.selenium.grid.security.SecretOptions;
import org.openqa.selenium.grid.server.BaseServerOptions;
import org.openqa.selenium.internal.Either;
import org.openqa.selenium.io.TemporaryFilesystem;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
import org.openqa.selenium.remote.tracing.Tracer;

public class DecoratedLoggingNode extends Node {

  private Node node;

  protected DecoratedLoggingNode(Tracer tracer, NodeId nodeId, URI uri, Secret registrationSecret, Duration sessionTimeout) {
    super(tracer, nodeId, uri, registrationSecret, sessionTimeout);
  }

  public static Node create(Config config) {
    LoggingOptions loggingOptions = new LoggingOptions(config);
    BaseServerOptions serverOptions = new BaseServerOptions(config);
    URI uri = serverOptions.getExternalUri();
    SecretOptions secretOptions = new SecretOptions(config);
    NodeOptions nodeOptions = new NodeOptions(config);
    Duration sessionTimeout = nodeOptions.getSessionTimeout();

    // Refer to the foot notes for additional context on this line.
    Node node = LocalNodeFactory.create(config);

    DecoratedLoggingNode wrapper = new DecoratedLoggingNode(loggingOptions.getTracer(),
        node.getId(),
        uri,
        secretOptions.getRegistrationSecret(),
        sessionTimeout);
    wrapper.node = node;
    return wrapper;
  }

  @Override
  public Either<WebDriverException, CreateSessionResponse> newSession(
      CreateSessionRequest sessionRequest) {
    return perform(() -> node.newSession(sessionRequest), "newSession");
  }

  @Override
  public HttpResponse executeWebDriverCommand(HttpRequest req) {
    return perform(() -> node.executeWebDriverCommand(req), "executeWebDriverCommand");
  }

  @Override
  public Session getSession(SessionId id) throws NoSuchSessionException {
    return perform(() -> node.getSession(id), "getSession");
  }

  @Override
  public HttpResponse uploadFile(HttpRequest req, SessionId id) {
    return perform(() -> node.uploadFile(req, id), "uploadFile");
  }

  @Override
  public HttpResponse downloadFile(HttpRequest req, SessionId id) {
    return perform(() -> node.downloadFile(req, id), "downloadFile");
  }

  @Override
  public TemporaryFilesystem getDownloadsFilesystem(UUID uuid) {
    return perform(() -> {
      try {
        return node.getDownloadsFilesystem(uuid);
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
    }, "downloadsFilesystem");
  }

  @Override
  public TemporaryFilesystem getUploadsFilesystem(SessionId id) throws IOException {
    return perform(() -> {
      try {
        return node.getUploadsFilesystem(id);
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
    }, "uploadsFilesystem");

  }

  @Override
  public void stop(SessionId id) throws NoSuchSessionException {
    perform(() -> node.stop(id), "stop");
  }

  @Override
  public boolean isSessionOwner(SessionId id) {
    return perform(() -> node.isSessionOwner(id), "isSessionOwner");
  }

  @Override
  public boolean isSupporting(Capabilities capabilities) {
    return perform(() -> node.isSupporting(capabilities), "isSupporting");
  }

  @Override
  public NodeStatus getStatus() {
    return perform(() -> node.getStatus(), "getStatus");
  }

  @Override
  public HealthCheck getHealthCheck() {
    return perform(() -> node.getHealthCheck(), "getHealthCheck");
  }

  @Override
  public void drain() {
    perform(() -> node.drain(), "drain");
  }

  @Override
  public boolean isReady() {
    return perform(() -> node.isReady(), "isReady");
  }

  private void perform(Runnable function, String operation) {
    try {
      System.err.printf("[COMMENTATOR] Before %s()%n", operation);
      function.run();
    } finally {
      System.err.printf("[COMMENTATOR] After %s()%n", operation);
    }
  }

  private <T> T perform(Supplier<T> function, String operation) {
    try {
      System.err.printf("[COMMENTATOR] Before %s()%n", operation);
      return function.get();
    } finally {
      System.err.printf("[COMMENTATOR] After %s()%n", operation);
    }
  }
}
```

***Foot Notes:***

In the above example, the line `Node node = LocalNodeFactory.create(config);` explicitly creates a `LocalNode`.

There are basically 2 types of *user facing implementations* of `org.openqa.selenium.grid.node.Node` available.

These classes are good starting points to learn how to build a custom Node and also to learn the internals of a Node.

* `org.openqa.selenium.grid.node.local.LocalNode` - Used to represent a long running Node and is the default implementation that gets wired in when you start a `node`.

  * It can be created by calling `LocalNodeFactory.create(config);`, where:

    * `LocalNodeFactory` belongs to `org.openqa.selenium.grid.node.local`
    * `Config` belongs to `org.openqa.selenium.grid.config`

* `org.openqa.selenium.grid.node.k8s.OneShotNode` - This is a special reference implementation wherein the Node gracefully shuts itself down after servicing one test session. This class is currently not available as part of any pre-built maven artifact.

  * You can refer to the source code [here](https://github.com/SeleniumHQ/selenium/blob/trunk/java/src/org/openqa/selenium/grid/node/k8s/OneShotNode.java) to understand its internals.

  * To build it locally refer [here](https://github.com/SeleniumHQ/selenium/blob/trunk/deploys/k8s/README.md).

  * It can be created by calling `OneShotNode.create(config)`, where:

    * `OneShotNode` belongs to `org.openqa.selenium.grid.node.k8s`
    * `Config` belongs to `org.openqa.selenium.grid.config`

Last modified May 17, 2024: [Update Custom Node Initialization in Grid Advanced Features (#1729) (808af3e6bdd)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/808af3e6bddcae225b07dc2547e4e8024feae912)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/interactions/frames/
----

# Working with IFrames and frames

Frames são um meio obsoleto de construir um layout de site a partir de vários documentos no mesmo domínio. É improvável que você trabalhe com eles a menos que você esteja trabalhando com um webapp pré-HTML5. Iframes permitem a inserção de um documento de um domínio totalmente diferente, e são ainda comumente usado.

Se você precisa trabalhar com frames ou iframes, o WebDriver permite que você trabalhe com eles da mesma maneira. Considere um botão dentro de um iframe. Se inspecionarmos o elemento usando as ferramentas de desenvolvimento do navegador, podemos ver o seguinte:

```html
<div id="modal">
  <iframe id="buttonframe" name="myframe"  src="https://seleniumhq.github.io">
   <button>Click here</button>
 </iframe>
</div>
```

```java
//This won't work
driver.findElement(By.tagName("button")).click();
  
```

```python
    # This Wont work
driver.find_element(By.TAG_NAME, 'button').click()
  
```

```csharp
//This won't work
driver.FindElement(By.TagName("button")).Click();
  
```

```ruby
    # This won't work
driver.find_element(:tag_name,'button').click
  
```

```javascript
// This won't work
await driver.findElement(By.css('button')).click();
  
```

```kotlin
//This won't work
driver.findElement(By.tagName("button")).click()
  
```

```java
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L38-L46)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L24-L32)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L38-L46)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L26-L33)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Store the web element
const iframe = driver.findElement(By.css('#modal > iframe'));

// Switch to the frame
await driver.switchTo().frame(iframe);

// Now we can click the button
await driver.findElement(By.css('button')).click();
  
```

```kotlin
//Store the web element
val iframe = driver.findElement(By.cssSelector("#modal>iframe"))

//Switch to the frame
driver.switchTo().frame(iframe)

//Now we can click the button
driver.findElement(By.tagName("button")).click()
  
```

```java
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L50-L58)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L34-L42)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L50-L58)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L36-L43)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Using the ID
await driver.switchTo().frame('buttonframe');

// Or using the name instead
await driver.switchTo().frame('myframe');

// Now we can click the button
await driver.findElement(By.css('button')).click();
  
```

```kotlin
//Using the ID
driver.switchTo().frame("buttonframe")

//Or using the name instead
driver.switchTo().frame("myframe")

//Now we can click the button
driver.findElement(By.tagName("button")).click()
  
```

```java
         //switch To IFrame using index
         driver.switchTo().frame(0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L62-L63)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L45-L46)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L62-L63)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L46-L47)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Switches to the second frame
await driver.switchTo().frame(1);
```

```kotlin
// Switches to the second frame
driver.switchTo().frame(1)
```

```java
         //leave frame
         driver.switchTo().defaultContent();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L66-L67)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L49-L50)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //leave frame
            driver.SwitchTo().DefaultContent();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L66-L67)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L49-L50)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Return to the top level
await driver.switchTo().defaultContent();
```

```kotlin
// Return to the top level
driver.switchTo().defaultContent()
```

----
url: https://www.selenium.dev/documentation/test_practices/discouraged/test_dependency/
----

# Test dependency

A common idea and misconception about automated testing is regarding a specific test order. Your tests should be able to run in **any** order, and not rely on other tests to complete in order to be successful.

----
url: https://www.selenium.dev/documentation/legacy/selenium_3/grid_setup/
----

# Setting up your own Grid 3

```shell
java -jar selenium-server-standalone.jar -role hub
```

The Hub will listen to port 4444 by default. You can view the status of the hub by opening a browser window and navigating to <http://localhost:4444/grid/console>.

To change the default port, you can add the optional `-port` flag with an integer representing the port to listen to when you run the command. Also, all of the other options you see in the JSON config file (seen below) are possible command-line flags.

You certainly can get by with only the simple command shown above, but if you need more advanced configuration, you can also specify a JSON format config file, for convenience, to configure the hub when you start it. You can do it like so:

```shell
java -jar selenium-server-standalone.jar -role hub -hubConfig hubConfig.json -debug
```

Below you will see an example of a `hubConfig.json` file. We will go into more detail on how to provide node configuration files in step 2.

```json
{
  "_comment" : "Configuration for Hub - hubConfig.json",
  "host": ip,
  "maxSession": 5,
  "port": 4444,
  "cleanupCycle": 5000,
  "timeout": 300000,
  "newSessionWaitTimeout": -1,
  "servlets": [],
  "prioritizer": null,
  "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
  "throwOnCapabilityNotPresent": true,
  "nodePolling": 180000,
  "platform": "WINDOWS"}
```

### Step 2: Start the Nodes

Regardless of whether you want to run a grid with new WebDriver functionality, or a grid with Selenium 1 RC functionality, or both at the same time, you use the same `selenium-server-standalone.jar` file to start the nodes:

```shell
java -jar selenium-server-standalone.jar -role node -hub http://localhost:4444
```

```shell
java -Dwebdriver.chrome.driver=chromedriver.exe -jar selenium-server-standalone.jar -role node -nodeConfig node1Config.json
```

And here is an example of a `nodeConfig.json` file:

```json
{
  "capabilities": [
    {
      "browserName": "firefox",
      "acceptSslCerts": true,
      "javascriptEnabled": true,
      "takesScreenshot": false,
      "firefox_profile": "",
      "browser-version": "27",
      "platform": "WINDOWS",
      "maxInstances": 5,
      "firefox_binary": "",
      "cleanSession": true
    },
    {
      "browserName": "chrome",
      "maxInstances": 5,
      "platform": "WINDOWS",
      "webdriver.chrome.driver": "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"
    },
    {
      "browserName": "internet explorer",
      "maxInstances": 1,
      "platform": "WINDOWS",
      "webdriver.ie.driver": "C:/Program Files (x86)/Internet Explorer/iexplore.exe"
    }
  ],
  "configuration": {
    "_comment" : "Configuration for Node",
    "cleanUpCycle": 2000,
    "timeout": 30000,
    "proxy": "org.openqa.grid.selenium.proxy.WebDriverRemoteProxy",
    "port": 5555,
    "host": ip,
    "register": true,
    "hubPort": 4444,
    "maxSession": 5
  }
}
```

```shell
java -jar selenium-server-standalone.jar -role hub -log log.txt
```

Use your favorite text editor to open log file (log.txt in the example above) to find “ERROR” logs if you get issues.

### Using `-debug` argument

Also you can use `-debug` argument to print debug logs to console. Start Selenium Grid Hub or Node with `-debug` argument. Please see the below example:

```shell
java -jar selenium-server-standalone.jar -role hub -debug
```

## Warning

The Selenium Grid must be protected from external access using appropriate firewall permissions.

Failure to protect your Grid could result in one or more of the following occurring:

* You provide open access to your Grid infrastructure
* You allow third parties to access internal web applications and files
* You allow third parties to run custom binaries

See this blog post on [Detectify](/), which gives a good overview of how a publicly exposed Grid could be misused: [Don’t Leave your Grid Wide Open](//labs.detectify.com/2017/10/06/guest-blog-dont-leave-your-grid-wide-open/).

## Docker Selenium

[Docker](/) provides a convenient way to provision and scale Selenium Grid infrastructure in a unit known as a container. Containers are standardised units of software that contain everything required to run the desired application, including all dependencies, in a reliable and repeatable way on different machines.

The Selenium project maintains a set of Docker images which you can download and run to get a working grid up and running quickly. Nodes are available for both Firefox and Chrome. Full details of how to provision a grid can be found within the [Docker Selenium](//github.com/SeleniumHQ/docker-selenium) repository.

### Prerequisite

The only requirement to run a Grid is to have Docker installed and working. [Install Docker](//www.docker.com/products/docker-desktop).

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/support_features/
----

# Recursos de suporte

As classes de suporte fornecem características opcionais de nível superior.

As bibliotecas principais do Selenium tentam ser de baixo nível e não opinativas. As classes de suporte em cada linguagem fornecem invólucros opinativos para interações comuns que podem ser usadas para simplificar alguns comportamentos.

***

##### [Command Listeners](/pt-br/documentation/webdriver/support_features/listeners/)

##### [Trabalhando com cores](/pt-br/documentation/webdriver/support_features/colors/)

##### [ThreadGuard](/pt-br/documentation/webdriver/support_features/thread_guard/)

##### [Trabalhando com elementos select](/pt-br/documentation/webdriver/support_features/select_lists/)

Select lists have special behaviors compared to other elements.

##### [](/pt-br/documentation/webdriver/support_features/expected_conditions/)

Última modificação October 25, 2023: [feat: translate webDriver and support features into Portuguese (#1512) (357295af44e)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/357295af44e4819794de0dbcf19a681a05eafa8e)

----
url: https://www.selenium.dev/zh-cn/documentation/grid/configuration/cli_options/
----

# CLI 选项

所有网格组件配置CLI选项的详细信息.

**Page being translated from English to Chinese. Do you speak Chinese? Help us to translate it by sending us pull requests!

Different sections are available to configure a Grid. Each section has options can be configured through command line arguments.

A complete description of the component to section mapping can be seen below.

Note that this documentation could be outdated if an option was modified or added but has not been documented yet. In case you bump into this situation, please check the [“Config help”](https://www.selenium.dev/zh-cn/documentation/grid/configuration/help/) section and feel free to send us a pull request updating this page.

## Sections

|                               | Standalone | Hub | Node | Distributor | Router | Sessions | SessionQueue |
| ----------------------------- | ---------- | --- | ---- | ----------- | ------ | -------- | ------------ |
| [Distributor](#distributor)   | **         | **  |      | **          | **     |          |              |
| [Docker](#docker)             | **         |     | **   |             |        |          |              |
| [Events](#events)             |            | **  | **   | **          |        | **       | **           |
| [Logging](#logging)           | **         | **  | **   | **          | **     | **       | **           |
| [Network](#network)           | **         | **  |      |             | **     |          |              |
| [Node](#node)                 | **         |     | **   |             |        |          |              |
| [Router](#router)             | **         | **  |      |             | **     |          |              |
| [Relay](#relay)               | **         |     | **   |             |        |          |              |
| [Server](#server)             | **         | **  | **   | **          | **     | **       | **           |
| [SessionQueue](#sessionqueue) | **         | **  |      | **          | **     |          | **           |
| [Sessions](#sessions)         |            |     |      | **          | **     | **       |              |

### Distributor

| Option                         | Type    | Value/Example                                                       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ------------------------------ | ------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--healthcheck-interval`       | int     | `120`                                                               | How often, in seconds, will the health check run for all Nodes. This ensures the server can ping all the Nodes successfully.                                                                                                                                                                                                                                                                                                                        |
| `--distributor`                | uri     | `http://localhost:5553`                                             | Url of the distributor.                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `--distributor-host`           | string  | `localhost`                                                         | Host on which the distributor is listening.                                                                                                                                                                                                                                                                                                                                                                                                         |
| `--distributor-implementation` | string  | `org.openqa.selenium.grid.distributor.local.LocalDistributor`       | Full class name of non-default distributor implementation                                                                                                                                                                                                                                                                                                                                                                                           |
| `--distributor-port`           | int     | `5553`                                                              | Port on which the distributor is listening.                                                                                                                                                                                                                                                                                                                                                                                                         |
| `--reject-unsupported-caps`    | boolean | `false`                                                             | Allow the Distributor to reject a request immediately if the Grid does not support the requested capability. Rejecting requests immediately is suitable for a Grid setup that does not spin up Nodes on demand.                                                                                                                                                                                                                                     |
| `--slot-matcher`               | string  | `org.openqa.selenium.grid.data.DefaultSlotMatcher`                  | Full class name of non-default slot matcher to use. This is used to determine whether a Node can support a particular session.                                                                                                                                                                                                                                                                                                                      |
| `--slot-selector`              | string  | `org.openqa.selenium.grid.distributor.selector.DefaultSlotSelector` | Full class name of non-default slot selector. This is used to select a slot in a Node once the Node has been matched.                                                                                                                                                                                                                                                                                                                               |
| `--newsession-threadpool-size` | int     | `24`                                                                | The Distributor uses a fixed-sized thread pool to create new sessions as it consumes new session requests from the queue. This allows configuring the size of the thread pool. The default value is no. of available processors \* 3. Note: If the no. of threads is way greater than the available processors it will not always increase the performance. A high number of threads causes more context switching which is an expensive operation. |
| `--purge-nodes-interval`       | int     | `30`                                                                | How often, in seconds, will the Distributor purge Nodes that have been down for a while. This is calculated based on the heartbeat received from a particular node.                                                                                                                                                                                                                                                                                 |

### Docker

| Option                      | Type      | Value/Example                                                     | Description                                                                                                                                                                                                                                                                                 |
| --------------------------- | --------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--docker-assets-path`      | string    | `/opt/selenium/assets`                                            | Absolute path where assets will be stored                                                                                                                                                                                                                                                   |
| `--docker-`                 | string\[] | `selenium/standalone-firefox:latest '{"browserName": "firefox"}'` | Docker configs which map image name to stereotype capabilities (example \`-D selenium/standalone-firefox:latest ‘{“browserName”: “firefox”}’)                                                                                                                                               |
| `--docker-devices`          | string\[] | `/dev/kvm:/dev/kvm`                                               | Exposes devices to a container. Each device mapping declaration must have at least the path of the device in both host and container separated by a colon like in this example: /device/path/in/host:/device/path/in/container                                                              |
| `--docker-host`             | string    | `localhost`                                                       | Host name where the Docker daemon is running                                                                                                                                                                                                                                                |
| `--docker-port`             | int       | `2375`                                                            | Port where the Docker daemon is running                                                                                                                                                                                                                                                     |
| `--docker-url`              | string    | `http://localhost:2375`                                           | URL for connecting to the Docker daemon                                                                                                                                                                                                                                                     |
| `--docker-video-image`      | string    | `selenium/video:latest`                                           | Docker image to be used when video recording is enabled                                                                                                                                                                                                                                     |
| `--docker-host-config-keys` | string\[] | `Dns DnsOptions DnsSearch ExtraHosts Binds`                       | Specify which docker host configuration keys should be passed to browser containers. Keys name can be found in the Docker API [documentation](https://docs.docker.com/engine/api/v1.41/#tag/Container/operation/ContainerCreate), or by running `docker inspect` the node-docker container. |

### Events

| Option                    | Type    | Value/Example                                      | Description                                                                                                                                                                                                                                                                         |
| ------------------------- | ------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--bind-bus`              | boolean | `false`                                            | Whether the connection string should be bound or connected. When true, the component will be bound to the Event Bus (as in the Event Bus will also be started by the component, typically by the Distributor and the Hub). When false, the component will connect to the Event Bus. |
| `--events-implementation` | string  | `org.openqa.selenium.events.zeromq.ZeroMqEventBus` | Full class name of non-default event bus implementation                                                                                                                                                                                                                             |
| `--publish-events`        | string  | `tcp://*:4442`                                     | Connection string for publishing events to the event bus                                                                                                                                                                                                                            |
| `--subscribe-events`      | string  | `tcp://*:4443`                                     | Connection string for subscribing to events from the event bus                                                                                                                                                                                                                      |

### Logging

| Option                   | Type    | Value/Example                                                                                                                                              | Description                                                                                                                                                            |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--http-logs`            | boolean | `false`                                                                                                                                                    | Enable http logging. Tracing should be enabled to log http logs.                                                                                                       |
| `--log-encoding`         | string  | `UTF-8`                                                                                                                                                    | Log encoding                                                                                                                                                           |
| `--log`                  | string  | Windows path example : `'\path\to\file\gridlog.log'` or `'C:\path\path\to\file\gridlog.log'` Linux/Unix/MacOS path example : `'/path/to/file/gridlog.log'` | File to write out logs. Ensure the file path is compatible with the operating system’s file path.                                                                      |
| `--log-level`            | string  | `“INFO”`                                                                                                                                                   | Log level. Default logging level is INFO. Log levels are described here <https://docs.oracle.com/en/java/javase/11/docs/api/java.logging/java/util/logging/Level.html> |
| `--plain-logs`           | boolean | `true`                                                                                                                                                     | Use plain log lines                                                                                                                                                    |
| `--structured-logs`      | boolean | `false`                                                                                                                                                    | Use structured logs                                                                                                                                                    |
| `--tracing`              | boolean | `true`                                                                                                                                                     | Enable trace collection                                                                                                                                                |
| `--log-timestamp-format` | string  | `HH:mm:ss.SSS`                                                                                                                                             | Allows the configure log timestamp format                                                                                                                              |

### Network

| Option           | Type    | Value/Example | Description                                                                                                          |
| ---------------- | ------- | ------------- | -------------------------------------------------------------------------------------------------------------------- |
| `--relax-checks` | boolean | `false`       | Relax checks on origin header and content type of incoming requests, in contravention of strict W3C spec compliance. |

### Node

| Option                           | Type      | Value/Example                                                                                                                                                                                                                                                              | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |   |
| -------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - |
| `--detect-drivers`               | boolean   | `true`                                                                                                                                                                                                                                                                     | Autodetect which drivers are available on the current system, and add them to the Node.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |   |
| `--driver-configuration`         | string\[] | `display-name="Firefox Nightly" max-sessions=2 webdriver-path="/usr/local/bin/geckodriver" stereotype="{\"browserName\": \"firefox\", \"browserVersion\": \"86\", \"moz:firefoxOptions\": {\"binary\":\"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"` | List of configured drivers a Node supports. It is recommended to provide this type of configuration through a toml config file to improve readability                                                                                                                                                                                                                                                                                                                                                                                                                                                   |   |
| `--driver-factory`               | string\[] | `org.openqa.selenium.example.LynxDriverFactory '{"browserName": "lynx"}'`                                                                                                                                                                                                  | Mapping of fully qualified class name to a browser configuration that this matches against.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |   |
| `--driver-implementation`        | string\[] | `"firefox"`                                                                                                                                                                                                                                                                | Drivers that should be checked. If specified, will skip autoconfiguration.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |   |
| `--node-implementation`          | string    | `"org.openqa.selenium.grid.node.local.LocalNodeFactory"`                                                                                                                                                                                                                   | Full classname of non-default Node implementation. This is used to manage a session’s lifecycle.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |   |
| `--grid-url`                     | string    | `https://grid.example.com`                                                                                                                                                                                                                                                 | Public URL of the Grid as a whole (typically the address of the Hub or the Router)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |   |
| `--heartbeat-period`             | int       | `60`                                                                                                                                                                                                                                                                       | How often, in seconds, will the Node send heartbeat events to the Distributor to inform it that the Node is up.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |   |
| `--max-sessions`                 | int       | `8`                                                                                                                                                                                                                                                                        | Maximum number of concurrent sessions. Default value is the number of available processors.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |   |
| `--override-max-sessions`        | boolean   | `false`                                                                                                                                                                                                                                                                    | The # of available processors is the recommended max sessions value (1 browser session per processor). Setting this flag to true allows the recommended max value to be overwritten. Session stability and reliability might suffer as the host could run out of resources.                                                                                                                                                                                                                                                                                                                             |   |
| `--register-cycle`               | int       | `10`                                                                                                                                                                                                                                                                       | How often, in seconds, the Node will try to register itself for the first time to the Distributor.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |   |
| `--register-period`              | int       | `120`                                                                                                                                                                                                                                                                      | How long, in seconds, will the Node try to register to the Distributor for the first time. After this period is completed, the Node will not attempt to register again.                                                                                                                                                                                                                                                                                                                                                                                                                                 |   |
| `--session-timeout`              | int       | `300`                                                                                                                                                                                                                                                                      | Let X be the session-timeout in seconds. The Node will automatically kill a session that has not had any activity in the last X seconds. This will release the slot for other tests.                                                                                                                                                                                                                                                                                                                                                                                                                    |   |
| `--vnc-env-var`                  | string\[] | `SE_START_XVFB SE_START_VNC SE_START_NO_VNC`                                                                                                                                                                                                                               | Environment variable to check in order to determine if a vnc stream is available or not.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |   |
| `--no-vnc-port`                  | int       | `7900`                                                                                                                                                                                                                                                                     | If VNC is available, sets the port where the local noVNC stream can be obtained                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |   |
| `--drain-after-session-count`    | int       | `1`                                                                                                                                                                                                                                                                        | Drain and shutdown the Node after X sessions have been executed. Useful for environments like Kubernetes. A value higher than zero enables this feature.                                                                                                                                                                                                                                                                                                                                                                                                                                                |   |
| `--hub`                          | string    | `http://localhost:4444`                                                                                                                                                                                                                                                    | The address of the Hub in a Hub-and-Node configuration. Can be a hostname or IP address (`hostname`), in which case the Hub will be assumed to be `http://hostname:4444`, the `--grid-url` will be the same `--publish-events` will be `tcp://hostname:4442` and `--subscribe-events` will be `tcp://hostname:4443`. If `hostname` contains a port number, that will be used for `--grid-url` but the URIs for the event bus will remain the same. Any of these default values may be overridden but setting the correct flags. If the hostname has a protocol (such as `https`) that will be used too. |   |
| `--enable-cdp`                   | boolean   | `true`                                                                                                                                                                                                                                                                     | Enable CDP proxying in Grid. A Grid admin can disable CDP if the network does not allow websockets. True by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |   |
| `--enable-managed-downloads`     | boolean   | `false`                                                                                                                                                                                                                                                                    | This causes the Node to auto manage files downloaded for a given session on the Node.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |   |
| `--selenium-manager`             | boolean   | `false`                                                                                                                                                                                                                                                                    | When drivers are not available on the current system, use Selenium Manager. False by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |   |
| `--connection-limit-per-session` | int       | `10`                                                                                                                                                                                                                                                                       | Let X be the maximum number of websocket connections per session.This will ensure one session is not able to exhaust the connection limit of the host.                                                                                                                                                                                                                                                                                                                                                                                                                                                  |   |

### Relay

| Option                       | Type      | Value/Example                                                                                                     | Description                                                                                                                                                              |
| ---------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--service-url`              | string    | `http://localhost:4723`                                                                                           | URL for connecting to the service that supports WebDriver commands like an Appium server or a cloud service.                                                             |
| `--service-host`             | string    | `localhost`                                                                                                       | Host name where the service that supports WebDriver commands is running                                                                                                  |
| `--service-port`             | int       | `4723`                                                                                                            | Port where the service that supports WebDriver commands is running                                                                                                       |
| `--service-status-endpoint`  | string    | `/status`                                                                                                         | Optional, endpoint to query the WebDriver service status, an HTTP 200 response is expected                                                                               |
| `--service-protocol-version` | string    | `HTTP/1.1`                                                                                                        | Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status                                                          |
| `--service-configuration`    | string\[] | `max-sessions=2 stereotype='{"browserName": "safari", "platformName": "iOS", "appium:platformVersion": "14.5"}}'` | Configuration for the service where calls will be relayed to. It is recommended to provide this type of configuration through a toml config file to improve readability. |

### Router

| Option         | Type    | Value/Example              | Description                                                                                                         |
| -------------- | ------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `--password`   | string  | `myStrongPassword`         | Password clients must use to connect to the server. Both this and the username need to be set in order to be used.  |
| `--username`   | string  | `admin`                    | User name clients must use to connect to the server. Both this and the password need to be set in order to be used. |
| `--sub-path`   | string  | `my_company/selenium_grid` | A sub-path that should be considered for all user facing routes on the Hub/Router/Standalone.                       |
| `--disable-ui` | boolean | `true`                     | Disable the Grid UI.                                                                                                |

### Server

| Option                | Type    | Value/Example        | Description                                                                                                                                                                                                                                                                           |
| --------------------- | ------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--allow-cors`        | boolean | `true`               | Whether the Selenium server should allow web browser connections from any host                                                                                                                                                                                                        |
| `--host`              | string  | `localhost`          | Server IP or hostname: usually determined automatically.                                                                                                                                                                                                                              |
| `--bind-host`         | boolean | `true`               | Whether the server should bind to the host address/name, or only use it to" report its reachable url. Helpful in complex network topologies where the server cannot report itself with the current IP/hostname but rather an external IP or hostname (e.g. inside a Docker container) |
| `--https-certificate` | path    | `/path/to/cert.pem`  | Server certificate for https. Get more detailed information by running “java -jar selenium-server.jar info security”                                                                                                                                                                  |
| `--https-private-key` | path    | `/path/to/key.pkcs8` | Private key for https. Get more detailed information by running “java -jar selenium-server.jar info security”                                                                                                                                                                         |
| `--max-threads`       | int     | `24`                 | Maximum number of listener threads. Default value is: (available processors) \* 3.                                                                                                                                                                                                    |
| `--port`              | int     | `4444`               | Port to listen on. There is no default as this parameter is used by different components, for example, Router/Hub/Standalone will use 4444 and Node will use 5555.                                                                                                                    |

### SessionQueue

| Option                      | Type   | Value/Example           | Description                                                                                                                                               |
| --------------------------- | ------ | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--sessionqueue`            | uri    | `http://localhost:1237` | Address of the session queue server.                                                                                                                      |
| `-sessionqueue-host`        | string | `localhost`             | Host on which the session queue server is listening.                                                                                                      |
| `--sessionqueue-port`       | int    | `1234`                  | Port on which the session queue server is listening.                                                                                                      |
| `--session-request-timeout` | int    | `300`                   | Timeout in seconds. A new incoming session request is added to the queue. Requests sitting in the queue for longer than the configured time will timeout. |
| `--session-retry-interval`  | int    | `5`                     | Retry interval in seconds. If all slots are busy, new session request will be retried after the given interval.                                           |
| `--maximum-response-delay`  | int    | `8`                     | How often, in seconds, will the the SessionQueue response in case there is no data, to reduce the http requests while polling for new session requests.   |

### Sessions

| Option            | Type   | Value/Example           | Description                                        |
| ----------------- | ------ | ----------------------- | -------------------------------------------------- |
| `--sessions`      | uri    | `http://localhost:1234` | Address of the session map server.                 |
| `--sessions-host` | string | `localhost`             | Host on which the session map server is listening. |
| `--sessions-port` | int    | `1234`                  | Port on which the session map server is listening. |

## Configuration examples

All the options mentioned above can be used when starting the Grid components. They are a good way of exploring the Grid options, and trying out values to find a suitable configuration.

We recommend the use of [Toml files](https://www.selenium.dev/zh-cn/documentation/grid/configuration/toml_options/) to configure a Grid. Configuration files improve readability, and you can also check them in source control.

When needed, you can combine a Toml file configuration with CLI arguments.

### Command-line flags

To pass config options as command-line flags, identify the valid options for the component and follow the template below.

```
java -jar selenium-server-<version>.jar <component> --<option> value
```

#### Standalone, setting max sessions and main port

```
java -jar selenium-server-<version>.jar standalone --max-sessions 4 --port 4444
```

#### Hub, setting a new session request timeout, a main port, and disabling tracing

```
java -jar selenium-server-<version>.jar hub --session-request-timeout 500 --port 3333 --tracing false
```

#### Node, with 4 max sessions, with debug(fine) log, 7777 as port, and only with Firefox and Edge

```
java -jar selenium-server-<version>.jar node --max-sessions 4 --log-level "fine" --port 7777 --driver-implementation "firefox" --driver-implementation "edge"
```

#### Distributor, setting Session Map server url, Session Queue server url, and disabling bus

```
java -jar selenium-server-<version>.jar distributor --sessions http://localhost:5556 --sessionqueue http://localhost:5559 --bind-bus false
```

#### Setting custom capabilities for matching specific Nodes

**Important:** Custom capabilities need to be set in the configuration in all Nodes. They also need to be included always in every session request.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node A with custom cap set to `true`

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":true}' --port 6161
```

##### Start the Node B with custom cap set to `false`

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":false}' --port 6262
```

##### Matching Node A

```java
ChromeOptions options = new ChromeOptions();
options.setCapability("gsg:customcap", true);
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

Set the custom capability to `false` in order to match the Node B.

#### Enabling Managed downloads by the Node

At times a test may need to access files that were downloaded by it on the Node. To retrieve such files, following can be done.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node with manage downloads enabled

```
java -jar selenium-server-<version>.jar node --enable-managed-downloads true
```

##### Set the capability at the test level

Tests that want to use this feature should set the capability `"se:downloadsEnabled"`to `true`

```java
options.setCapability("se:downloadsEnabled", true);
```

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

In the response the list of file names appear under the key `names`.

##### Dowloading a file:

* The endpoint to `POST` from is `/session/<sessionId>/se/files` with a payload of the form `{"name": "fileNameGoesHere}`
* The session needs to be active in order for the command to work.
* The raw response looks like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "Base64EncodedStringContentsOfDownloadedFileAsZipGoesHere"
  }
}
```

* The response blob contains two keys,

  * `filename` - The file name that was downloaded.
  * `contents` - Base64 encoded zipped contents of the file.

* The file contents are Base64 encoded and they need to be unzipped.

##### List files that can be downloaded

The below mentioned `curl` example can be used to list all the files that were downloaded by the current session in the Node, and which can be retrieved locally.

```bash
curl -X GET "http://localhost:4444/session/90c0149a-2e75-424d-857a-e78734943d4c/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

##### Retrieve a downloaded file

Assuming the downloaded file is named `Red-blue-green-channel.jpg`, and using `curl`, the file could be downloaded with the following command:

```bash
curl -H "Accept: application/json" \
-H "Content-Type: application/json; charset=utf-8" \
-X POST -d '{"name":"Red-blue-green-channel.jpg"}' \
"http://localhost:4444/session/18033434-fa4f-4d11-a7df-9e6d75920e19/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "UEsDBBQACAgIAJpagVYAAAAAAAAAAAAAAAAaAAAAUmVkLWJsAAAAAAAAAAAAUmVkLWJsdWUtZ3JlZW4tY2hhbm5lbC5qcGdQSwUGAAAAAAEAAQBIAAAAcNkAAAAA"
  }
}
```

##### Complete sample code in Java

Below is an example in Java that does the following:

* Sets the capability to indicate that the test requires automatic managing of downloaded files.
* Triggers a file download via a browser.
* Lists the files that are available for retrieval from the remote node (These are essentially files that were downloaded in the current session)
* Picks one file and downloads the file from the remote node to the local machine.

```java
import com.google.common.collect.ImmutableMap;

import org.openqa.selenium.By;
import org.openqa.selenium.io.Zip;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.io.File;
import java.net.URL;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import static org.openqa.selenium.remote.http.Contents.asJson;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.HttpMethod.GET;
import static org.openqa.selenium.remote.http.HttpMethod.POST;

public class DownloadsSample {

  public static void main(String[] args) throws Exception {
    // Assuming the Grid is running locally.
    URL gridUrl = new URL("http://localhost:4444");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("se:downloadsEnabled", true);
    RemoteWebDriver driver = new RemoteWebDriver(gridUrl, options);
    try {
      demoFileDownloads(driver, gridUrl);
    } finally {
      driver.quit();
    }
  }

	private static void demoFileDownloads(RemoteWebDriver driver, URL gridUrl) throws Exception {
		driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
		// Download the two available files on the page
		driver.findElement(By.id("file-1")).click();
		driver.findElement(By.id("file-2")).click();

		// The download happens in a remote Node, which makes it difficult to know when the file
		// has been completely downloaded. For demonstration purposes, this example uses a
		// 10-second sleep which should be enough time for a file to be downloaded.
		// We strongly recommend to avoid hardcoded sleeps, and ideally, to modify your
		// application under test, so it offers a way to know when the file has been completely
		// downloaded.
		TimeUnit.SECONDS.sleep(10);

		//This is the endpoint which will provide us with list of files to download and also to
		//let us download a specific file.
		String downloadsEndpoint = String.format("/session/%s/se/files", driver.getSessionId());

		String fileToDownload;

		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To list all files that are were downloaded on the remote node for the current session
			// we trigger GET request.
			HttpRequest request = new HttpRequest(GET, downloadsEndpoint);
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			@SuppressWarnings("unchecked")
			List<String> names = (List<String>) value.get("names");
			// Let's say there were "n" files downloaded for the current session, we would like
			// to retrieve ONLY the first file.
			fileToDownload = names.get(0);
		}

		// Now, let's download the file
		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To retrieve a specific file from one or more files that were downloaded by the current session
			// on a remote node, we use a POST request.
			HttpRequest request = new HttpRequest(POST, downloadsEndpoint);
			request.setContent(asJson(ImmutableMap.of("name", fileToDownload)));
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			// The returned map would contain 2 keys,
			// filename - This represents the name of the file (same as what was provided by the test)
			// contents - Base64 encoded String which contains the zipped file.
			String zippedContents = value.get("contents").toString();
			// The file contents would always be a zip file and has to be unzipped.
			File downloadDir = Zip.unzipToTempDir(zippedContents, "download", "");
			// Read the file contents
			File downloadedFile = Optional.ofNullable(downloadDir.listFiles()).orElse(new File[]{})[0];
			String fileContent = String.join("", Files.readAllLines(downloadedFile.toPath()));
			System.out.println("The file which was "
					+ "downloaded in the node is now available in the directory: "
					+ downloadDir.getAbsolutePath() + " and has the contents: " + fileContent);
		}
	}


}
```

最后修改 October 3, 2025: [Correct a typo (\*doesnot\*) (#2487) (e189ca8ab39)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e189ca8ab397e914b15658a80c68c84db2274edb)

----
url: https://www.selenium.dev/ja/_print/documentation/webdriver/getting_started/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/webdriver/getting_started/).

# 入門

Seleniumを初めて使用する場合は、すぐに習得するのに役立つリソースがいくつかあります。

* 1: [Seleniumライブラリのインストール](#pg-d0db14108fa0030d3a5db273c2792645)
* 2: [最初のSeleniumスクリプトを書く](#pg-9e6e4115836e074878611ee01fae8c99)
* 3: [Seleniumコードの整理と実行](#pg-38e1ba7a52c7e91b19bfd4a29b1f9010)

# 1 - Seleniumライブラリのインストール

```xml
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/pom.xml#L35-L38)

##### /examples/java/pom.xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>dev.selenium</groupId>
    <artifactId>selenium-examples</artifactId>
    <version>1.0.0</version>

    <properties>
        <surefire.parallel>1</surefire.parallel>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <selenium.version>4.41.0</selenium.version>
    </properties>

    <repositories>
        <repository>
            <name>Central Portal Snapshots</name>
            <id>central-portal-snapshots</id>
            <url>https://central.sonatype.com/repository/maven-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-grid</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>6.0.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.titusfortner</groupId>
            <artifactId>selenium-logger</artifactId>
            <version>2.4.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.5.5</version>
                <configuration>
                    <properties>
                        <configurationParameters>
                            junit.jupiter.execution.parallel.enabled = true
                            junit.jupiter.execution.parallel.mode.default = concurrent
                            junit.jupiter.execution.parallel.config.strategy = fixed
                            junit.jupiter.execution.parallel.config.fixed.parallelism = ${surefire.parallel}
                            junit.jupiter.execution.parallel.config.fixed.max-pool-size = ${surefire.parallel}
                        </configurationParameters>
                    </properties>
                    <rerunFailingTestsCount>3</rerunFailingTestsCount>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
```

### Gradle

プロジェクトの ‘build.gradle’ ファイル内の依存関係を ’testImplementation’ として指定します:

```gradle

dependencies {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/build.gradle#L13-L14)

##### /examples/java/build.gradle

```gradle
plugins {
    id 'java'
}

group 'dev.selenium'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

ext['seleniumVersion'] = System.getProperty('selenium.version', '4.41.0')

dependencies {
    testImplementation "org.seleniumhq.selenium:selenium-java:${seleniumVersion}"
    testImplementation "org.seleniumhq.selenium:selenium-grid:${seleniumVersion}"
    testImplementation platform("org.junit:junit-bom:6.0.2")
    testImplementation 'org.junit.jupiter:junit-jupiter-engine'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    testImplementation 'com.titusfortner:selenium-logger:2.4.0'
}

test {
    useJUnitPlatform()
}
```

各 Selenium バージョンでサポートされている最小 Python バージョンについては、次の場所にあります `サポートされている Python バージョン` オン [PyPi](https://pypi.org/project/selenium/)。

Seleniumをインストールするには、いくつかの方法があります。

### Pip

```shell
pip install selenium
```



### ダウンロード

または、ダウンロードすることもできます[PyPI ソースアーカイブ](https://pypi.org/project/selenium/#files) (selenium-x.x.x.-py3-none-any.whl) を使用してインストールします *pip*:

```shell
pip install selenium-x.x.x.-py3-none-any.whl
```



### プロジェクトで必要

プロジェクトで使用するには、requirements.txt ファイルに追加します:

```txt
selenium==4.41.0
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/requirements.txt#L1)

##### /examples/python/requirements.txt

```txt
selenium==4.41.0
pytest==9.0.3
trio==0.31.0
pytest-trio==0.8.0
pytest-rerunfailures==16.1
flake8==7.3.0
requests==2.33.0
tox==4.32.0
pytest-xdist==3.8.0
```

Seleniumの各バージョンでサポートされているすべてのフレームワークのリスト で利用可能です[Nuget](https://www.nuget.org/packages/Selenium.WebDriver)

Seleniumのインストールにはいくつかのオプションがあります。

### パケットマネージャー

```shell
Install-Package Selenium.WebDriver
```



### .NET CLI

```shell
dotnet add package Selenium.WebDriver
```



### CSProj

プロジェクトの `csproj`ファイルで、`ItemGroup` の `PackageReference`として依存関係を指定します。:

```csproj
      <PackageReference Include="Selenium.WebDriver" Version="4.41.0" />
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/SeleniumDocs.csproj#L14)

##### /examples/dotnet/SeleniumDocs/SeleniumDocs.csproj

```csproj
<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <GenerateProgramFile>false</GenerateProgramFile>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
      <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="7.7.1" />
      <PackageReference Include="MSTest.TestAdapter" Version="3.6.0" />
      <PackageReference Include="MSTest.TestFramework" Version="3.6.0" />
      <PackageReference Include="Selenium.Support" Version="4.41.0" />
      <PackageReference Include="Selenium.WebDriver" Version="4.41.0" />
    </ItemGroup>

    <ItemGroup>
      <Folder Include="LocalPackages" />
    </ItemGroup>

</Project>
```

### その他の考慮事項

その他、使用上の注意点 Visual Studio Code (vscode) そして C#

上記のセクションに従って、互換性のある .NET SDK をインストールします。 また、C# と NuGet の vscode 拡張機能 (Ctrl-Shift-X) もインストールします。に従ってください[指示はこちら](https://docs.microsoft.com/en-us/dotnet/core/tutorials/with-visual-studio-code?pivots=dotnet-5-0) C# を使用して “Hello World” コンソール プロジェクトを作成および実行します。 コマンドラインを使用してNUnitスタータープロジェクトを作成することもできます `dotnet new NUnit`. ファイルを確認してください `%appdata%\NuGet\nuget.config`一部の開発者がいくつかの問題のために空になると報告したため、適切に構成されています。 もし`nuget.config`が空であるか、正しく構成されていない場合、Selenium プロジェクトの .NET ビルドは失敗します。 次のセクションをファイルに追加します`nuget.config` 空の場合:

```
<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />   
  </packageSources>
...
```

詳細については、`nuget.config` [ここをクリック](https://docs.microsoft.com/en-us/nuget/reference/nuget-config-file). カスタマイズする必要があるかもしれません `nuget.config` あなたのニーズを満たすために。

さて、戻ってください vscode、プレス Ctrl-Shift-P、およびタイプ “NuGet Add Package"をクリックし、必要な Selenium パッケージ `Selenium.WebDriver`. Enter キーを押して、バージョンを選択します。 これで、C# と vscode に関連するドキュメントの例を使用できるようになりました。

特定の Selenium バージョンに対して最低限必要な Ruby のバージョンを確認できます オン [rubygems.org](https://rubygems.org/gems/selenium-webdriver/)

Seleniumは2つの異なる方法でインストールできます。

### 手動でインストールする

```shell
gem install selenium-webdriver
```



### プロジェクトの gemfile に追加

```gemfile
gem 'selenium-devtools', '= 0.147.0'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/Gemfile#L10)

##### /examples/ruby/Gemfile

```gemfile
# frozen_string_literal: true

source 'https://rubygems.org'

gem 'ffi', '~> 1.15', '>= 1.15.5' if Gem.win_platform? # Windows only
gem 'rake', '~> 13.0'
gem 'rspec', '~> 3.0'
gem 'rubocop', '~> 1.35'
gem 'rubocop-rspec', '~> 3.0'
gem 'selenium-devtools', '= 0.147.0'
gem 'selenium-webdriver', '= 4.43.0'
```

Seleniumの特定のバージョンに最低限必要なNodeのバージョンは、`Node Support Policy` 節 オン [npmjs](https://www.npmjs.com/package/selenium-webdriver)

Seleniumは通常、npmを使用してインストールされます。

### ローカルにインストールする

```shell
npm install selenium-webdriver
```



### プロジェクトに加える

プロジェクトの `package.json`で、要件を `dependencies`:

```json
        "mocha": "11.7.5"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/package.json#L14)

##### /examples/javascript/package.json

```json
{
    "name": "javascript-examples",
    "version": "1.0.0",
    "scripts": {
        "test": "npx mocha test/**/*.spec.js --timeout 120000 --parallel --retries 2"
    },
    "author": "The Selenium project",
    "license": "Apache-2.0",
    "dependencies": {
        "assert": "2.1.0",
        "selenium-webdriver": "4.41.0"
    },
    "devDependencies": {
        "mocha": "11.7.5"
    }
}
```

Kotlin の Java バインディングを使用します。

## 次のステップ

[初めてのSeleniumスクリプトを作成する](https://www.selenium.dev/ja/documentation/webdriver/getting_started/first_script/)

# 2 - 最初のSeleniumスクリプトを書く

```java
        WebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver = webdriver.Chrome()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L4)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L11)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver = Selenium::WebDriver.for :chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L3)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    driver = await new Builder().forBrowser(Browser.CHROME).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L8)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver = ChromeDriver()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L16)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.get("https://www.selenium.dev/selenium/web/web-form.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L6)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L13)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.get('https://www.selenium.dev/selenium/web/web-form.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L5)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L9)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.get("https://www.selenium.dev/selenium/web/web-form.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L18)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#16)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L8)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var title = driver.Title;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L15)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L7)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let title = await driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L11)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L20)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L18)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.implicitly_wait(0.5)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L10)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L17)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.manage.timeouts.implicit_wait = 500
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L9)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.manage().setTimeouts({implicit: 500});
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L14)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L23)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L20-L21)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L12-L13)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L19-L20)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L11-L12)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L16-L17)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L25-L26)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        textBox.sendKeys("Selenium");
        submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L23-L24)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
text_box.send_keys("Selenium")
submit_button.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L15-L16)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        textBox.SendKeys("Selenium");
        submitButton.Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
text_box.send_keys('Selenium')
submit_button.click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L14-L15)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await textBox.sendKeys('Selenium');
    await submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L19-L20)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        textBox.sendKeys("Selenium")
        submitButton.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L28-L29)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        WebElement message = driver.findElement(By.id("message"));
        message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-27)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
message = driver.find_element(by=By.ID, value="message")
text = message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L18-19)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-26)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
message = driver.find_element(id: 'message')
message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L17-18)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L22-23)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val message = driver.findElement(By.id("message"))
        val value = message.getText()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-32)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L21)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L28)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L20)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L28)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L35)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```md
mvn exec:java -D"exec.mainClass"="dev.selenium.getting_started.FirstScript" -D"exec.classpathScope"=test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/README.md#L60)

##### /examples/java/README.md

````md
# Running Selenium Java Tests
The following steps will guide you on how to 
run Selenium Java tests using a repository 
of `SeleniumHQ/seleniumhq.github.io` examples.

## Initial Setup

### Prerequisites

Ensure that Java Development Kit (JDK) and Maven 
are installed on your system. If they are not installed, 
you will need to download and install them. You can 
find detailed installation guides for both on their 
respective official sites.

### Clone the repository
First, we need to get the Selenium Java examples 
on your local machine. This can be done by 
cloning the `SeleniumHQ/seleniumhq.github.io` Git repository. 
Run the following command in your terminal:

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```
## Navigate to the java directory
After cloning the repository, navigate into the 
directory where the Selenium Java examples are 
located. Run the following command:

```bash
cd seleniumhq.github.io/examples/java
```

## Running the Tests
### Install dependencies
Before running the tests, we need to install all 
necessary dependencies. Maven, a software 
project management tool, can do this for us. 
Run the following command:

```bash
mvn test-compile
```

### Run all tests
To verify if everything is installed correctly and 
functioning properly, we should run all 
available tests. This can be done with the following command:

```bash
mvn test
```

Please be patient! If this is your first time running these tests, 
it might take a while to download and verify all necessary browser drivers.

## Execute a specific example
To run a specific Selenium Java example, use the following command:
```bash
mvn exec:java -D"exec.mainClass"="dev.selenium.getting_started.FirstScript" -D"exec.classpathScope"=test
```

Make sure to replace `dev.selenium.getting_started.FirstScript` with the path and name of the example you want to run.
````

````md
```
````

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/README.md#L35)

##### /examples/python/README.md

````md
# Running tests from Selenium Python examples

#### 1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

#### 2. Navigate to `python` directory

```
cd seleniumhq.github.io/examples/python
```

#### 3. Create a virtual environment

- On Windows:

```
py -m venv venv
venv\Scripts\activate
```

- On Linux/Mac:

```
python3 -m venv venv
source venv/bin/activate
```

#### 4. Install dependencies:

```
pip install -r requirements.txt
```

> for help, see: https://packaging.python.org/en/latest/tutorials/installing-packages

#### 5. Run tests

- Run all tests with the default Python interpreter:

```
pytest
```

- Run all tests with every installed/supported Python interpreter:

```
tox
```

> Please have some patience - If you are doing it for the first time, it will take a little while to download the browser drivers

- Run a specific example:

```
pytest path/to/test_script.py
```

> Make sure to replace `path/to/test_script.py` with the path and name of the example you want to run
````

```md
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/README.md#L55)

##### /examples/dotnet/README.md

````md

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

## Navigate to the .NET directory
### Change into the .NET examples directory:

```bash
cd seleniumhq.github.io/examples/dotnet/SeleniumDocs
```

## Running the Tests
### Restore dependencies
Install necessary dependencies using the .NET CLI:

```bash
dotnet restore
```

### Run all tests
To run all available tests:

```bash
dotnet test
```

### Run a Specific Test Method
To run a specific test method using its fully qualified name:

```bash
dotnet test --filter "FullyQualifiedName=Namespace.ClassName.MethodName"
```
For example:
```bash
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

You can also filter by test name only (if it's unique):
```bash
dotnet test --filter "Name=EightComponents"
```
````

```md
ruby example_script.rb
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/README.md#L36)

##### /examples/ruby/README.md

````md
# Running all tests from Selenium ruby example

Follow these steps to run all test example from selenium ruby

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `ruby` directory

```
cd seleniumhq.github.io/examples/ruby
```

3. Install dependencies using bundler

```
bundler install
```

4. Run all tests

```
bundle exec rspec
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a ruby script

Use this command to run a ruby script and follow the first script example

```
ruby example_script.rb
```
````

```md
node example_script.spec.js
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/README.md#L36)

##### /examples/javascript/README.md

````md
# Running all tests from Selenium javascript example

Follow these steps to run all test example from selenium javascript

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `javascript` directory

```
cd seleniumhq.github.io/examples/javascript
```

3. Install dependencies using node

```
npm install
```

4. Run all all tests

```
npm test
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a javascript test

Use this command to run a JavaScript and follow the first script example

```
node example_script.spec.js
```
````

[Add Example](/documentation/about/contributing/#creating-examples)

## 次のステップ

ほとんどのSeleniumユーザーは多くのセッションを実行し、重複を最小限に抑え、コードをより保守しやすくするために整理する必要があります。このコードをユースケースのコンテキストに配置する方法については、以下をお読みください [Seleniumの使用](https://www.selenium.dev/ja/documentation/webdriver/getting_started/using_selenium/)。

# 3 - Seleniumコードの整理と実行

IDEとテストランナーライブラリを使用したSelenium実行のスケーリング

一握り以上の 1 回限りのスクリプトを実行する場合は、コードを整理して操作できる必要があります。このページでは、Seleniumコードを使用して実際に生産的なことを行う方法についてのアイデアを提供します。

## 一般的な用途

ほとんどの人はSeleniumを使用してWebアプリケーションの自動テストを実行します。 しかし、Seleniumはブラウザ自動化のあらゆるユースケースをサポートします。

### 反復タスク

おそらく、Webサイトにログインして何かをダウンロードするか、フォームを送信する必要があります。 Selenium スクリプトを作成して、あらかじめ設定された時間にサービスと共に実行できます。

### Webスクレイピング

APIがないサイトからデータを収集したいとお考えですか?セレン これを行うことができますが、Webサイトに精通していることを確認してください。 一部のWebサイトでは許可されておらず、他のWebサイトではSeleniumがブロックされることさえあります。

### テスティング

テストのためにSeleniumを実行するには、Seleniumが実行したアクションに対してアサーションを行う必要があります。 したがって、優れたアサーションライブラリが必要です。テストの構造を提供する追加機能 使用する必要があります [Test Runner](/ja/documentation/webdriver/getting_started/using_selenium/#test-runner).

## IDEs

Seleniumコードの使用方法に関係なく、優れた統合開発環境がなければ、Seleniumコードの作成や実行はあまり効果的ではありません。一般的なオプションを次に示します…

* [Eclipse](https://www.eclipse.org/)
* [IntelliJ IDEA](https://www.jetbrains.com/idea/)
* [PyCharm](https://www.jetbrains.com/pycharm/)
* [RubyMine](https://www.jetbrains.com/ruby/)
* [Rider](https://www.jetbrains.com/rider/)
* [WebStorm](https://www.jetbrains.com/webstorm/)
* [VS Code](https://code.visualstudio.com/)

## Test Runner

テストにSeleniumを使用していない場合でも、高度なユースケースがある場合は、テストランナーを使用してコードをより適切に整理するのが理にかなっている場合があります。before/after フックを使用して、グループまたは並行して物事を実行できると非常に便利です。

### 卜

さまざまなテストランナーが利用可能です。

このドキュメントのすべてのコード例は、 テストランナーを使用し、すべてのコードが正しく更新されていることを確認するためにリリースごとに実行されるディレクトリの例。 リンク付きのテストランナーのリストを次に示します。最初の項目は、このリポジトリで使用される項目と このページのすべての例で使用されます。

*
*
*
*
*
*

- [JUnit](https://junit.org/junit5/) - JavaベースのSeleniumテストで広く使用されているテストフレームワーク。
- [TestNG](https://testng.org/) - 並列テスト実行やパラメーター化されたテストなどの追加機能を提供します。

* [pytest](https://pytest.org/) - そのシンプルさと強力なプラグインのおかげで、多くの人に好まれる選択肢です。
* [unittest](https://docs.python.org/3/library/unittest.html) - Python の標準ライブラリテストフレームワーク。

- [NUnit](https://nunit.org/) - .NET の一般的な単体テスト フレームワーク。
- [MS Test](https://docs.microsoft.com/en-us/visualstudio/test/getting-started-with-unit-testing?view=vs-2019) - Microsoft 独自の単体テスト フレームワーク。

* [RSpec](https://rspec.info/) - RubyでSeleniumテストを実行するために最も広く使用されているテストライブラリ。
* [Minitest](https://github.com/seattlerb/minitest) - Ruby標準ライブラリに付属する軽量なテストフレームワークです。

- [Jest](https://jestjs.io/) - 主にReactのテストフレームワークとして知られていますが、Seleniumのテストにも使用できます。
- [Mocha](https://mochajs.org/) - Seleniumテストを実行するための最も一般的なJSライブラリ。

* [Kotest](https://kotest.io/) - Kotlin専用に設計された、柔軟で包括的なテストフレームワークです。
* [JUnit5](https://junit.org/junit5/) - 標準的なJavaテストフレームワークであり、Kotlinと完全に互換性があります。

### 装着

これは、で必要とされたものと非常によく似ています [Seleniumライブラリのインストール](https://www.selenium.dev/ja/documentation/webdriver/getting_started/install_library/)。このコードは、私たちのドキュメント例プロジェクトで使用されているものの例を示しているだけです。

*
*
*
*
*
*

**Maven**

**Gradle**

プロジェクトで使用するには、requirements.txt ファイルに追加します:

プロジェクトの ‘csproj’ ファイルで、依存関係を ‘ItemGroup’ の ‘PackageReference’ として指定します:

プロジェクトの gemfile に追加

プロジェクトの ‘package.json’ で、要件を ‘dependencies’ に追加します。:

### 主張

*
*
*
*
*
*

```java
		String title = driver.getTitle();
		assertEquals("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L30-L31)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

```py
    title = driver.title
    assert title == "Web form"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L8-L9)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

```cs
            var title = driver.Title;
            Assert.AreEqual("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs#L19-L20)

##### /examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted
{
    [TestClass]
    public class UsingSeleniumTest
    {

        [TestMethod]
        public void EightComponents()
        {
            IWebDriver driver = new ChromeDriver();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

            var title = driver.Title;
            Assert.AreEqual("Web form", title);

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            var textBox = driver.FindElement(By.Name("my-text"));
            var submitButton = driver.FindElement(By.TagName("button"));
            
            textBox.SendKeys("Selenium");
            submitButton.Click();
            
            var message = driver.FindElement(By.Id("message"));
            var value = message.Text;
            Assert.AreEqual("Received!", value);
            
            driver.Quit();
        }
    }
}
```

```rb
    title = @driver.title
    expect(title).to eq('Web form')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb#L14-L15)

##### /examples/ruby/spec/getting\_started/using\_selenium\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

```js
    let title = await driver.getTitle();
    assert.equal("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L14-L15)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

```kt
        val title = driver.title
        assertEquals("Web form", title)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L20-21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt

    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

### セットアップとティアダウン

*
*
*
*
*
*

### 並べる

```java
	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L19-L22)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

### 取り壊す

```java
	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L45-L48)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

### 並べる

```py
def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L25-L28)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

### 取り壊す

```py
def teardown(driver):
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L30-31)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

### 並べる

```rb
  before do
    @driver = Selenium::WebDriver.for :chrome
  end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb#L7-L9)

##### /examples/ruby/spec/getting\_started/using\_selenium\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

### 取り壊す

```rb
  config.after { @driver&.quit }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/spec_helper.rb#L30)

##### /examples/ruby/spec/spec\_helper.rb

```rb

    c.syntax = :expect
  end

  config.before do |example|
    bug_tracker = 'https://github.com/SeleniumHQ/seleniumhq.github.io/issues'
    guards = Selenium::WebDriver::Support::Guards.new(example,
                                                      bug_tracker: bug_tracker)
    guards.add_condition(:platform, Selenium::WebDriver::Platform.os)
    guards.add_condition(:ci, Selenium::WebDriver::Platform.ci)

    results = guards.disposition
    send(*results) if results
  end

  config.after { @driver&.quit }

  def start_session
    options = Selenium::WebDriver::Chrome::Options.new
    options.add_argument('disable-search-engine-choice-screen')
    options.add_argument('--no-sandbox')
    @driver = Selenium::WebDriver.for(:chrome, options: options)
  end

  def start_bidi_session
    options = Selenium::WebDriver::Chrome::Options.new(web_socket_url: true)
    @driver = Selenium::WebDriver.for :chrome, options: options
  end

  def start_firefox
    options = Selenium::WebDriver::Options.firefox(timeouts: {implicit: 1500})
    @driver = Selenium::WebDriver.for :firefox, options: options
  end
end
```

\### 並べる

```js
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L7-L9)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

\### 取り壊す

```js
  after(async () => await driver.quit());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L30)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

### 実行

*
*
*
*
*
*

### Maven

```shell
mvn clean test
```

### Gradle

```shell
gradle clean test
```

````md
```
````

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/README.md#L35)

##### /examples/python/README.md

````md
# Running tests from Selenium Python examples

#### 1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

#### 2. Navigate to `python` directory

```
cd seleniumhq.github.io/examples/python
```

#### 3. Create a virtual environment

- On Windows:

```
py -m venv venv
venv\Scripts\activate
```

- On Linux/Mac:

```
python3 -m venv venv
source venv/bin/activate
```

#### 4. Install dependencies:

```
pip install -r requirements.txt
```

> for help, see: https://packaging.python.org/en/latest/tutorials/installing-packages

#### 5. Run tests

- Run all tests with the default Python interpreter:

```
pytest
```

- Run all tests with every installed/supported Python interpreter:

```
tox
```

> Please have some patience - If you are doing it for the first time, it will take a little while to download the browser drivers

- Run a specific example:

```
pytest path/to/test_script.py
```

> Make sure to replace `path/to/test_script.py` with the path and name of the example you want to run
````

```md
dotnet test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/README.md#L44)

##### /examples/dotnet/README.md

````md
# Running Selenium .NET (C#) Tests

The following steps will guide you on how to  
run Selenium .NET (C#) tests using the examples  
from the `SeleniumHQ/seleniumhq.github.io` repository.

## Initial Setup

### Prerequisites

Ensure you have the following installed:

- [.NET SDK (8.0 or later)](https://dotnet.microsoft.com/en-us/download)
- An IDE like [Visual Studio](https://visualstudio.microsoft.com/) or [Visual Studio Code](https://code.visualstudio.com/)
- [.NET CLI tools](https://learn.microsoft.com/en-us/dotnet/core/tools/)

### Clone the repository

Clone the Selenium documentation repository to your local machine:

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

## Navigate to the .NET directory
### Change into the .NET examples directory:

```bash
cd seleniumhq.github.io/examples/dotnet/SeleniumDocs
```

## Running the Tests
### Restore dependencies
Install necessary dependencies using the .NET CLI:

```bash
dotnet restore
```

### Run all tests
To run all available tests:

```bash
dotnet test
```

### Run a Specific Test Method
To run a specific test method using its fully qualified name:

```bash
dotnet test --filter "FullyQualifiedName=Namespace.ClassName.MethodName"
```
For example:
```bash
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

You can also filter by test name only (if it's unique):
```bash
dotnet test --filter "Name=EightComponents"
```
````

```md
bundle exec rspec
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/README.md#L26)

##### /examples/ruby/README.md

````md
# Running all tests from Selenium ruby example

Follow these steps to run all test example from selenium ruby

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `ruby` directory

```
cd seleniumhq.github.io/examples/ruby
```

3. Install dependencies using bundler

```
bundler install
```

4. Run all tests

```
bundle exec rspec
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a ruby script

Use this command to run a ruby script and follow the first script example

```
ruby example_script.rb
```
````

### Mocha

```shell
mocha runningTests.spec.js
```

### npx

```shell
npx mocha runningTests.spec.js
```

[Add Example](/documentation/about/contributing/#creating-examples)

### 例

[最初のスクリプト](https://www.selenium.dev/ja/documentation/webdriver/getting_started/first_script/)のトピックでは、Seleniumスクリプトの各コンポーネントを見ました。こちらが、テストランナーを使用したそのコードの例です。

*
*
*
*
*
*

```java
package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java)

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py)

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted
{
    [TestClass]
    public class UsingSeleniumTest
    {

        [TestMethod]
        public void EightComponents()
        {
            IWebDriver driver = new ChromeDriver();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

            var title = driver.Title;
            Assert.AreEqual("Web form", title);

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            var textBox = driver.FindElement(By.Name("my-text"));
            var submitButton = driver.FindElement(By.TagName("button"));
            
            textBox.SendKeys("Selenium");
            submitButton.Click();
            
            var message = driver.FindElement(By.Id("message"));
            var value = message.Text;
            Assert.AreEqual("Received!", value);
            
            driver.Quit();
        }
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs)

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb)

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js)

[Add Example](/documentation/about/contributing/#creating-examples)

## 次のステップ

学んだことを活かして、Seleniumコードを構築します!

必要な機能が他にも見つかったら、残りの機能をお読みください [WebDriver ドキュメント](https://www.selenium.dev/ja/documentation/webdriver/).

----
url: https://www.selenium.dev/zh-cn/documentation/ide/
----

# Selenium IDE

Selenium IDE是一个记录和回放用户操作的浏览器扩展.

Selenium的集成开发环境 ([Selenium IDE](//selenium.dev/selenium-ide)) 是一个易于使用的浏览器扩展, 利用既定的Selenium命令记录用户的浏览器行为, 参数由每个元素的上下文定义. 它提供了一种学习Selenium语法的极好方法. 其适用于谷歌Chrome、Mozilla火狐以及微软Edge浏览器.

有关更多信息, 请访问完整的 [Selenium IDE 文档](https://www.selenium.dev/selenium-ide/docs/en/introduction/getting-started)

最后修改 January 4, 2022: [Update Chinese translation of "ide" (#911)\[deploy site\] (21684dc1101)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/21684dc110106cd6f60c6686636fc99fa8fcc684)

----
url: https://www.selenium.dev/documentation/webdriver/bidi/cdp/network/
----

# Chrome DevTools Network Features

```java
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L41-L43)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
        credentials = base64.b64encode("admin:admin".encode()).decode()
        auth = {'authorization': 'Basic ' + credentials}
        await connection.session.execute(connection.devtools.network.set_extra_http_headers(Headers(auth)))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L13-15)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L25-L32)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L9-L11)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      HttpResponse res = next.execute(req);
                      contentType.add(res.getHeader("Content-Type"));
                      return res;
                    })) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L56-L65)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L46-L51)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L20-L24)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    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!"))))) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L75-L85)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L62-L73)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L31-L35)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L97-L110)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L85-L97)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    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
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L42-L46)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L125-L126)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    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())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L26-L28)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L114-L118)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L56-L57)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    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()));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L142-L157)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L37-L44)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L136-L143)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L68-L71)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    devTools.send(
            Browser.setDownloadBehavior(
                    Browser.SetDownloadBehaviorBehavior.ALLOWANDNAME,
                    Optional.empty(),
                    Optional.of(""),
                    Optional.of(true)));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L171-L176)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    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
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L82-L88)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/bidi/cdp/logging/
----

```java
    ((HasLogEvents) driver).onLogEvent(consoleEvent(e -> messages.add(e.getMessages().get(0))));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/LoggingTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/LoggingTest.java

```java
package dev.selenium.bidi.cdp;

import static org.openqa.selenium.devtools.events.CdpEventTypes.consoleEvent;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.CopyOnWriteArrayList;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.HasLogEvents;
import org.openqa.selenium.support.ui.WebDriverWait;

public class LoggingTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void consoleLogs() {
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    CopyOnWriteArrayList<String> messages = new CopyOnWriteArrayList<>();

    ((HasLogEvents) driver).onLogEvent(consoleEvent(e -> messages.add(e.getMessages().get(0))));

    driver.findElement(By.id("consoleLog")).click();
    driver.findElement(By.id("consoleError")).click();

    wait.until(_d -> messages.size() > 1);
    Assertions.assertTrue(messages.contains("Hello, world!"));
    Assertions.assertTrue(messages.contains("I am console error"));
  }
}
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_logs.py#L11-12)

##### /examples/python/tests/bidi/cdp/test\_logs.py

```py
import pytest
from selenium.webdriver.common.bidi.console import Console
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log


@pytest.mark.trio
async def test_console_log(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
            driver.find_element(by=By.ID, value='consoleLog').click()

        assert messages["message"] == "Hello, world!"


@pytest.mark.trio
async def test_js_error(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
            driver.find_element(by=By.ID, value='jsException').click()

        assert "Error: Not working" in messages.exception_details.exception.description
```

```cs
            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs#L19-L25)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class LoggingTest : BaseChromeTest
    {
        [TestMethod]
        public async Task ConsoleLogs()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("consoleLog")).Click();
            driver.FindElement(By.Id("consoleError")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => messages.Count > 1);
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Hello, world!"));
            Assert.IsTrue(messages.Contains("I am console error"));
        }
        
        [TestMethod]
        public async Task JsErrors()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("jsException")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !messages.IsNullOrEmpty());
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Uncaught"));
        }
    }
}
```

```rb
    driver.on_log_event(:console) { |log| logs << log.args.first }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/logging_spec.rb#L12)

##### /examples/ruby/spec/bidi/cdp/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'listens for console logs' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    logs = []
    driver.on_log_event(:console) { |log| logs << log.args.first }

    driver.find_element(id: 'consoleLog').click
    driver.find_element(id: 'consoleError').click

    Selenium::WebDriver::Wait.new.until { logs.size > 1 }
    expect(logs).to include 'Hello, world!'
    expect(logs).to include 'I am console error'
  end

  it 'listens for js exception' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    exceptions = []
    driver.on_log_event(:exception) { |exception| exceptions << exception }

    driver.find_element(id: 'jsException').click

    Selenium::WebDriver::Wait.new.until { exceptions.any? }
    expect(exceptions.first&.description).to include 'Error: Not working'
  end
end
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_logs.py#L22-L23)

##### /examples/python/tests/bidi/cdp/test\_logs.py

```py
import pytest
from selenium.webdriver.common.bidi.console import Console
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log


@pytest.mark.trio
async def test_console_log(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
            driver.find_element(by=By.ID, value='consoleLog').click()

        assert messages["message"] == "Hello, world!"


@pytest.mark.trio
async def test_js_error(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
            driver.find_element(by=By.ID, value='jsException').click()

        assert "Error: Not working" in messages.exception_details.exception.description
```

```cs
            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs#L41-L47)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class LoggingTest : BaseChromeTest
    {
        [TestMethod]
        public async Task ConsoleLogs()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("consoleLog")).Click();
            driver.FindElement(By.Id("consoleError")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => messages.Count > 1);
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Hello, world!"));
            Assert.IsTrue(messages.Contains("I am console error"));
        }
        
        [TestMethod]
        public async Task JsErrors()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("jsException")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !messages.IsNullOrEmpty());
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Uncaught"));
        }
    }
}
```

```rb
    driver.on_log_event(:exception) { |exception| exceptions << exception }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/logging_spec.rb#L26)

##### /examples/ruby/spec/bidi/cdp/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'listens for console logs' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    logs = []
    driver.on_log_event(:console) { |log| logs << log.args.first }

    driver.find_element(id: 'consoleLog').click
    driver.find_element(id: 'consoleError').click

    Selenium::WebDriver::Wait.new.until { logs.size > 1 }
    expect(logs).to include 'Hello, world!'
    expect(logs).to include 'I am console error'
  end

  it 'listens for js exception' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    exceptions = []
    driver.on_log_event(:exception) { |exception| exceptions << exception }

    driver.find_element(id: 'jsException').click

    Selenium::WebDriver::Wait.new.until { exceptions.any? }
    expect(exceptions.first&.description).to include 'Error: Not working'
  end
end
```

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/overview/
----

# Sobre automação de testes

```java
// Crie um usuário que tenha permissões somente leitura - eles podem configurar um unicórnio,
// mas eles não têm informações de pagamento configuradas, nem têm
// privilégios administrativos. No momento em que o usuário é criado, seu endereço
// de e-mail e senha são gerados aleatoriamente - você nem precisa
// conhecê-los.
User user = UserFactory.createCommonUser(); //Este método está definido em algum outro lugar.

// Faça login como este usuário.
// O login neste site leva você à sua página pessoal "Minha conta", e então
// o objeto AccountPage é retornado pelo método loginAs, permitindo que você
// execute ações da AccountPage.
AccountPage accountPage = loginAs(user.getEmail(), user.getPassword());
  
```

```python
# Crie um usuário que tenha permissões somente leitura - eles podem configurar um unicórnio,
# mas eles não têm informações de pagamento configuradas, nem têm
# privilégios administrativos. No momento em que o usuário é criado, seu endereço
# de e-mail e senha são gerados aleatoriamente - você nem precisa
# conhecê-los.
user = user_factory.create_common_user() #This method is defined elsewhere.

# Faça login como este usuário.
# O login neste site leva você à sua página pessoal "Minha conta", e então
# o objeto AccountPage é retornado pelo método loginAs, permitindo que você
# execute ações da AccountPage.
account_page = login_as(user.get_email(), user.get_password())
  
```

```csharp
// Crie um usuário que tenha permissões somente leitura - eles podem configurar um unicórnio,
// mas eles não têm informações de pagamento configuradas, nem têm
// privilégios administrativos. No momento em que o usuário é criado, seu endereço
// de e-mail e senha são gerados aleatoriamente - você nem precisa
// conhecê-los.
User user = UserFactory.CreateCommonUser(); //This method is defined elsewhere.

// Faça login como este usuário.
// O login neste site leva você à sua página pessoal "Minha conta", e então
// o objeto AccountPage é retornado pelo método loginAs, permitindo que você
// execute ações da AccountPage.
AccountPage accountPage = LoginAs(user.Email, user.Password);
  
```

```ruby
# Crie um usuário que tenha permissões somente leitura - eles podem configurar um unicórnio,
# mas eles não têm informações de pagamento configuradas, nem têm
# privilégios administrativos. No momento em que o usuário é criado, seu endereço
# de e-mail e senha são gerados aleatoriamente - você nem precisa
# conhecê-los.
user = UserFactory.create_common_user #This method is defined elsewhere.

# Faça login como este usuário.
# O login neste site leva você à sua página pessoal "Minha conta", e então
# o objeto AccountPage é retornado pelo método loginAs, permitindo que você
# execute ações da AccountPage.
account_page = login_as(user.email, user.password)
  
```

```javascript
// Crie um usuário que tenha permissões somente leitura - eles podem configurar um unicórnio,
// mas eles não têm informações de pagamento configuradas, nem têm
// privilégios administrativos. No momento em que o usuário é criado, seu endereço
// de e-mail e senha são gerados aleatoriamente - você nem precisa
// conhecê-los.
var user = userFactory.createCommonUser(); //This method is defined elsewhere.

// Faça login como este usuário.
// O login neste site leva você à sua página pessoal "Minha conta", e então
// o objeto AccountPage é retornado pelo método loginAs, permitindo que você
// execute ações da AccountPage.
var accountPage = loginAs(user.email, user.password);
  
```

```kotlin
// Crie um usuário que tenha permissões somente leitura - eles podem configurar um unicórnio,
// mas eles não têm informações de pagamento configuradas, nem têm
// privilégios administrativos. No momento em que o usuário é criado, seu endereço
// de e-mail e senha são gerados aleatoriamente - você nem precisa
// conhecê-los.
val user = UserFactory.createCommonUser() //This method is defined elsewhere.

// Faça login como este usuário.
// O login neste site leva você à sua página pessoal "Minha conta", e então
// o objeto AccountPage é retornado pelo método loginAs, permitindo que você
// execute ações da AccountPage.
val accountPage = loginAs(user.getEmail(), user.getPassword())
  
```

```java
// O Unicórnio é um objeto de nível superior - ele possui atributos, que são definidos aqui.
// Isso armazena apenas os valores; não preenche formulários da web nem interage
// com o navegador de qualquer forma.
Unicorn sparkles = new Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS);

// Uma vez que já estamos "na" página da conta, temos que usá-la para chegar ao
// lugar real onde você configura os unicórnios. Chamar o método "Add Unicorn"
// nos leva lá.
AddUnicornPage addUnicornPage = accountPage.addUnicorn();

// Agora que estamos na AddUnicornPage, passaremos o objeto "sparkles" para
// o método createUnicorn(). Este método pegará os atributos do Sparkles,
// preencher o formulário e clicar em enviar.
UnicornConfirmationPage unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles);
  
```

```python
# O Unicórnio é um objeto de nível superior - ele possui atributos, que são definidos aqui.
# Isso armazena apenas os valores; não preenche formulários da web nem interage
# com o navegador de qualquer forma.
sparkles = Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

# Uma vez que já estamos "na" página da conta, temos que usá-la para chegar ao
# lugar real onde você configura os unicórnios. Chamar o método "Add Unicorn"
# nos leva lá.
add_unicorn_page = account_page.add_unicorn()

# Agora que estamos na AddUnicornPage, passaremos o objeto "sparkles" para
# o método createUnicorn(). Este método pegará os atributos do Sparkles,
# preencher o formulário e clicar em enviar.
unicorn_confirmation_page = add_unicorn_page.create_unicorn(sparkles)
  
```

```csharp
// O Unicórnio é um objeto de nível superior - ele possui atributos, que são definidos aqui.
// Isso armazena apenas os valores; não preenche formulários da web nem interage
// com o navegador de qualquer forma.
Unicorn sparkles = new Unicorn("Sparkles", UnicornColors.Purple, UnicornAccessories.Sunglasses, UnicornAdornments.StarTattoos);

// Uma vez que já estamos "na" página da conta, temos que usá-la para chegar ao
// lugar real onde você configura os unicórnios. Chamar o método "Add Unicorn"
// nos leva lá.
AddUnicornPage addUnicornPage = accountPage.AddUnicorn();

// Agora que estamos na AddUnicornPage, passaremos o objeto "sparkles" para
// o método createUnicorn(). Este método pegará os atributos do Sparkles,
// preencher o formulário e clicar em enviar.
UnicornConfirmationPage unicornConfirmationPage = addUnicornPage.CreateUnicorn(sparkles);
  
```

```ruby
# O Unicórnio é um objeto de nível superior - ele possui atributos, que são definidos aqui.
# Isso armazena apenas os valores; não preenche formulários da web nem interage
# com o navegador de qualquer forma.
sparkles = Unicorn.new('Sparkles', UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

# Uma vez que já estamos "na" página da conta, temos que usá-la para chegar ao
# lugar real onde você configura os unicórnios. Chamar o método "Add Unicorn"
# nos leva lá.
add_unicorn_page = account_page.add_unicorn

# Agora que estamos na AddUnicornPage, passaremos o objeto "sparkles" para
# o método createUnicorn(). Este método pegará os atributos do Sparkles,
# preencher o formulário e clicar em enviar.
unicorn_confirmation_page = add_unicorn_page.create_unicorn(sparkles)
  
```

```javascript
// O Unicórnio é um objeto de nível superior - ele possui atributos, que são definidos aqui.
// Isso armazena apenas os valores; não preenche formulários da web nem interage
// com o navegador de qualquer forma.
var sparkles = new Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS);

// Uma vez que já estamos "na" página da conta, temos que usá-la para chegar ao
// lugar real onde você configura os unicórnios. Chamar o método "Add Unicorn"
// nos leva lá.
var addUnicornPage = accountPage.addUnicorn();

// Agora que estamos na AddUnicornPage, passaremos o objeto "sparkles" para
// o método createUnicorn(). Este método pegará os atributos do Sparkles,
// preencher o formulário e clicar em enviar.
var unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles);

  
```

```kotlin
// O Unicórnio é um objeto de nível superior - ele possui atributos, que são definidos aqui.
// Isso armazena apenas os valores; não preenche formulários da web nem interage
// com o navegador de qualquer forma.
val sparkles = Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

// Uma vez que já estamos "na" página da conta, temos que usá-la para chegar ao
// lugar real onde você configura os unicórnios. Chamar o método "Add Unicorn"
// nos leva lá.
val addUnicornPage = accountPage.addUnicorn()

// Agora que estamos na AddUnicornPage, passaremos o objeto "sparkles" para
// o método createUnicorn(). Este método pegará os atributos do Sparkles,
// preencher o formulário e clicar em enviar.
unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles)

  
```

```java
// O método exists() de UnicornConfirmationPage pegará o objeto
// Sparkles - uma especificação dos atributos que você deseja ver e compará-los
// com os campos na página
Assert.assertTrue("Sparkles should have been created, with all attributes intact", unicornConfirmationPage.exists(sparkles));
  
```

```python
# O método exists() de UnicornConfirmationPage pegará o objeto
# Sparkles - uma especificação dos atributos que você deseja ver e compará-los
# com os campos na página
assert unicorn_confirmation_page.exists(sparkles), "Sparkles should have been created, with all attributes intact"
  
```

```csharp
// O método exists() de UnicornConfirmationPage pegará o objeto
// Sparkles - uma especificação dos atributos que você deseja ver e compará-los
// com os campos na página
Assert.True(unicornConfirmationPage.Exists(sparkles), "Sparkles should have been created, with all attributes intact");
  
```

```ruby
# O método exists() de UnicornConfirmationPage pegará o objeto
# Sparkles - uma especificação dos atributos que você deseja ver e compará-los
# com os campos na página
expect(unicorn_confirmation_page.exists?(sparkles)).to be, 'Sparkles should have been created, with all attributes intact'
  
```

```javascript
// O método exists() de UnicornConfirmationPage pegará o objeto
// Sparkles - uma especificação dos atributos que você deseja ver e compará-los
// com os campos na página
assert(unicornConfirmationPage.exists(sparkles), "Sparkles should have been created, with all attributes intact");

  
```

```kotlin
// O método exists() de UnicornConfirmationPage pegará o objeto
// Sparkles - uma especificação dos atributos que você deseja ver e compará-los
// com os campos na página
assertTrue("Sparkles should have been created, with all attributes intact", unicornConfirmationPage.exists(sparkles))
  
```

Observe que o testador ainda não fez nada além de falar sobre unicórnios neste código– sem botões, sem localizadores, sem controles do navegador. Este método de *modelagem* do aplicativo permite que você mantenha esses comandos de nível de teste no lugar e imutáveis, mesmo se Larry decidir na próxima semana que não gosta mais de Ruby-on-Rails e decidir reimplementar todo o site em Haskell com um front-end Fortran.

Seus objetos de página exigirão alguma pequena manutenção para estar conformidade com o redesenho do site, mas esses testes permanecerão os mesmos. Pegando esse design básico, você desejará continuar seus fluxos de trabalho com o menor número possível de etapas voltadas para o navegador. Seu próximo fluxo de trabalho envolverá adicionar um unicórnio ao carrinho de compras. Provavelmente, você desejará muitas iterações deste teste para ter certeza de que o carrinho está mantendo o estado adequado: Existe mais de um unicórnio no carrinho antes de você começar? Quantos cabem no carrinho de compras? Se você criar mais de um com o mesmo nome e / ou recursos, ele falhará? Manterá apenas o existente ou acrescentará outro?

Cada vez que você passa pelo fluxo de trabalho, você deseja evitar ter que criar uma conta, fazer login como o usuário e configurar o unicórnio. Idealmente, você será capaz de criar uma conta e pré-configurar um unicórnio por meio da API ou banco de dados. Em seguida, tudo que você precisa fazer é fazer login como o usuário, localizar Sparkles, e adicioná-lo ao carrinho.

### Automatizar ou não automatizar?

A automação é sempre vantajosa? Quando se deve decidir automatizar os casos de teste?

Nem sempre é vantajoso automatizar casos de teste. Tem vezes que o teste manual pode ser mais apropriado. Por exemplo, se a interface do aplicativo mudará consideravelmente em um futuro próximo, então qualquer automação pode precisar ser reescrita de qualquer maneira. Além disso, às vezes simplesmente não há tempo suficiente para construir automação de testes. A curto prazo, o teste manual pode ser mais eficaz. Se um aplicativo tem um prazo muito curto, atualmente não há automação de teste disponível, e é imperativo que o teste seja feito dentro nesse período, o teste manual é a melhor solução.

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/browsers/firefox/
----

# Firefox specific functionality

These are capabilities and features specific to Mozilla Firefox browsers.

Selenium 4 requires Firefox 78 or greater. It is recommended to always use the latest version of geckodriver.

## Options

Capabilities common to all browsers are described on the [Options page](https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/options/).

Capabilities unique to Firefox can be found at Mozilla’s page for [firefoxOptions](https://developer.mozilla.org/en-US/docs/Web/WebDriver/Capabilities/firefoxOptions)

Starting a Firefox session with basic defined options looks like this:

*
*
*
*
*
*

```java
    driver = new FirefoxDriver(options);
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L36-L37)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L10-L11)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
        public void BasicOptions()
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L34-L35)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/openFirefoxTest.spec.js#L10-L13)

##### /examples/javascript/test/getting\_started/openFirefoxTest.spec.js

```js
const {Browser, Builder} = require('selenium-webdriver');
const firefox = require('selenium-webdriver/firefox');


describe('Open Firefox', function () {
  let driver;

  before(async function () {
    let options = new firefox.Options();
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options)
      .build();
  });

  after(async () => await driver.quit());

  it('Basic Firefox test', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

Here are a few common use cases with different capabilities:

### Arguments

The `args` parameter is for a list of Command line switches used when starting the browser.\
Commonly used args include `-headless` and `"-profile", "/path/to/profile"`

Add an argument to options:

*
*
*
*
*
*

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options.add_argument("-headless")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L19)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            var options = new FirefoxOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L43)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options.args << '-headless'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L17)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
      .setFirefoxOptions(options.addArguments('--headless'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L12)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L54)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options.binary_location = firefox_bin
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L28)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            var options = new FirefoxOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L53)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options.binary = firefox_location
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L25)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### Profiles

There are several ways to work with Firefox profiles

*
*
*
*
*
*

```java
    driver = new FirefoxDriver(options);
  }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L211-L216)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L160-L168)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```csharp
var options = new FirefoxOptions();
var profile = new FirefoxProfile();
options.Profile = profile;
var driver = new RemoteWebDriver(options);
  
```

```rb
      profile = Selenium::WebDriver::Firefox::Profile.new
          profile['browser.download.dir'] = '/tmp/webdriver-downloads'
          options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L139-L141)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true
    
    require 'spec_helper'
    
    RSpec.describe 'Firefox' do
      describe 'Options' do
        let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }
    
        it 'basic options' do
          options = Selenium::WebDriver::Options.firefox
          @driver = Selenium::WebDriver.for :firefox, options: options
        end
    
        it 'add arguments' do
          options = Selenium::WebDriver::Options.firefox
    
          options.args << '-headless'
    
          @driver = Selenium::WebDriver.for :firefox, options: options
        end
    
        it 'sets location of binary' do
          options = Selenium::WebDriver::Options.firefox
    
          options.binary = firefox_location
    
          @driver = Selenium::WebDriver.for :firefox, options: options
        end
      end
    
      describe 'Service' do
        let(:file_name) { Tempfile.new('geckodriver').path }
        let(:root_directory) { Dir.mktmpdir }
    
        after do
          FileUtils.rm_f(file_name)
          FileUtils.rm_rf(root_directory)
        end
    
        it 'logs to file' do
          service = Selenium::WebDriver::Service.firefox
    
          service.log = file_name
    
          @driver = Selenium::WebDriver.for :firefox, service: service
          expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
        end
    
        it 'logs to console' do
          service = Selenium::WebDriver::Service.firefox
    
          service.log = $stdout
    
          expect {
            @driver = Selenium::WebDriver.for :firefox, service: service
          }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
        end
    
        it 'sets log level' do
          service = Selenium::WebDriver::Service.firefox
          service.log = file_name
    
          service.args += %w[--log debug]
    
          @driver = Selenium::WebDriver.for :firefox, service: service
          expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
        end
    
        it 'stops truncating log lines' do
          service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])
    
          service.args << '--log-no-truncate'
    
          @driver = Selenium::WebDriver.for :firefox, service: service
          expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
        end
    
        it 'sets default profile location' do
          service = Selenium::WebDriver::Service.firefox
    
          service.args += ['--profile-root', root_directory]
    
          @driver = Selenium::WebDriver.for :firefox, service: service
          profile_location = Dir.new(@driver.capabilities['moz:profile'])
          expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
        end
      end
    
      describe 'Features' do
        let(:driver) { start_firefox }
    
        it 'installs addon' do
          extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
    
          driver.install_addon(extension_file_path)
    
          driver.get 'https://www.selenium.dev/selenium/web/blank.html'
          injected = driver.find_element(id: 'webextensions-selenium-example')
          expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
        end
    
        it 'uninstalls addon' do
          extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
          extension_id = driver.install_addon(extension_file_path)
    
          driver.uninstall_addon(extension_id)
    
          driver.get 'https://www.selenium.dev/selenium/web/blank.html'
          expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
        end
    
        it 'installs unsigned addon' do
          extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)
    
          driver.install_addon(extension_dir_path, true)
    
          driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
          injected = driver.find_element(id: 'webextensions-selenium-example')
          expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
        end
    
        it 'takes full page screenshot' do
          driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
          Dir.mktmpdir('screenshot_test') do |dir|
            screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))
    
            expect(screenshot).to be_a File
          end
        end
    
        it 'sets the context' do
          driver.context = 'content'
          expect(driver.context).to eq 'content'
        end
      end
    
      describe 'Profile' do
        it 'creates a new profile' do
          profile = Selenium::WebDriver::Firefox::Profile.new
          profile['browser.download.dir'] = '/tmp/webdriver-downloads'
          options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
          expect(options.profile).to eq(profile)
        end
      end
    
      def driver_finder
        options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
        service = Selenium::WebDriver::Service.firefox
        finder = Selenium::WebDriver::DriverFinder.new(options, service)
        ENV['GECKODRIVER_BIN'] = finder.driver_path
        ENV['FIREFOX_BIN'] = finder.browser_path
      end
    end
    
```

```javascript
const { Builder } = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');

const options = new firefox.Options();
let profile = '/path to custom profile';
options.setProfile(profile);
const driver = new Builder()
    .forBrowser('firefox')
    .setFirefoxOptions(options)
    .build();
  
```

```kotlin
val options = FirefoxOptions()
options.profile = FirefoxProfile()
driver = RemoteWebDriver(options)
  
```

**Note**: Whether you create an empty `FirefoxProfile` or point it to the directory of your own profile, Selenium will create a temporary directory to store either the data of the new profile or a copy of your existing one. Every time you run your program, a different temporary directory will be created. These directories are not cleaned up explicitly by Selenium, they should eventually get removed by the operating system. However, if you want to remove the copy manually (e.g. if your profile is large in size), the path of the copy is exposed by the `FirefoxProfile` object. Check the language specific implementation to see how to retrieve that location.

If you want to use an existing Firefox profile, you can pass in the path to that profile. Please refer to the official [Firefox documentation](https://support.mozilla.org/en-US/kb/profiles-where-firefox-stores-user-data#w_how-do-i-find-my-profile) for instructions on how to find the directory of your profile.

## Service

Service settings common to all browsers are described on the [Service page](https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/service/).

### Log output

Getting driver logs can be helpful for debugging various issues. The Service class lets you direct where the logs will go. Logging output is ignored unless the user directs it somewhere.

#### File output

To change the logging output to save to a specific file:

*
*
*
*
*
*

```java
        new GeckoDriverService.Builder().withLogFile(logLocation).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L62-L63)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY`\
Property value: String representing path to log file

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L36)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L43)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withLogOutput(System.out).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L76-L77)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L48)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L52)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L90-L91)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY`\
Property value: String representation of `FirefoxDriverLogLevel` enum

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L59)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args += %w[--log debug]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L63)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L106-L107)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_NO_TRUNCATE`\
Property value: `"true"` or `"false"`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L70)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '--log-no-truncate'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L72)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L118-L119)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_PROFILE_ROOT`\
Property value: String representing path to profile root directory

```py
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L81)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args += ['--profile-root', root_directory]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L81)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## Special Features

### Add-ons

Unlike Chrome, Firefox extensions are not added as part of capabilities as mentioned in [this issue](https://github.com/mozilla/geckodriver/issues/1476), they are created after starting the driver.

The following examples are for local webdrivers. For remote webdrivers, please refer to the [Remote WebDriver](https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/remote_webdriver/) page.

#### Installation

A signed xpi file you would get from [Mozilla Addon page](https://addons.mozilla.org/en-US/firefox/)

*
*
*
*
*
*

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L133)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.install_addon(addon_path_xpi)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L94)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L137)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      driver.install_addon(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L95)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    let id = await driver.installAddon(xpiPath);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L25)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L148)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.uninstall_addon(id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L106)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```cs
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L152)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      driver.uninstall_addon(extension_id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L106)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    await driver.uninstallAddon(id);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L26)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L160)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.install_addon(addon_path_dir, temporary=True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L115)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```cs
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L165)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```rb
      driver.install_addon(extension_dir_path, true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L115)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    let id = await driver.installAddon(xpiPath, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L41)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

### Full page screenshots

The following examples are for local webdrivers. For remote webdrivers, please refer to the [Remote WebDriver](https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/remote_webdriver/) page.

*
*
*
*
*
*

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L181)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.save_full_page_screenshot("full_page_screenshot.png")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L139)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L125)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### Context

The following examples are for local webdrivers. For remote webdrivers, please refer to the [Remote WebDriver](https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/remote_webdriver/) page.

*
*
*
*
*
*

```java
    // Verify the context is back to "content"
    Assertions.assertEquals(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L197-L198)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L151-L152)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      driver.context = 'content'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L132)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

**Note**: As of Firefox 138, geckodriver needs to be started with the argument `--allow-system-access` to switch the context to `CHROME`.

----
url: https://www.selenium.dev/_print/documentation/legacy/selenium_2/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/legacy/selenium_2/).

# Selenium 2

Selenium 2 was a rewrite of Selenium 1 that was implemented with WebDriver code.

* 1: [Migrating from RC to WebDriver](#pg-6d6ce38fefd72ba339f1f94ce93b4b11)
* 2: [Backing Selenium with WebDriver](#pg-b70fabac091738e86524dd8793bcc0bf)
* 3: [Legacy Firefox Driver](#pg-6984c4d03154181ae791e3cd56fd311f)
* 4: [Selenium grid 2](#pg-8ed1a0dc90a43d86e2d25e92a3e7cbd8)
* 5: [History of Grid Platforms](#pg-54595ecbfa5e5d9fb842086d5fc39a0d)
* 6: [Remote WebDriver standalone server](#pg-1b088b432d4645b4106c50b880e5e299)
* 7: [Limitations of scaling up tests in Selenium 2](#pg-993524c9537baa2d57c6eaba7881014f)
* 8: [Stealing focus from Firefox in Linux](#pg-3e28db920e0f683929711b45122a4d4d)
* 9: [Untrusted SSL Certificates](#pg-f0fd86d94624603be663eacc23f25aba)
* 10: [WebDriver For Mobile Browsers](#pg-e1d327a5eb6a8ebaeaca9cdfa4dbbd7d)
* 11: [Frequently Asked Questions for Selenium 2](#pg-36437cf691a726827ecca3a5756760ad)
* 12: [Selenium 2.0 Team](#pg-b18f30320b6067c6959caae4547f4b0c)

# 1 - Migrating from RC to WebDriver

```java
Selenium selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.yoursite.com");
selenium.start();
```

This should be replaced like so:

```java
WebDriver driver = new FirefoxDriver();
Selenium selenium = new WebDriverBackedSelenium(driver, "http://www.yoursite.com");
```

## Next Steps

Once your tests execute without errors, the next stage is to migrate the actual test code to use the WebDriver APIs. Depending on how well abstracted your code is, this might be a short process or a long one. In either case, the approach is the same and can be summed up simply: modify code to use the new API when you come to edit it.

If you need to extract the underlying WebDriver implementation from the Selenium instance, you can simply cast it to WrapsDriver:

```java
WebDriver driver = ((WrapsDriver) selenium).getWrappedDriver();
```

This allows you to continue passing the Selenium instance around as normal, but to unwrap the WebDriver instance as required.

At some point, you’re codebase will mostly be using the newer APIs. At this point, you can flip the relationship, using WebDriver throughout and instantiating a Selenium instance on demand:

```java
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);
```

## Common Problems

Fortunately, you’re not the first person to go through this migration, so here are some common problems that others have seen, and how to solve them.

### Clicking and Typing is More Complete

A common pattern in a Selenium RC test is to see something like:

```java
selenium.type("name", "exciting tex");
selenium.keyDown("name", "t");
selenium.keyPress("name", "t");
selenium.keyUp("name", "t");
```

```java
Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(30));
WebElement element= wait.until(visibilityOfElementLocated(By.id("some_id")));
```

Where “visibilityOfElementLocated” is implemented as:

```java
public ExpectedCondition<WebElement> visibilityOfElementLocated(final By locator) {
  return new ExpectedCondition<WebElement>() {
    public WebElement apply(WebDriver driver) {
      WebElement toReturn = driver.findElement(locator);
      if (toReturn.isDisplayed()) {
        return toReturn;
      }
      return null;
    }
  };
}
```

This may look complex, but it’s almost all boiler-plate code. The only interesting bit is that the “ExpectedCondition” will be evaluated repeatedly until the “apply” method returns something that is neither “null” nor Boolean.FALSE.

Of course, adding all these “wait” calls may clutter up your code. If that’s the case, and your needs are simple, consider using the implicit waits:

```java
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
```

```java
String name = selenium.getEval(
    "selenium.browserbot.findElement('id=foo', browserbot.getCurrentWindow()).tagName");
```

becomes:

```java
WebElement element = driver.findElement(By.id("foo"));
String name = (String) ((JavascriptExecutor) driver).executeScript(
    "return arguments[0].tagName", element);
```

Notice how the passed in “element” variable appears as the first item in the JS standard “arguments” array.

### Executing Javascript Doesn’t Return Anything

WebDriver’s JavascriptExecutor will wrap all JS and evaluate it as an anonymous expression. This means that you need to use the “return” keyword:

```java
String title = selenium.getEval("browserbot.getCurrentWindow().document.title");
```

becomes:

```java
((JavascriptExecutor) driver).executeScript("return document.title;");
```

# 2 - Backing Selenium with WebDriver

The Java and .NET versions of Selenium 2 provided implementations of the original Selenium API

(Previously located: <https://github.com/SeleniumHQ/selenium/wiki/Selenium-Emulation>)

## Backing Selenium with WebDriver

The Java and .NET versions of WebDriver provide implementations of the existing Selenium API. In Java, it is used like so:

```
// You may use any WebDriver implementation. Firefox is used here as an example
WebDriver driver = new FirefoxDriver();

// A "base url", used by selenium to resolve relative URLs
String baseUrl = "http://www.google.com";

// Create the Selenium implementation
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);

// Perform actions with selenium
selenium.open("http://www.google.com");
selenium.type("name=q", "cheese");
selenium.click("name=btnG");

// And get the underlying WebDriver implementation back. This will refer to the
// same WebDriver instance as the "driver" variable above.
WebDriver driverInstance = ((WebDriverBackedSelenium) selenium).getUnderlyingWebDriver();
```

```
driver = RemoteWebDriver(desired_capabilities = DesiredCapabilities.FIREFOX)
selenium = DefaultSelenium('localhost', '4444', '*webdriver', 'http://www.google.com')
selenium.start(driver = driver)
```

Provided you keep a reference to the original WebDriver and Selenium objects you created, you can use even the two APIs interchangeably. The magic is the “`*webdriver`” browser name passed to the Selenium instance, and that you pass the WebDriver instance when calling `start()`.

In languages where DefaultSelenium doesn’t have `start(driver)`, you can connect the WebDriver and Selenium objects together yourself, by supplying the WebDriver session ID to the Selenium object.

For example, in C#:

```

RemoteWebDriver driver = new RemoteWebDriver(DesiredCapabilities.Firefox());
string sessionId = (string) driver.Capabilities.GetCapability("webdriver.remote.sessionid");
DefaultSelenium selenium = new DefaultSelenium("localhost", 4444, "*webdriver", "http://www.google.com");
selenium.Start("webdriver.remote.sessionid=" + sessionId);
```

## Backing WebDriver with Selenium

WebDriver doesn’t support as many browsers as Selenium does, so in order to provide that support while still using the webdriver API, you can make use of the `SeleneseCommandExecutor` It is done like this:

```
Capabilities capabilities = new DesiredCapabilities()
capabilities.setBrowserName("safari");
CommandExecutor executor = new SeleneseCommandExecutor("http:localhost:4444/", "http://www.google.com/", capabilities);
WebDriver driver = new RemoteWebDriver(executor, capabilities);
```

There are currently some major limitations with this approach, notably that `findElements` doesn’t work as expected. Also, because we’re using Selenium Core for the heavy lifting of driving the browser, you are limited by the Javascript sandbox.

# 3 - Legacy Firefox Driver

| **Property**                  | **What it means**                                                                                                                                                                 |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| webdriver.firefox.bin         | The location of the binary used to control firefox.                                                                                                                               |
| webdriver.firefox.marionette  | Boolean value, if set on standalone-server will ignore any “marionette” desired capability requested and force firefox to use GeckoDriver (true) or Legacy Firefox Driver (false) |
| webdriver.firefox.profile     | The name of the profile to use when starting firefox. This defaults to webdriver creating an anonymous profile                                                                    |
| webdriver.firefox.useExisting | **Never use in production** Use a running instance of firefox if one is present                                                                                                   |
| webdriver.firefox.logfile     | Log file to dump firefox stdout/stderr to                                                                                                                                         |

Normally the Firefox binary is assumed to be in the default location for your particular operating system:

| **OS**  | **Expected Location of Firefox**                     |
| ------- | ---------------------------------------------------- |
| Linux   | firefox (found using “which”)                        |
| Mac     | /Applications/Firefox.app/Contents/MacOS/firefox-bin |
| Windows | %PROGRAMFILES%\Mozilla Firefox\firefox.exe           |

By default, the Firefox driver creates an anonymous profile

### Running with firebug

Download the firebug xpi file from mozilla and start the profile as follows:

```
   File file = new File("firebug-1.8.1.xpi");
   FirefoxProfile firefoxProfile = new FirefoxProfile();
   firefoxProfile.addExtension(file);
   firefoxProfile.setPreference("extensions.firebug.currentVersion", "1.8.1"); // Avoid startup screen

   WebDriver driver = new FirefoxDriver(firefoxProfile);
```

# 4 - Selenium grid 2

> This example will show you how to start the Selenium 2 Hub, and register both a WebDriver node and a Selenium 1 RC legacy node. We’ll also show you how to call the grid from Java. The hub and nodes are shown here running on the same machine, but of course you can copy the selenium-server-standalone to multiple machines. Note: The selenium-server-standalone package includes the Hub, WebDriver, and legacy RC needed to run the grid. Ant is not required anymore. You can download the selenium-server-standalone-`*`.jar from <http://selenium-release.storage.googleapis.com/index.html> This walk-through assumes you already have Java installed.

**Step 1: Start the hub**

The Hub is the central point that will receive all the test request and distribute them the the right nodes.

Open a command prompt and navigate to the directory where you copied the selenium-server-standalone file. Type the following command:

```
java -jar selenium-server-standalone-<version>.jar -role hub
```

The hub will automatically start-up using port 4444 by default. To change the default port, you can add the optional parameter -port when you run the command. You can view the status of the hub by opening a browser window and navigating to: http\://localhost:4444/grid/console

**Step 2: Start the nodes**

Regardless on whether you want to run a grid with new WebDriver functionality, or a grid with Selenium 1 RC functionality, or both at the same time, you use the same selenium-server-standalone jar file to start the nodes.

```
java -jar selenium-server-standalone-<version>.jar -role node  -hub http://localhost:4444/grid/register
```

Note: The port defaults to 5555 if not specified whenever the “-role” option is provided and is not hub.

For backwards compatibility “wd” and “rc” roles are still a valid subset of the “node” role. But those roles limit the types of remote connections to their corresponding API, while “node” allows both RC and WebDriver remote connections.

### Using grid to run tests

( using java as an example ) Now that the grid is in-place, we need to access the grid from our test cases. For the Selenium 1 RC nodes, you can continue to use the DefaultSelenium object and pass in the hub information:

```
Selenium selenium = new DefaultSelenium(“localhost”, 4444, “*firefox”, “http://www.google.com”);
```

For WebDriver nodes, you will need to use the **RemoteWebDriver** and the **DesiredCapabilities** object to define which browser, version and platform you wish to use. Create the target browser capabilities you want to run the tests against:

```
DesiredCapabilities capability = DesiredCapabilities.firefox();
```

Pass that into the RemoteWebDriver object:

```
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
```

The hub will then assign the test to a matching node.

A node matches if all the requested capabilities are met. To request specific capabilities on the grid, specify them before passing it into the WebDriver object.

```
capability.setBrowserName();
capability.setPlatform();
capability.setVersion()
capability.setCapability(,);
```

Example: A node registered with the setting:

```
 -browser  browserName=firefox,version=3.6,platform=LINUX
```

> will be a match for:

```
capability.setBrowserName(“firefox” ); 
capability.setPlatform(“LINUX”);  
capability.setVersion(“3.6”);
```

and would also be a match for

```
capability.setBrowserName(“firefox” ); 
capability.setVersion(“3.6”);
```

The capabilities that are not specified will be ignored. If you specify capabilities that do not exist on your grid (for example, your test specifies Firefox version 4.0, but have no Firefox 4 instance) then there will be no match and the test will fail to run.

## Configuring the nodes

The node can be configured in 2 different ways; one is by specifying command-line parameters, the other is by specifying a JSON file.

### Configuring the nodes by command line

By default, starting the node allows for concurrent use of 11 browsers…: 5 Firefox, 5 Chrome, 1 Internet Explorer. The maximum number of concurrent tests is set to 5 by default. To change this and other browser settings, you can pass in parameters to each -browser switch (each switch represents a node based on your parameters). If you use the -browser parameter, the default browsers will be ignored and only what you specify command line will be used.

```
-browser browserName=firefox,version=3.6,maxInstances=5,platform=LINUX
```

This setting starts 5 Firefox 3.6 nodes on a Linux machine.

If your remote machine has multiple versions of Firefox you’d like to use, you can map the location of each binary to a particular version on the same machine:

```
-browser browserName=firefox,version=3.6,firefox_binary=/home/myhomedir/firefox36/firefox,maxInstances=3,platform=LINUX -browser browserName=firefox,version=4,firefox_binary=/home/myhomedir/firefox4/firefox,maxInstances=4,platform=LINUX
```

Tip: If you need to provide a space somewhere in your browser parameters, then surround the parameters with quotation marks:

```
-browser “browserName=firefox,version=3.6,firefox_binary=c:\Program Files\firefox ,maxInstances=3, platform=WINDOWS”
```

### Optional parameters

* `-port 4444` (4444 is default)
* `-host <IP | hostname>` specify the hostname or IP. usually not needed and determined automatically. For exotic network configuration, network with VPN, specifying the host might be necessary.
* `-timeout 30` (300 is default) The timeout in seconds before the hub automatically releases a node that hasn’t received any requests for more than the specified number of seconds. After this time, the node will be released for another test in the queue. This helps to clear client crashes without manual intervention. To remove the timeout completely, specify -timeout 0 and the hub will never release the node.

> Note: This is NOT the WebDriver timeout for all ”wait for WebElement” type of commands.

> java -jar selenium-server-standalone.jar -role node -nodeConfig nodeconfig.json

A sample nodeconfig file for server version 3.x.x (>= beta4) can be seen at <https://github.com/SeleniumHQ/selenium/blob/selenium-3.141.59/java/server/src/org/openqa/grid/common/defaults/DefaultNodeWebDriver.json>

A sample nodeconfig file for server version 2.x.x can be seen at <https://github.com/SeleniumHQ/selenium/blob/selenium-2.53.0/java/server/src/org/openqa/grid/common/defaults/DefaultNode.json>

Note: the `configuration { ... }` object in version 2.x.x has been flattened in version 3.x.x (>= beta4)

### Configuring the hub by JSON

> java -jar selenium-server-standalone.jar -role hub -hubConfig hubconfig.json

A sample hubconfig.json file can be seen at <https://github.com/SeleniumHQ/selenium/blob/selenium-3.141.59/java/server/src/org/openqa/grid/common/defaults/DefaultHub.json>

## Hub diagnostic messages

Upon detecting anomalous usage patterns, the hub can give the following message:

```
Client requested session XYZ that was terminated due to REASON
```

| **Reason**                   | **Cause/fix**                                                                                                                                                                   |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| TIMEOUT                      | The session timed out because the client did not access it within the timeout. If the client has been somehow suspended, this may happen when it wakes up                       |
| BROWSER\_TIMEOUT             | The node timed out the browser because it was hanging for too long (parameter browserTimeout)                                                                                   |
| ORPHAN                       | A client waiting in queue has given up once it was offered a new session                                                                                                        |
| CLIENT\_STOPPED\_SESSION     | The session was stopped using an ordinary call to stop/quit on the client. Why are you using it again??                                                                         |
| CLIENT\_GONE                 | The client process (*your* code) appears to have died or otherwise not responded to our requests, intermittent network issues may also cause                                    |
| FORWARDING\_TO\_NODE\_FAILED | The hub was unable to forward to the node. Out of memory errors/node stability issues or network problems                                                                       |
| CREATIONFAILED               | The node failed to create the browser. This can typically happen when there are environmental/configuration problems on the node. Try using the node directly to track problem. |
| PROXY\_REREGISTRATION        | The session has been discarded because the node has re-registered on the grid (in mid-test)                                                                                     |

```
	[[DesiredCapabilities]] capability = DesiredCapabilities.internetExplorer();
	capability.setVersion("8");
	capability.setPlatform(Platform.XP);
	WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
```

The request for a new session with specified DesiredCapability is sent to the Grid Hub, which will look through all of the registered nodes to see if any of them match the specification given by the test. If no node matches the specification, a CapabilityNotPresentOnTheGridException will be returned.

It is a common misconception that the PLATFORM determines the ability to choose the Operating System on which the new session will be created. In this situation, platform and operating system are not the same, thus specifying the platform to “Windows 2003 Server” will not allow you to choose between a Windows XP, Vista, and 2003 server. This misconception can be born from platforms such as Mac OSX and Linux, where the name of the platform matches the name of the Operating System.

In case of Selenium Grid, platform refers to the underlying interactions between the Driver Atoms and the web browser. Mac OSX and Linux based Operating Systems (Centos, Ubuntu, Debian, etc..) have a relatively stable communication with the web browsers such as Firefox and Chrome. Thus the platform names are simple to understand, as seen in the example bellow:

```
   capability.setPlatform(Platform.MAC);   //Set platform to OSX
   capability.setPlatform(Platform.LINUX); // Set platform to Linux based systems
```

The prior to release of Vista, Windows based Operating Systems only had one platform, shown here:

```
	capability.setPlatform(Platform.WINDOWS); //Set platform to Windows
```

However, with the introduction of UAC in Windows Vista, there were major changes done to the underlying interactions between WebDriver and Internet Explorer. To work around the UAC constrains a new platform was added to nodes with Windows based Operating systems:

```
	capability.setPlatform(Platform.VISTA); //Set platform to VISTA
```

With the release of Windows 8, another major overhaul happened in how the WebDriver communicates with Internet Explorer, thus a new platform was added for Windows 8 based nodes:

```
	capability.setPlatform(Platform.WIN8); //Set platform to Windows 8
```

Similar story happened with introduction of Windows 8.1, in this example the platform is set to Windows 8.1:

```
	capability.setPlatform(Platform.WIN8_1); //Set platform to Windows 8.1
```

```
  	capability.setPlatform(Platform.VISTA); //Will return a node with Windows Vista or 2008 Server or Windows 7 Operating System.
  	capability.setPlatform(Platform.XP);   //Will return a node with Windows XP or 2003 Server or Windows 2000 Professional Operating System.   
  	capability.setPlatform(Platform.WINDOWS); //Will return a node with ANY Windows Operating System
```

### More Information

For more information on the latest platforms, please view this file:

org.openqa.selenium.Platform.java

# 5 - History of Grid Platforms

```
	[[DesiredCapabilities]] capability = DesiredCapabilities.internetExplorer();
	capability.setVersion("8");
	capability.setPlatform(Platform.XP);
	WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
```

The request for a new session with specified DesiredCapability is sent to the Grid Hub, which will look through all of the registered nodes to see if any of them match the specification given by the test. If no node matches the specification, a CapabilityNotPresentOnTheGridException will be returned.

It is a common misconception that the PLATFORM determines the ability to choose the Operating System on which the new session will be created. In this situation, platform and operating system are not the same, thus specifying the platform to “Windows 2003 Server” will not allow you to choose between a Windows XP, Vista, and 2003 server. This misconception can be born from platforms such as Mac OSX and Linux, where the name of the platform matches the name of the Operating System.

In case of Selenium Grid, platform refers to the underlying interactions between the Driver Atoms and the web browser. Mac OSX and Linux based Operating Systems (Centos, Ubuntu, Debian, etc..) have a relatively stable communication with the web browsers such as Firefox and Chrome. Thus the platform names are simple to understand, as seen in the example bellow:

```
   capability.setPlatform(Platform.MAC);   //Set platform to OSX
   capability.setPlatform(Platform.LINUX); // Set platform to Linux based systems
```

The prior to release of Vista, Windows based Operating Systems only had one platform, shown here:

```
	capability.setPlatform(Platform.WINDOWS); //Set platform to Windows
```

However, with the introduction of UAC in Windows Vista, there were major changes done to the underlying interactions between WebDriver and Internet Explorer. To work around the UAC constrains a new platform was added to nodes with Windows based Operating systems:

```
	capability.setPlatform(Platform.VISTA); //Set platform to VISTA
```

With the release of Windows 8, another major overhaul happened in how the WebDriver communicates with Internet Explorer, thus a new platform was added for Windows 8 based nodes:

```
	capability.setPlatform(Platform.WIN8); //Set platform to Windows 8
```

Similar story happened with introduction of Windows 8.1, in this example the platform is set to Windows 8.1:

```
	capability.setPlatform(Platform.WIN8_1); //Set platform to Windows 8.1
```

```
  	capability.setPlatform(Platform.VISTA); //Will return a node with Windows Vista or 2008 Server or Windows 7 Operating System.
  	capability.setPlatform(Platform.XP);   //Will return a node with Windows XP or 2003 Server or Windows 2000 Professional Operating System.   
  	capability.setPlatform(Platform.WINDOWS); //Will return a node with ANY Windows Operating System
```

### More Information

For more information on the latest platforms, please view this file:

org.openqa.selenium.Platform.java

# 6 - Remote WebDriver standalone server

Working with the Standalone Server.

This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/RemoteWebDriverServer)

The server will always run on the machine with the browser you want to test. The server can be used either from the command line or through code configuration.

## Starting the server from the command line

Once you have downloaded `selenium-server-standalone-{VERSION}.jar`, place it on the computer with the browser you want to test. Then, from the directory with the jar, run the following:

```shell
java -jar selenium-server-standalone-{VERSION}.jar
```

## Considerations for running the server

The caller is expected to terminate each session properly, calling either `Selenium#stop()` or `WebDriver#quit`.

The selenium-server keeps in-memory logs for each ongoing session, which are cleared when `Selenium#stop()` or `WebDriver#quit` is called. If you forget to terminate these sessions, your server may leak memory. If you keep extremely long-running sessions, you will probably need to stop/quit every now and then (or increase memory with -Xmx jvm option).

## Timeouts (from version 2.21)

The server has two different timeouts, which can be set as follows:

```shell
java -jar selenium-server-standalone-{VERSION}.jar -timeout=20 -browserTimeout=60
```

```java
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.security.SslSocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;

import javax.servlet.Servlet;
import java.io.File;

import org.openqa.selenium.remote.server.DriverServlet;

public class AppServer {
  private Server server = new Server();

  public AppServer() throws Exception {
    WebAppContext context = new WebAppContext();
    context.setContextPath("");
    context.setWar(new File("."));
    server.addHandler(context);

    context.addServlet(DriverServlet.class, "/wd/*");

    SelectChannelConnector connector = new SelectChannelConnector();
    connector.setPort(3001);
    server.addConnector(connector);

    server.start();
  }
}
```

# 7 - Limitations of scaling up tests in Selenium 2

# 8 - Stealing focus from Firefox in Linux

# 9 - Untrusted SSL Certificates

```
WdCertOverrideService.prototype.hasMatchingOverride = function(
    aHostName, aPort, aCert, aOverrideBits, aIsTemporary)
```

The aOverrideBits and aIsTemporary are output arguments. This is where things get a bit tricky: There are three possible override bits:

```
  ERROR_UNTRUSTED: 1,
  ERROR_MISMATCH: 2,
  ERROR_TIME: 4
```

It’s impossible to just set them all, since Firefox expects a perfect match between the offences generated by the certificate and the function’s return value: (security/manager/ssl/src/SSLServerCertVerification.cpp:302):

```
  if (overrideService)
  {
    PRBool haveOverride;
    PRBool isTemporaryOverride; // we don't care
  
    nsrv = overrideService->HasMatchingOverride(hostString, port,
                                                ix509, 
                                                &overrideBits,
                                                &isTemporaryOverride, 
                                                &haveOverride);
    if (NS_SUCCEEDED(nsrv) && haveOverride) 
    {
      // remove the errors that are already overriden
      remaining_display_errors -= overrideBits;
    }
  }

  if (!remaining_display_errors) {
    // all errors are covered by override rules, so let's accept the cert
    return SECSuccess;
  }
```

The exact mapping of violation to error code can be easily seen at security/manager/pki/resources/content/exceptionDialog.js (in Firefox source):

```
  var flags = 0;
  if(gSSLStatus.isUntrusted)
    flags |= overrideService.ERROR_UNTRUSTED;
  if(gSSLStatus.isDomainMismatch)
    flags |= overrideService.ERROR_MISMATCH;
  if(gSSLStatus.isNotValidAtThisTime)
    flags |= overrideService.ERROR_TIME;
```

# 10 - WebDriver For Mobile Browsers

# 11 - Frequently Asked Questions for Selenium 2

```
WebDriver driver; // Assigned elsewhere
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("return document.title");
```

Other language bindings will follow a similar approach. Take a look at the UsingJavascript page for more information.

### Q: Why is my Javascript execution always returning null?

A: You need to return from your javascript snippet to return a value, so:

```
js.executeScript("document.title");
```

will return null, but:

```
js.executeScript("return document.title");
```

will return the title of the document.

### Q: My XPath finds elements in one browser, but not in others. Why is this?

A: The short answer is that each supported browser handles XPath slightly differently, and you’re probably running into one of these differences. The long answer is on the XpathInWebDriver page.

### Q: The InternetExplorerDriver does not work well on Vista. How do I get it to work as expected?

A: The InternetExplorerDriver requires that all security domains are set to the same value (either trusted or untrusted) If you’re not in a position to modify the security domains, then you can override the check like this:

```
DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer();
capabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
WebDriver driver = new InternetExplorerDriver(capabilities);
```

```
// Get a handle to the open alert, prompt or confirmation
Alert alert = driver.switchTo().alert();
// Get the text of the alert or prompt
alert.getText();  
// And acknowledge the alert (equivalent to clicking "OK")
alert.accept();
```

### Q: Does WebDriver support file uploads?

A: Yes.

You can’t interact with the native OS file browser dialog directly, but we do some magic so that if you call WebElement#sendKeys("/path/to/file") on a file upload element, it does the right thing. Make sure you don’t WebElement#click() the file upload element, or the browser will probably hang.

Handy hint: You can’t interact with hidden elements without making them un-hidden. If your element is hidden, it can probably be un-hidden with some code like:

```
((JavascriptExecutor)driver).executeScript("arguments[0].style.visibility = 'visible'; arguments[0].style.height = '1px'; arguments[0].style.width = '1px'; arguments[0].style.opacity = 1", fileUploadElement);
```

### Q: The “onchange” event doesn’t fire after a call “sendKeys”

A: WebDriver leaves the focus in the element you called “sendKeys” on. The “onchange” event will only fire when focus leaves that element. As such, you need to move the focus, perhaps using a “click” on another element.

### Q: Can I run multiple instances of the WebDriver sub-classes?

A: Each instance of an HtmlUnitDriver, ChromeDriver and FirefoxDriver is completely independent of every other instance (in the case of firefox and chrome, each instance has its own anonymous profile it uses). Because of the way that Windows works, there should only ever be a single InternetExplorerDriver instance at one time. If you need to run more than one instance of the InternetExplorerDriver at a time, consider using the Remote!WebDriver and virtual machines.

### Q: I need to use a proxy. How do I configure that?

A: Proxy configuration is done via the `org.openqa.selenium.Proxy` class like so:

```
Proxy proxy = new Proxy();
proxy.setProxyAutoconfigUrl("http://youdomain/config");

// We use firefox as an example here.
DesiredCapabilities capabilities = DesiredCapabilities.firefox();
capabilities.setCapability(CapabilityType.PROXY, proxy);

// You could use any webdriver implementation here
WebDriver driver = new FirefoxDriver(capabilities);
```

### Q: How do I handle authentication with the HtmlUnitDriver?

A: When creating your instance of the HtmlUnitDriver, override the “modifyWebClient” method, for example:

```
WebDriver driver = new HtmlUnitDriver() {
  protected WebClient modifyWebClient(WebClient client) {
    // This class ships with HtmlUnit itself
    DefaultCredentialsProvider creds = new DefaultCredentialsProvider();

    // Set some example credentials
    creds.addCredentials("username", "password");

    // And now add the provider to the webClient instance
    client.setCredentialsProvider(creds);

    return client;
  }
};
```

### Q: Is WebDriver thread-safe?

A: WebDriver is not thread-safe. Having said that, if you can serialise access to the underlying driver instance, you can share a reference in more than one thread. This is not advisable. You /can/ on the other hand instantiate one WebDriver instance for each thread.

### Q: How do I type into a contentEditable iframe?

A: Assuming that the iframe is named “foo”:

```
driver.switchTo().frame("foo");
WebElement editable = driver.switchTo().activeElement();
editable.sendKeys("Your text here");
```

Sometimes this doesn’t work, and this is because the iframe doesn’t have any content. On Firefox you can execute the following before “sendKeys”:

```
((JavascriptExecutor) driver).executeScript("document.body.innerHTML = '<br>'");
```

This is needed because the iframe has no content by default: there’s nothing to send keyboard input to. This method call inserts an empty tag, which sets everything up nicely.

Remember to switch out of the frame once you’re done (as all further interactions will be with this specific frame):

```
driver.switchTo().defaultContent();
```

### Q: WebDriver fails to start Firefox on Linux due to java.net.SocketException

A: If, when running WebDriver on Linux, Firefox fails to start and the error looks like:

```
Caused by: java.net.SocketException: Invalid argument
        at java.net.PlainSocketImpl.socketBind(Native Method)
        at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:365)
        at java.net.Socket.bind(Socket.java:571)
        at org.openqa.selenium.firefox.internal.SocketLock.isLockFree(SocketLock.java:99)
        at org.openqa.selenium.firefox.internal.SocketLock.lock(SocketLock.java:63)
```

It may be caused due to IPv6 settings on the machine. Execute:

```
sudo sysctl net.ipv6.bindv6only=0
```

```
WebElement element = ...;
((JavascriptExecutor) driver).executeScript("return arguments[0].getText();", element);
```

### Q: How do I start Firefox with an extension installed?

A:

```
FirefoxProfile profile = new FirefoxProfile()
profile.addExtension(....);

WebDriver driver = new FirefoxDriver(profile);
```

```
driver.findElement(By.tagName("body")).getText()
```

# 12 - Selenium 2.0 Team

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/actions_api/pen/
----

# Ações de Caneta

```java
        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/PenTest.java#L26-L33)

##### /examples/java/src/test/java/dev/selenium/actions\_api/PenTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PenTest extends BaseChromeTest {
    @Test
    public void usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();

        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    @Test
    public void setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();
        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("-72", moveBy.get("tiltX"));
        Assertions.assertEquals("9", moveBy.get("tiltY"));
        Assertions.assertEquals("86", moveBy.get("twist"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    private Map<String, String> getPropertyInfo(WebElement element) {
        String text = element.getText();
        text = text.substring(text.indexOf(' ') + 1);

        return Arrays.stream(text.split(", "))
                .map(s -> s.split(": "))
                .collect(Collectors.toMap(
                        a -> a[0],
                        a -> a[1]
                ));
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_pen.py#L12-L20)

##### /examples/python/tests/actions\_api/test\_pen.py

```py
import math

from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.interaction import POINTER_PEN
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.by import By


def test_use_pen(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def test_set_pointer_event_properties(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert move_by["tiltX"] == "-72"
    assert move_by["tiltY"] == "9"
    assert move_by["twist"] == "86"
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def properties(element):
    kv = element.text.split(' ', 1)[1].split(', ')
    return {x[0]:x[1] for x in list(map(lambda item: item.split(': '), kv))}
```

```cs
            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs#L19-L28)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class PenTest : BaseChromeTest
    {
        [TestMethod]
        public void UsePen()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        [TestMethod]
        public void SetPointerEventProperties()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual((-72).ToString(), moveBy["tiltX"]);
            Assert.AreEqual((9).ToString(), moveBy["tiltY"]);
            Assert.AreEqual((86).ToString(), moveBy["twist"]);
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        private Dictionary<string, string> getProperties(IWebElement element)
        {
            var str = element.Text;
            str = str[(str.Split()[0].Length + 1)..];
            IEnumerable<string[]> keyValue = str.Split(", ").Select(part => part.Split(":"));
            return keyValue.ToDictionary(split => split[0].Trim(), split => split[1].Trim());
        }

        private bool VerifyEquivalent(decimal expected, string actual)
        {
            var absolute = Math.Abs(expected - decimal.Parse(actual));
            if (absolute <= 1)
            {
                return true;
            }

            throw new Exception("Expected: " + expected + "; but received: " + actual);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/pen_spec.rb#L11-L17)

##### /examples/ruby/spec/actions\_api/pen\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Pen' do
  let(:driver) { start_session }

  it 'uses a pen' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  it 'sets pointer event attributes' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s,
                               'tiltX' => -72.to_s,
                               'tiltY' => 9.to_s,
                               'twist' => 86.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  def properties(element)
    element.text.sub(/.*?\s/, '').split(',').to_h { |item| item.lstrip.split(/\s*:\s*/) }
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/PenTest.kt#L23-L30)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/PenTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import kotlin.collections.Map
import java.time.Duration

class PenTest : BaseTest() {
  
    @Test
    fun usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
    }

    @Test
    fun setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY")) 
	    
        Assertions.assertEquals("-72", moveBy.get("tiltX"))
        Assertions.assertEquals("9", moveBy.get("tiltY"))
        Assertions.assertEquals("86", moveBy.get("twist"))
    }
    
    fun getPropertyInfo(element: WebElement): Map<String, String> {
        var text = element.getText()  
        text = text.substring(text.indexOf(" ")+1)
        return text.split(", ")
        .map { it.split(": ") }
        .map { it.first() to it.last() }
        .toMap() 
    }
}
```

```java
        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/PenTest.java#L67-L81)

##### /examples/java/src/test/java/dev/selenium/actions\_api/PenTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PenTest extends BaseChromeTest {
    @Test
    public void usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();

        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    @Test
    public void setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();
        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("-72", moveBy.get("tiltX"));
        Assertions.assertEquals("9", moveBy.get("tiltY"));
        Assertions.assertEquals("86", moveBy.get("twist"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    private Map<String, String> getPropertyInfo(WebElement element) {
        String text = element.getText();
        text = text.substring(text.indexOf(' ') + 1);

        return Arrays.stream(text.split(", "))
                .map(s -> s.split(": "))
                .collect(Collectors.toMap(
                        a -> a[0],
                        a -> a[1]
                ));
    }
}
```

```py
    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_pen.py#L53-L61)

##### /examples/python/tests/actions\_api/test\_pen.py

```py
import math

from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.interaction import POINTER_PEN
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.by import By


def test_use_pen(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def test_set_pointer_event_properties(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert move_by["tiltX"] == "-72"
    assert move_by["tiltY"] == "9"
    assert move_by["twist"] == "86"
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def properties(element):
    kv = element.text.split(' ', 1)[1].split(', ')
    return {x[0]:x[1] for x in list(map(lambda item: item.split(': '), kv))}
```

```cs
            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs#L64-L77)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class PenTest : BaseChromeTest
    {
        [TestMethod]
        public void UsePen()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        [TestMethod]
        public void SetPointerEventProperties()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual((-72).ToString(), moveBy["tiltX"]);
            Assert.AreEqual((9).ToString(), moveBy["tiltY"]);
            Assert.AreEqual((86).ToString(), moveBy["twist"]);
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        private Dictionary<string, string> getProperties(IWebElement element)
        {
            var str = element.Text;
            str = str[(str.Split()[0].Length + 1)..];
            IEnumerable<string[]> keyValue = str.Split(", ").Select(part => part.Split(":"));
            return keyValue.ToDictionary(split => split[0].Trim(), split => split[1].Trim());
        }

        private bool VerifyEquivalent(decimal expected, string actual)
        {
            var absolute = Math.Abs(expected - decimal.Parse(actual));
            if (absolute <= 1)
            {
                return true;
            }

            throw new Exception("Expected: " + expected + "; but received: " + actual);
        }
    }
}
```

```rb
    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/pen_spec.rb#L50-L56)

##### /examples/ruby/spec/actions\_api/pen\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Pen' do
  let(:driver) { start_session }

  it 'uses a pen' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  it 'sets pointer event attributes' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s,
                               'tiltX' => -72.to_s,
                               'tiltY' => 9.to_s,
                               'twist' => 86.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  def properties(element)
    element.text.sub(/.*?\s/, '').split(',').to_h { |item| item.lstrip.split(/\s*:\s*/) }
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/PenTest.kt#L64-L78)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/PenTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import kotlin.collections.Map
import java.time.Duration

class PenTest : BaseTest() {
  
    @Test
    fun usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
    }

    @Test
    fun setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY")) 
	    
        Assertions.assertEquals("-72", moveBy.get("tiltX"))
        Assertions.assertEquals("9", moveBy.get("tiltY"))
        Assertions.assertEquals("86", moveBy.get("twist"))
    }
    
    fun getPropertyInfo(element: WebElement): Map<String, String> {
        var text = element.getText()  
        text = text.substring(text.indexOf(" ")+1)
        return text.split(", ")
        .map { it.split(": ") }
        .map { it.first() to it.last() }
        .toMap() 
    }
}
```

----
url: https://www.selenium.dev/zh-cn/documentation/grid/configuration/help/
----

# 配置帮助

```shell
java -jar selenium-server-<version>.jar info config
```

### 安全

获取构建网格服务器的详细信息, 用于安全通信和节点注册.

```shell
java -jar selenium-server-<version>.jar info security
```

### 会话表配置

默认情况下, 网格使用本地会话表来存储会话信息. 网格支持额外的存储选项, 比如Redis和JDBC-SQL支持的数据库. 要设置不同的会话存储, 请使用以下命令获取设置步骤:

```shell
java -jar selenium-server-<version>.jar info sessionmap
```

### 基于OpenTelemetry和Jaeger的追踪配置

默认情况下, 追踪是启用的. 要通过Jaeger导出追踪并将其可视化, 请使用以下命令进行说明:

```shell
java -jar selenium-server-<version>.jar info tracing
```

## 列出Selenium网格的命令

```shell
java -jar selenium-server-<version>.jar --config-help
```

上述命令将显示所有可用的命令及其描述.

## 组件帮助命令

在Selenium后面键入–help的配置选项, 以获取特定组件的配置信息.

### Standalone

```shell
java -jar selenium-server-<version>.jar standalone --help
```

### Hub

```shell
java -jar selenium-server-<version>.jar hub --help
```

### Sessions

```shell
java -jar selenium-server-<version>.jar sessions --help
```

### 队列器

```shell
java -jar selenium-server-<version>.jar sessionqueue --help
```

### Distributor

```shell
java -jar selenium-server-<version>.jar distributor --help
```

### Router

```shell
java -jar selenium-server-<version>.jar router --help
```

### Node

```shell
java -jar selenium-server-<version>.jar node --help
```

----
url: https://www.selenium.dev/ja/documentation/selenium_manager/
----

```
edge can only be installed in Windows with administrator permissions
```

Therefore, administrator permissions are required to install Edge in Windows automatically through Selenium Manager, and Edge is eventually installed in the usual program files folder (e.g., `C:\Program Files (x86)\Microsoft\Edge`).

## Data collection

Selenium Manager will report anonymised usage [statistics](https://plausible.io/privacy-focused-web-analytics) to [Plausible](https://plausible.io/manager.selenium.dev). This allows the Selenium team to understand more about how Selenium is being used so that we can better focus our development efforts. The data being collected is:

| Data                                               | Purpose                                                                                                                                      |
| -------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
| Selenium version                                   | This allows the Selenium developers to safely deprecate and remove features, as well as determine which new features may be available to you |
| Language binding                                   | Programming language used to execute Selenium scripts (Java, JavaScript, Python, .Net, Ruby)                                                 |
| OS and architecture Selenium Manager is running on | The Selenium developers can use this information to help prioritise bug reports, and to identify if there are systemic OS-related issues     |
| Browser and browser version                        | Helping for prioritising bug reports                                                                                                         |
| Rough geolocation                                  | Derived from the IP address you connect from. This is useful for determining where we need to focus our documentation efforts                |

Selenium Manager sends these data to Plausible once a day. This period is based on the TTL value (see [configuration](https://www.selenium.dev/documentation/selenium_manager/#configuration)).

### Opting out of data collection

**Data collection is on by default.** To disable it, set the `SE_AVOID_STATS` environment variable to `true`. You may also disable data collection in the configuration file (see below) by setting `avoid-stats = true`.

## Configuration

***TL;DR:*** *Selenium Manager should work silently and transparently for most users. Nevertheless, there are scenarios (e.g., to specify a custom cache path or setup globally a proxy) where custom configuration can be required.*

Selenium Manager is a CLI tool. Therefore, under the hood, the Selenium bindings call Selenium Manager by invoking shell commands. Like any other CLI tool, arguments can be used to specify specific capabilities in Selenium Manager. The different arguments supported by Selenium Manager can be checked by running the following command:

```
$ ./selenium-manager --help
```

| CLI argument                                | Configuration file                          | Env variable                               | Description                                                                                                                                                                                                                                                                             |
| ------------------------------------------- | ------------------------------------------- | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--browser BROWSER`                         | `browser = "BROWSER"`                       | `SE_BROWSER=BROWSER`                       | Browser name: `chrome`, `firefox`, `edge`, `iexplorer`, `safari`, `safaritp`, or `webview2`                                                                                                                                                                                             |
| `--driver <DRIVER>`                         | `driver = "DRIVER"`                         | `SE_DRIVER=DRIVER`                         | Driver name: `chromedriver`, `geckodriver`, `msedgedriver`, `IEDriverServer`, or `safaridriver`                                                                                                                                                                                         |
| `--browser-version <BROWSER_VERSION>`       | `browser-version = "BROWSER_VERSION"`       | `SE_BROWSER_VERSION=BROWSER_VERSION`       | Major browser version (e.g., `105`, `106`, etc. Also: `beta`, `dev`, `canary` -or `nightly`-, and `esr` -in Firefox- are accepted)                                                                                                                                                      |
| `--driver-version <DRIVER_VERSION>`         | `driver-version = "DRIVER_VERSION"`         | `SE_DRIVER_VERSION=DRIVER_VERSION`         | Driver version (e.g., `106.0.5249.61, 0.31.0`, etc.)                                                                                                                                                                                                                                    |
| `--browser-path <BROWSER_PATH>`             | `browser-path = "BROWSER_PATH"`             | `SE_BROWSER_PATH=BROWSER_PATH`             | Browser path (absolute) for browser version detection (e.g., `/usr/bin/google-chrome`, `/Applications/Google Chrome.app/Contents/MacOS/Google Chrome`, `C:\Program Files\Google\Chrome\Application\chrome.exe`)                                                                         |
| `--driver-mirror-url <DRIVER_MIRROR_URL>`   | `driver-mirror-url = "DRIVER_MIRROR_URL"`   | `SE_DRIVER_MIRROR_URL=DRIVER_MIRROR_URL`   | Mirror URL for driver repositories                                                                                                                                                                                                                                                      |
| `--browser-mirror-url <BROWSER_MIRROR_URL>` | `browser-mirror-url = "BROWSER_MIRROR_URL"` | `SE_BROWSER_MIRROR_URL=BROWSER_MIRROR_URL` | Mirror URL for browser repositories                                                                                                                                                                                                                                                     |
| `--output <OUTPUT>`                         | `output = "OUTPUT"`                         | `SE_OUTPUT=OUTPUT`                         | Output type: `LOGGER` (using `INFO`, `WARN`, etc.), `JSON` (custom JSON notation), `SHELL` (Unix-like), or `MIXED` (`INFO`, `WARN`, `DEBUG`, etc. to stderr and minimal `JSON` to stdout). Default: `LOGGER`                                                                            |
| `--os <OS>`                                 | `os = "OS"`                                 | `SE_OS=OS`                                 | Operating system for drivers and browsers (i.e., `windows`, `linux`, or `macos`)                                                                                                                                                                                                        |
| `--arch <ARCH>`                             | `arch = "ARCH"`                             | `SE_ARCH=ARCH`                             | System architecture for drivers and browsers (i.e., `x32`, `x64`, or `arm64`)                                                                                                                                                                                                           |
| `--proxy <PROXY>`                           | `proxy = "PROXY"`                           | `SE_PROXY=PROXY`                           | HTTP proxy for network connection (e.g., `myproxy:port`, `myuser:mypass@myproxy:port`)                                                                                                                                                                                                  |
| `--timeout <TIMEOUT>`                       | `timeout = TIMEOUT`                         | `SE_TIMEOUT=TIMEOUT`                       | Timeout for network requests (in seconds). Default: `300`                                                                                                                                                                                                                               |
| `--offline`                                 | `offline = true`                            | `SE_OFFLINE=true`                          | Offline mode (i.e., disabling network requests and downloads)                                                                                                                                                                                                                           |
| `--force-browser-download`                  | `force-browser-download = true`             | `SE_FORCE_BROWSER_DOWNLOAD=true`           | Force to download browser, e.g., when a browser is already installed in the system, but you want Selenium Manager to download and use it                                                                                                                                                |
| `--avoid-browser-download`                  | `avoid-browser-download = true`             | `SE_AVOID_BROWSER_DOWNLOAD=true`           | Avoid to download browser, e.g., when a browser is supposed to be downloaded by Selenium Manager, but you prefer to avoid it                                                                                                                                                            |
| `--skip-driver-in-path`                     | `skip-driver-in-path = true`                | `SE_SKIP_DRIVER_IN_PATH=true`              | Not using drivers found in the `PATH`                                                                                                                                                                                                                                                   |
| `--skip-browser-in-path`                    | `skip-browser-in-path = true`               | `SE_SKIP_BROWSER_IN_PATH=true`             | Not using browsers found in the `PATH`                                                                                                                                                                                                                                                  |
| `--debug`                                   | `debug = true`                              | `SE_DEBUG=true`                            | Display `DEBUG` messages                                                                                                                                                                                                                                                                |
| `--trace`                                   | `trace = true`                              | `SE_TRACE=true`                            | Display `TRACE` messages                                                                                                                                                                                                                                                                |
| `--cache-path <CACHE_PATH>`                 | `cache-path="CACHE_PATH"`                   | `SE_CACHE_PATH=CACHE_PATH`                 | Local folder used to store downloaded assets (drivers and browsers), local metadata, and configuration file. See next section for details. Default: `~/.cache/selenium`. For Windows paths in the TOML configuration file, double backslashes are required (e.g., `C:\\custom\\cache`). |
| `--ttl <TTL>`                               | `ttl = TTL`                                 | `SE_TTL=TTL`                               | Time-to-live in seconds. See next section for details. Default: `3600` (1 hour)                                                                                                                                                                                                         |
| `--language-binding <LANGUAGE>`             | `language-binding = "LANGUAGE"`             | `SE_LANGUAGE_BINDING=LANGUAGE`             | Language that invokes Selenium Manager (e.g., Java, JavaScript, Python, DotNet, Ruby)                                                                                                                                                                                                   |
| `--avoid-stats`                             | `avoid-stats = true`                        | `SE_AVOID_STATS=true`                      | Avoid sends usage statistics to plausible.io. Default: `false`                                                                                                                                                                                                                          |

```toml
browser = "chrome"                 # --browser BROWSER
driver = "chromedriver"             # --driver DRIVER
browser-version = "106"             # --browser-version BROWSER_VERSION
driver-version = "106.0.5249.61"    # --driver-version DRIVER_VERSION
browser-path = "/usr/bin/google-chrome"  # --browser-path BROWSER_PATH
driver-mirror-url = "https://custom-driver-mirror.com"  # --driver-mirror-url DRIVER_MIRROR_URL
browser-mirror-url = "https://custom-browser-mirror.com"  # --browser-mirror-url BROWSER_MIRROR_URL
output = "LOGGER"                   # --output OUTPUT
os = "linux"                        # --os OS
arch = "x64"                        # --arch ARCH
proxy = "myproxy:8080"              # --proxy PROXY
timeout = 300                       # --timeout TIMEOUT
offline = true                      # --offline
force-browser-download = true       # --force-browser-download
avoid-browser-download = false      # --avoid-browser-download
debug = true                        # --debug
trace = true                        # --trace
cache-path = "/custom/cache/path"    # --cache-path CACHE_PATH
ttl = 3600                          # --ttl TTL
language-binding = "Python"         # --language-binding LANGUAGE
avoid-stats = true                  # --avoid-stats
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/selenium_manager/example_se-config.toml#L1-L21)

##### /examples/python/tests/selenium\_manager/example\_se-config.toml

```toml
browser = "chrome"                 # --browser BROWSER
driver = "chromedriver"             # --driver DRIVER
browser-version = "106"             # --browser-version BROWSER_VERSION
driver-version = "106.0.5249.61"    # --driver-version DRIVER_VERSION
browser-path = "/usr/bin/google-chrome"  # --browser-path BROWSER_PATH
driver-mirror-url = "https://custom-driver-mirror.com"  # --driver-mirror-url DRIVER_MIRROR_URL
browser-mirror-url = "https://custom-browser-mirror.com"  # --browser-mirror-url BROWSER_MIRROR_URL
output = "LOGGER"                   # --output OUTPUT
os = "linux"                        # --os OS
arch = "x64"                        # --arch ARCH
proxy = "myproxy:8080"              # --proxy PROXY
timeout = 300                       # --timeout TIMEOUT
offline = true                      # --offline
force-browser-download = true       # --force-browser-download
avoid-browser-download = false      # --avoid-browser-download
debug = true                        # --debug
trace = true                        # --trace
cache-path = "/custom/cache/path"    # --cache-path CACHE_PATH
ttl = 3600                          # --ttl TTL
language-binding = "Python"         # --language-binding LANGUAGE
avoid-stats = true                  # --avoid-stats
```

```
$ ./selenium-manager --browser chrome --debug
DEBUG chromedriver not found in PATH
DEBUG chrome detected at C:\Program Files\Google\Chrome\Application\chrome.exe
DEBUG Detected browser: chrome 139.0.7258.67
DEBUG Discovering versions from https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json
DEBUG Required driver: chromedriver 139.0.7258.68
DEBUG Acquiring lock: C:\Users\boni\.cache\selenium\chromedriver\win64\139.0.7258.68\sm.lock
DEBUG Downloading chromedriver 139.0.7258.68 from https://storage.googleapis.com/chrome-for-testing-public/139.0.7258.68/win64/chromedriver-win64.zip
INFO  Driver path: C:\Users\boni\.cache\selenium\chromedriver\win64\139.0.7258.68\chromedriver.exe
INFO  Browser path: C:\Program Files\Google\Chrome\Application\chrome.exe
```

In this case, the local Chrome (in Windows) is detected by Selenium Manager. Then, using its version and the CfT endpoints, the proper chromedriver version (115, in this example) is downloaded to the local cache. Finally, Selenium Manager provides two results: i) the driver path (downloaded) and ii) the browser path (local).

Let’s consider another example. Now we want to use Chrome beta. Therefore, we invoke Selenium Manager specifying that version label as follows (notice that the CfT beta is discovered, downloaded, and stored in the local cache):

```
$ ./selenium-manager --browser chrome --browser-version beta --debug
DEBUG chromedriver not found in PATH
DEBUG chrome not found in PATH
DEBUG chrome beta not found in the system
DEBUG Discovering versions from https://googlechromelabs.github.io/chrome-for-testing/last-known-good-versions-with-downloads.json
DEBUG Required browser: chrome 140.0.7339.16
DEBUG Acquiring lock: C:\Users\boni\.cache\selenium\chrome\win64\140.0.7339.16\sm.lock
DEBUG Downloading chrome 140.0.7339.16 from https://storage.googleapis.com/chrome-for-testing-public/140.0.7339.16/win64/chrome-win64.zip
DEBUG chrome 140.0.7339.16 is available at C:\Users\boni\.cache\selenium\chrome\win64\140.0.7339.16\chrome.exe
DEBUG Discovering versions from https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json
DEBUG Required driver: chromedriver 140.0.7339.16
DEBUG Acquiring lock: C:\Users\boni\.cache\selenium\chromedriver\win64\140.0.7339.16\sm.lock
DEBUG Downloading chromedriver 140.0.7339.16 from https://storage.googleapis.com/chrome-for-testing-public/140.0.7339.16/win64/chromedriver-win64.zip
INFO  Driver path: C:\Users\boni\.cache\selenium\chromedriver\win64\140.0.7339.16\chromedriver.exe
INFO  Browser path: C:\Users\boni\.cache\selenium\chrome\win64\140.0.7339.16\chrome.exe
```

```java
    public void testSetupWithoutManager() {
        System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/selenium_manager/SeleniumManagerUsageDemo.java#L12-L17)

##### /examples/java/src/test/java/dev/selenium/selenium\_manager/SeleniumManagerUsageDemo.java

```java
package dev.selenium.selenium_manager;

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class SeleniumManagerUsageDemo {

    @Test
    @Disabled("This test is just for demo purposes and should not be run in CI")
    public void testSetupWithoutManager() {
        System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }

    @Test
    public void testSetupWithManager() {
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }

}
```

**Selenium Manager**

```java
    public void testSetupWithManager() {
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/selenium_manager/SeleniumManagerUsageDemo.java#L20-L24)

##### /examples/java/src/test/java/dev/selenium/selenium\_manager/SeleniumManagerUsageDemo.java

```java
package dev.selenium.selenium_manager;

import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class SeleniumManagerUsageDemo {

    @Test
    @Disabled("This test is just for demo purposes and should not be run in CI")
    public void testSetupWithoutManager() {
        System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }

    @Test
    public void testSetupWithManager() {
        WebDriver driver = new ChromeDriver();
        driver.get("https://www.selenium.dev/documentation/selenium_manager/");
        driver.quit();
    }

}
```

**Previously**

```py
def setup_without_selenium_manager():
    chrome_service = Service(executable_path='path/to/chrome.exe')
    driver = webdriver.Chrome(chrome_service)
    return driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/selenium_manager/usage.py#L5-L8)

##### /examples/python/tests/selenium\_manager/usage.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

def setup_without_selenium_manager():
    chrome_service = Service(executable_path='path/to/chrome.exe')
    driver = webdriver.Chrome(chrome_service)
    return driver
    
def setup_with_selenium_manager():
    driver = webdriver.Chrome()
    return driver
```

**Selenium Manager**

```py
def setup_with_selenium_manager():
    driver = webdriver.Chrome()
    return driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/selenium_manager/usage.py#L10-L12)

##### /examples/python/tests/selenium\_manager/usage.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.chrome.service import Service

def setup_without_selenium_manager():
    chrome_service = Service(executable_path='path/to/chrome.exe')
    driver = webdriver.Chrome(chrome_service)
    return driver
    
def setup_with_selenium_manager():
    driver = webdriver.Chrome()
    return driver
```

```cs
        public void TestWithSeleniumManager()
        {
            // Before
            // using var driver = new ChromeDriver("path/to/chromedriver");

            // Now
            using var driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/documentation/selenium_manager/");
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/SeleniumManager/UsageTest.cs#L10-L18)

##### /examples/dotnet/SeleniumDocs/SeleniumManager/UsageTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.SeleniumManagerTest
{
    [TestClass]
    public class UsageTest
    {
        [TestMethod]
        public void TestWithSeleniumManager()
        {
            // Before
            // using var driver = new ChromeDriver("path/to/chromedriver");

            // Now
            using var driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/documentation/selenium_manager/");
        }
    }
}
```

**Previously**

```rb
def setup_without_selenium_manager
  service = Selenium::WebDriver::Chrome::Service.new(path: '/path/to/chromedriver')
  driver = Selenium::WebDriver.for(:chrome, service: service)
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/selenium_manager/usage.rb#L5-L10)

##### /examples/ruby/spec/selenium\_manager/usage.rb

```rb
# frozen_string_literal: true

require 'selenium-webdriver'

def setup_without_selenium_manager
  service = Selenium::WebDriver::Chrome::Service.new(path: '/path/to/chromedriver')
  driver = Selenium::WebDriver.for(:chrome, service: service)
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end

def setup_with_selenium_manager
  driver = Selenium::WebDriver.for(:chrome) # Selenium Manager handles the driver automatically
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end
```

**Selenium Manager**

```rb
def setup_with_selenium_manager
  driver = Selenium::WebDriver.for(:chrome) # Selenium Manager handles the driver automatically
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/selenium_manager/usage.rb#L12-L16)

##### /examples/ruby/spec/selenium\_manager/usage.rb

```rb
# frozen_string_literal: true

require 'selenium-webdriver'

def setup_without_selenium_manager
  service = Selenium::WebDriver::Chrome::Service.new(path: '/path/to/chromedriver')
  driver = Selenium::WebDriver.for(:chrome, service: service)
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end

def setup_with_selenium_manager
  driver = Selenium::WebDriver.for(:chrome) # Selenium Manager handles the driver automatically
  driver.get('https://www.selenium.dev/documentation/selenium_manager/')
  driver.quit
end
```

**Previously**

```js
  // it('Creates driver with Selenium Manager', async function () {
  //   let driverPath = '/path/to/chromedriver';
  //   let browserPath = '/path/to/chrome';

  //   options.setChromeBinaryPath(browserPath)

  //   let service = new Chrome.ServiceBuilder().setPath(driverPath)

  //   let driver = new Builder()
  //       .forBrowser(Browser.CHROME)
  //       .setChromeService(service)
  //       .build();

  //   await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  //   await driver.quit();
  // });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/selenium_manager/usage.spec.js#L16-L31)

##### /examples/javascript/test/selenium\_manager/usage.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options();

describe('Usage Test', function () {
  it('Creates driver wit Selenium Manager', async function () {

    let driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  // it('Creates driver with Selenium Manager', async function () {
  //   let driverPath = '/path/to/chromedriver';
  //   let browserPath = '/path/to/chrome';

  //   options.setChromeBinaryPath(browserPath)

  //   let service = new Chrome.ServiceBuilder().setPath(driverPath)

  //   let driver = new Builder()
  //       .forBrowser(Browser.CHROME)
  //       .setChromeService(service)
  //       .build();

  //   await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  //   await driver.quit();
  // });
});
```

**Selenium Manager**

```js
  it('Creates driver wit Selenium Manager', async function () {

    let driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/selenium_manager/usage.spec.js#L6-L14)

##### /examples/javascript/test/selenium\_manager/usage.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options();

describe('Usage Test', function () {
  it('Creates driver wit Selenium Manager', async function () {

    let driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  // it('Creates driver with Selenium Manager', async function () {
  //   let driverPath = '/path/to/chromedriver';
  //   let browserPath = '/path/to/chrome';

  //   options.setChromeBinaryPath(browserPath)

  //   let service = new Chrome.ServiceBuilder().setPath(driverPath)

  //   let driver = new Builder()
  //       .forBrowser(Browser.CHROME)
  //       .setChromeService(service)
  //       .build();

  //   await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  //   await driver.quit();
  // });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

## Selenium Grid

Selenium Manager allows you to configure the drivers automatically when setting up Selenium Grid. To that aim, you need to include the argument `--selenium-manager true` in the command to start Selenium Grid. For more details, visit the [Selenium Grid starting page](https://www.selenium.dev/documentation/grid/getting_started/).

Moreover, Selenium Manager also allows managing Selenium Grid releases automatically. For that, the argument `--grid` is used as follows:

```
$ ./selenium-manager --grid
```

After this command, Selenium Manager discovers the latest version of Selenium Grid, storing the `selenium-server.jar` in the local cache.

Optionally, the argument `--grid` allows to specify a Selenium Grid version (`--grid <GRID_VERSION>`).

## Known Limitations

### Connectivity issues

Selenium Manager requests remote endpoints (like Chrome for Testing (CfT), among others) to discover and download drivers and browsers from online repositories. When this operation is done in a corporate environment with a proxy or firewall, it might lead to connectivity problems like the following:

```
error sending request for url (https://googlechromelabs.github.io/chrome-for-testing/known-good-versions-with-downloads.json)
```

```
error trying to connect: dns error: failed to lookup address information
```

```
error trying to connect: An existing connection was forcibly closed by the remote host. (os error 10054)
```

```
libdbus-glib-1.so.2: cannot open shared object file: No such file or directory
Couldn't load XPCOM.
```

If that happens, the solution is to install that library, for instance, as follows:

```
sudo apt-get install libdbus-glib-1-2
```

A similar issue might happen when trying to execute Chrome for Testing in Linux:

```
error while loading shared libraries: libatk-1.0.so.0: cannot open shared object file: No such file or directory
```

In this case, the library to be installed is the following:

```
sudo apt-get install libatk-bridge2.0-0
```

最終更新 August 17, 2025: [chore: fix typos (#2428) (b99b7e3c145)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/b99b7e3c145a6601f0b4313e9a8913fcf3324310)

----
url: https://www.selenium.dev/documentation/test_practices/discouraged/http_response_codes/
----

# HTTP response codes

For some browser configurations in Selenium RC, Selenium acted as a proxy between the browser and the site being automated. This meant that all browser traffic passed through Selenium could be captured or manipulated. The `captureNetworkTraffic()` method purported to capture all of the network traffic between the browser and the site being automated, including HTTP response codes.

Selenium WebDriver is a completely different approach to browser automation, preferring to act more like a user. This is represented in the way you write tests with WebDriver. In automated functional testing, checking the status code is not a particularly important detail of a test’s failure; the steps that preceded it are more important.

The browser will always represent the HTTP status code, imagine for example a 404 or a 500 error page. A simple way to “fail fast” when you encounter one of these error pages is to check the page title or content of a reliable point (e.g. the `<h1>` tag) after every page load. If you are using the page object model, you can include this check in your class constructor or similar point where the page load is expected. Occasionally, the HTTP code may even be represented in the browser’s error page and you could use WebDriver to read this and improve your debugging output.

Checking the webpage itself is in line with WebDriver’s ideal practice of representing and asserting upon the user’s view of the website.

If you insist, an advanced solution to capturing HTTP status codes is to replicate the behaviour of Selenium RC by using a proxy. WebDriver API provides the ability to set a proxy for the browser, and there are a number of proxies that will programmatically allow you to manipulate the contents of requests sent to and received from the web server. Using a proxy lets you decide how you want to respond to redirection response codes. Additionally, not every browser makes the response codes available to WebDriver, so opting to use a proxy allows you to have a solution that works for every browser.

----
url: https://www.selenium.dev/documentation/webdriver/elements/locators/
----

# Locator strategies

Ways to identify one or more specific elements in the DOM.

A locator is a way to identify elements on a page. It is the argument passed to the [Finding element](https://www.selenium.dev/documentation/webdriver/elements/finders/) methods.

Check out our [encouraged test practices](https://www.selenium.dev/documentation/test_practices/encouraged/) for tips on [locators](https://www.selenium.dev/documentation/test_practices/encouraged/locators/), including which to use when and why to declare locators separately from the finding methods.

## Traditional Locators

Selenium provides support for these 8 traditional location strategies in WebDriver:

| Locator           | Description                                                                                                                                   |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| class name        | Locates elements whose class name contains the search value (compound class names are not permitted)                                          |
| css selector      | Locates elements matching a CSS selector                                                                                                      |
| id                | Locates elements whose ID attribute matches the search value                                                                                  |
| name              | Locates elements whose NAME attribute matches the search value                                                                                |
| link text         | Locates anchor elements whose visible text matches the search value                                                                           |
| partial link text | Locates anchor elements whose visible text contains the search value. If multiple elements are matching, only the first one will be selected. |
| tag name          | Locates elements whose tag name matches the search value                                                                                      |
| xpath             | Locates elements matching an XPath expression                                                                                                 |

## Creating Locators

To work on a web element using Selenium, we need to first locate it on the web page. Selenium provides us above mentioned ways, using which we can locate element on the page. To understand and create locator we will use the following HTML snippet.

```html
<html>
<body>
<style>
.information {
  background-color: white;
  color: black;
  padding: 10px;
}
</style>
<h2>Contact Selenium</h2>

<form>
  <input type="radio" name="gender" value="m" />Male &nbsp;
  <input type="radio" name="gender" value="f" />Female <br>
  <br>
  <label for="fname">First name:</label><br>
  <input class="information" type="text" id="fname" name="fname" value="Jane"><br><br>
  <label for="lname">Last name:</label><br>
  <input class="information" type="text" id="lname" name="lname" value="Doe"><br><br>
  <label for="newsletter">Newsletter:</label>
  <input type="checkbox" name="newsletter" value="1" /><br><br>
  <input type="submit" value="Submit">
</form> 

<p>To know more about Selenium, visit the official page 
<a href ="www.selenium.dev">Selenium Official Page</a> 
</p>

</body>
</html>
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L31" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L7-L9)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.ClassName("information"));
  
```

```rb
    driver.find_element(class: 'information')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L7)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.className('information'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.className("information"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L38" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L17-L19)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.CssSelector("#fname"));
  
```

```rb
    driver.find_element(css: '#fname')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L11)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.css('#fname'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.css("#fname"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L45" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L27-L29)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.Id("lname"));
  
```

```rb
    driver.find_element(id: 'lname')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L15)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.id('lname'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.id("lname"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L52" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L37-L39)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.Name("newsletter"));
  
```

```rb
    driver.find_element(name: 'newsletter')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L19)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.name('newsletter'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.name("newsletter"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L59" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L47-L49)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.LinkText("Selenium Official Page"));
  
```

```rb
    driver.find_element(link_text: 'Selenium Official Page')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L23)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.linkText('Selenium Official Page'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.linkText("Selenium Official Page"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L66" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L57-L59)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.PartialLinkText("Official Page"));
  
```

```rb
    driver.find_element(partial_link_text: 'Official Page')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L27)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.partialLinkText('Official Page'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.partialLinkText("Official Page"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L73" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L67-L69)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.TagName("a"));
  
```

```rb
    driver.find_element(tag_name: 'a')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L31)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.tagName('a'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.tagName("a"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L80" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L77-L79)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	  driver.FindElement(By.Xpath("//input[@value='f']"));
  
```

```rb
    driver.find_element(xpath: "//input[@value='f']")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L35)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.xpath('//input[@value='f']'));
  
```

```kotlin
    import org.openqa.selenium.By
    val driver = ChromeDriver()
	  val loc: WebElement = driver.findElement(By.xpath('//input[@value='f']'))
  
```

```java
    import org.openqa.selenium.By;
    WebDriver driver = new ChromeDriver();
	driver.findElement(By.className("information"));
  
```

```python
    from selenium.webdriver.common.by import By
    driver = webdriver.Chrome()
	driver.find_element(By.CLASS_NAME, "information")
  
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.ClassName("information"));
  
```

```rb
    driver.find_element(class: 'information')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L7)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.className('information'));
  
```

```kotlin
    import org.openqa.selenium.By
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.className("information"))
  
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java#L37-L38)

##### /examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java

```java
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java#L22-L23)

##### /examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java

```java
```

```java
By emailLocator = RelativeLocator.with(By.tagName("input")).above(By.id("password"));
```

```python
email_locator = locate_with(By.TAG_NAME, "input").above({By.ID: "password"})
```

```csharp
var emailLocator = RelativeBy.WithLocator(By.TagName("input")).Above(By.Id("password"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L40)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let emailLocator = locateWith(By.tagName('input')).above(By.id('password'));
```

```kotlin
val emailLocator = RelativeLocator.with(By.tagName("input")).above(By.id("password"))
```

```java
By passwordLocator = RelativeLocator.with(By.tagName("input")).below(By.id("email"));
```

```python
password_locator = locate_with(By.TAG_NAME, "input").below({By.ID: "email"})
```

```csharp
var passwordLocator = RelativeBy.WithLocator(By.TagName("input")).Below(By.Id("email"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L44)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let passwordLocator = locateWith(By.tagName('input')).below(By.id('email'));
```

```kotlin
val passwordLocator = RelativeLocator.with(By.tagName("input")).below(By.id("email"))
```

```java
By cancelLocator = RelativeLocator.with(By.tagName("button")).toLeftOf(By.id("submit"));
```

```python
cancel_locator = locate_with(By.TAG_NAME, "button").to_left_of({By.ID: "submit"})
```

```csharp
var cancelLocator = RelativeBy.WithLocator(By.tagName("button")).LeftOf(By.Id("submit"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L48)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let cancelLocator = locateWith(By.tagName('button')).toLeftOf(By.id('submit'));
```

```kotlin
val cancelLocator = RelativeLocator.with(By.tagName("button")).toLeftOf(By.id("submit"))
```

```java
By submitLocator = RelativeLocator.with(By.tagName("button")).toRightOf(By.id("cancel"));
```

```python
submit_locator = locate_with(By.TAG_NAME, "button").to_right_of({By.ID: "cancel"})
```

```csharp
var submitLocator = RelativeBy.WithLocator(By.tagName("button")).RightOf(By.Id("cancel"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L52)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let submitLocator = locateWith(By.tagName('button')).toRightOf(By.id('cancel'));
```

```kotlin
val submitLocator = RelativeLocator.with(By.tagName("button")).toRightOf(By.id("cancel"))
```

```java
By emailLocator = RelativeLocator.with(By.tagName("input")).near(By.id("lbl-email"));
```

```python
email_locator = locate_with(By.TAG_NAME, "input").near({By.ID: "lbl-email"})
```

```csharp
var emailLocator = RelativeBy.WithLocator(By.tagName("input")).Near(By.Id("lbl-email"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L56)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let emailLocator = locateWith(By.tagName('input')).near(By.id('lbl-email'));
```

```kotlin
val emailLocator = RelativeLocator.with(By.tagName("input")).near(By.id("lbl-email"));
```

```java
By submitLocator = RelativeLocator.with(By.tagName("button")).below(By.id("email")).toRightOf(By.id("cancel"));
```

```python
submit_locator = locate_with(By.TAG_NAME, "button").below({By.ID: "email"}).to_right_of({By.ID: "cancel"})
```

```csharp
var submitLocator = RelativeBy.WithLocator(By.tagName("button")).Below(By.Id("email")).RightOf(By.Id("cancel"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L60)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let submitLocator = locateWith(By.tagName('button')).below(By.id('email')).toRightOf(By.id('cancel'));
```

```kotlin
val submitLocator = RelativeLocator.with(By.tagName("button")).below(By.id("email")).toRightOf(By.id("cancel"))
```

Last modified February 16, 2026: [added locator code file for java for locator strategies Section and added content in diff languages files (#2583) (77549cd7301)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/77549cd7301dea332c7559cb6a5365a82a357e50)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/troubleshooting/
----

# 故障排除协助

如何管理 WebDriver 的问题.

Selenium错误的根本原因并不总是很明显.

1. 最常见的Selenium相关错误, 是源自未及时同步的结果. 请阅读 [等待策略](https://www.selenium.dev/zh-cn/documentation/webdriver/waits/). 当遇到一个问题, 如果不确定是否因为同步策略, 您可以尝试*暂时*硬编码一个较大的休眠时间, 您将明确添加显式等待是否有帮助.

2. 请注意, 报告给项目的许多错误, 实际上是由Selenium向其发送命令的基础驱动程序所引起的. 您可以通过执行 [浏览器](https://www.selenium.dev/zh-cn/documentation/webdriver/browsers/) 中的 多个命令来解决驱动程序问题.

3. 如果您对如何执行有疑惑, 请查看 [支持选项](/support/) 获取帮助的方法.

4. 如果您认为您发现了Selenium代码的问题, 请在Github上提交 [问题报告](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=I-defect%2Cneeds-triaging\&template=bug-report.yml\&title=%5B%F0%9F%90%9B+Bug%5D%3A+).

***

##### [理解常见的异常](/zh-cn/documentation/webdriver/troubleshooting/errors/)

如何处理Selenium代码中的各种问题.

##### [记录 Selenium 命令](/zh-cn/documentation/webdriver/troubleshooting/logging/)

获取Selenium的执行信息.

##### [升级到Selenium 4](/zh-cn/documentation/webdriver/troubleshooting/upgrade_to_selenium_4/)

对Selenium 4感兴趣? 查看本指南, 它将帮助您升级到最新版本!

最后修改 October 2, 2023: [Update Chinese translation on troubleshooting (#1487) (60f2eb90ee8)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/60f2eb90ee89f316129085aa19ad65bcf0730bee)

----
url: https://www.selenium.dev/documentation/legacy/selenium_2/faq/
----

# Frequently Asked Questions for Selenium 2

```
WebDriver driver; // Assigned elsewhere
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("return document.title");
```

Other language bindings will follow a similar approach. Take a look at the UsingJavascript page for more information.

### Q: Why is my Javascript execution always returning null?

A: You need to return from your javascript snippet to return a value, so:

```
js.executeScript("document.title");
```

will return null, but:

```
js.executeScript("return document.title");
```

will return the title of the document.

### Q: My XPath finds elements in one browser, but not in others. Why is this?

A: The short answer is that each supported browser handles XPath slightly differently, and you’re probably running into one of these differences. The long answer is on the XpathInWebDriver page.

### Q: The InternetExplorerDriver does not work well on Vista. How do I get it to work as expected?

A: The InternetExplorerDriver requires that all security domains are set to the same value (either trusted or untrusted) If you’re not in a position to modify the security domains, then you can override the check like this:

```
DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer();
capabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
WebDriver driver = new InternetExplorerDriver(capabilities);
```

```
// Get a handle to the open alert, prompt or confirmation
Alert alert = driver.switchTo().alert();
// Get the text of the alert or prompt
alert.getText();  
// And acknowledge the alert (equivalent to clicking "OK")
alert.accept();
```

### Q: Does WebDriver support file uploads?

A: Yes.

You can’t interact with the native OS file browser dialog directly, but we do some magic so that if you call WebElement#sendKeys("/path/to/file") on a file upload element, it does the right thing. Make sure you don’t WebElement#click() the file upload element, or the browser will probably hang.

Handy hint: You can’t interact with hidden elements without making them un-hidden. If your element is hidden, it can probably be un-hidden with some code like:

```
((JavascriptExecutor)driver).executeScript("arguments[0].style.visibility = 'visible'; arguments[0].style.height = '1px'; arguments[0].style.width = '1px'; arguments[0].style.opacity = 1", fileUploadElement);
```

### Q: The “onchange” event doesn’t fire after a call “sendKeys”

A: WebDriver leaves the focus in the element you called “sendKeys” on. The “onchange” event will only fire when focus leaves that element. As such, you need to move the focus, perhaps using a “click” on another element.

### Q: Can I run multiple instances of the WebDriver sub-classes?

A: Each instance of an HtmlUnitDriver, ChromeDriver and FirefoxDriver is completely independent of every other instance (in the case of firefox and chrome, each instance has its own anonymous profile it uses). Because of the way that Windows works, there should only ever be a single InternetExplorerDriver instance at one time. If you need to run more than one instance of the InternetExplorerDriver at a time, consider using the Remote!WebDriver and virtual machines.

### Q: I need to use a proxy. How do I configure that?

A: Proxy configuration is done via the `org.openqa.selenium.Proxy` class like so:

```
Proxy proxy = new Proxy();
proxy.setProxyAutoconfigUrl("http://youdomain/config");

// We use firefox as an example here.
DesiredCapabilities capabilities = DesiredCapabilities.firefox();
capabilities.setCapability(CapabilityType.PROXY, proxy);

// You could use any webdriver implementation here
WebDriver driver = new FirefoxDriver(capabilities);
```

### Q: How do I handle authentication with the HtmlUnitDriver?

A: When creating your instance of the HtmlUnitDriver, override the “modifyWebClient” method, for example:

```
WebDriver driver = new HtmlUnitDriver() {
  protected WebClient modifyWebClient(WebClient client) {
    // This class ships with HtmlUnit itself
    DefaultCredentialsProvider creds = new DefaultCredentialsProvider();

    // Set some example credentials
    creds.addCredentials("username", "password");

    // And now add the provider to the webClient instance
    client.setCredentialsProvider(creds);

    return client;
  }
};
```

### Q: Is WebDriver thread-safe?

A: WebDriver is not thread-safe. Having said that, if you can serialise access to the underlying driver instance, you can share a reference in more than one thread. This is not advisable. You /can/ on the other hand instantiate one WebDriver instance for each thread.

### Q: How do I type into a contentEditable iframe?

A: Assuming that the iframe is named “foo”:

```
driver.switchTo().frame("foo");
WebElement editable = driver.switchTo().activeElement();
editable.sendKeys("Your text here");
```

Sometimes this doesn’t work, and this is because the iframe doesn’t have any content. On Firefox you can execute the following before “sendKeys”:

```
((JavascriptExecutor) driver).executeScript("document.body.innerHTML = '<br>'");
```

This is needed because the iframe has no content by default: there’s nothing to send keyboard input to. This method call inserts an empty tag, which sets everything up nicely.

Remember to switch out of the frame once you’re done (as all further interactions will be with this specific frame):

```
driver.switchTo().defaultContent();
```

### Q: WebDriver fails to start Firefox on Linux due to java.net.SocketException

A: If, when running WebDriver on Linux, Firefox fails to start and the error looks like:

```
Caused by: java.net.SocketException: Invalid argument
        at java.net.PlainSocketImpl.socketBind(Native Method)
        at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:365)
        at java.net.Socket.bind(Socket.java:571)
        at org.openqa.selenium.firefox.internal.SocketLock.isLockFree(SocketLock.java:99)
        at org.openqa.selenium.firefox.internal.SocketLock.lock(SocketLock.java:63)
```

It may be caused due to IPv6 settings on the machine. Execute:

```
sudo sysctl net.ipv6.bindv6only=0
```

```
WebElement element = ...;
((JavascriptExecutor) driver).executeScript("return arguments[0].getText();", element);
```

### Q: How do I start Firefox with an extension installed?

A:

```
FirefoxProfile profile = new FirefoxProfile()
profile.addExtension(....);

WebDriver driver = new FirefoxDriver(profile);
```

```
driver.findElement(By.tagName("body")).getText()
```

Last modified April 5, 2024: [Broken Links (#1612)\[deploy site\] (c73064b0d9b)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/c73064b0d9be5fdaae0c5da94854a9f1220e9c27)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/elements/finders/
----

# 查询网络元素

根据提供的定位值定位元素.

使用 Selenium 最基本的特点之一是获取可用于操作的元素引用。 Selenium 提供了许多内置的 [定位策略](https://www.selenium.dev/zh-cn/documentation/webdriver/elements/locators/)，用于唯一标识元素。 在更复杂的场景中，可以用多种方式使用这些定位器。为了本篇文档的目的， 我们来考虑下面的 HTML 片段：

```html
<ol id="vegetables">
 <li class="potatoes">…
 <li class="onions">…
 <li class="tomatoes"><span>Tomato is a Vegetable</span>…
</ol>
<ul id="fruits">
  <li class="bananas">…
  <li class="apples">…
  <li class="tomatoes"><span>Tomato is a Fruit</span>…
</ul>
```

```java
WebElement vegetable = driver.findElement(By.className("tomatoes"));
  
```

```python
vegetable = driver.find_element(By.CLASS_NAME, "tomatoes")
  
```

```csharp
var vegetable = driver.FindElement(By.ClassName("tomatoes"));
  
```

```rb
      driver.find_element(class: 'tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L10)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const vegetable = await driver.findElement(By.className('tomatoes'));
  
```

```kotlin
val vegetable: WebElement = driver.findElement(By.className("tomatoes"))
  
```

```java
WebElement fruits = driver.findElement(By.id("fruits"));
WebElement fruit = fruits.findElement(By.className("tomatoes"));
  
```

```python
fruits = driver.find_element(By.ID, "fruits")
fruit = fruits.find_element(By.CLASS_NAME,"tomatoes")
  
```

```csharp
IWebElement fruits = driver.FindElement(By.Id("fruits"));
IWebElement fruit = fruits.FindElement(By.ClassName("tomatoes"));
  
```

```rb
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L14-L15)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const fruits = await driver.findElement(By.id('fruits'));
const fruit = fruits.findElement(By.className('tomatoes'));
  
```

```kotlin
val fruits = driver.findElement(By.id("fruits"))
val fruit = fruits.findElement(By.className("tomatoes"))
  
```

```java
WebElement shadowHost = driver.findElement(By.cssSelector("#shadow_host"));
SearchContext shadowRoot = shadowHost.getShadowRoot();
WebElement shadowContent = shadowRoot.findElement(By.cssSelector("#shadow_content"));
```

```python
shadow_host = driver.find_element(By.CSS_SELECTOR, '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(By.CSS_SELECTOR, '#shadow_content')
```

```csharp
var shadowHost = _driver.FindElement(By.CssSelector("#shadow_host"));
var shadowRoot = shadowHost.GetShadowRoot();
var shadowContent = shadowRoot.FindElement(By.CssSelector("#shadow_content"));
```

```ruby
shadow_host = @driver.find_element(css: '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(css: '#shadow_content')
```

```java
WebElement fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"));
  
```

```python
fruit = driver.find_element(By.CSS_SELECTOR,"#fruits .tomatoes")
  
```

```csharp
var fruit = driver.FindElement(By.CssSelector("#fruits .tomatoes"));
  
```

```rb
      driver.find_element(css: '#fruits .tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L19)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const fruit = await driver.findElement(By.css('#fruits .tomatoes'));
  
```

```kotlin
val fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"))
  
```

```java
List<WebElement> plants = driver.findElements(By.tagName("li"));
  
```

```python
plants = driver.find_elements(By.TAG_NAME, "li")
  
```

```csharp
IReadOnlyList<IWebElement> plants = driver.FindElements(By.TagName("li"));
  
```

```rb
      driver.find_elements(tag_name: 'li')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L23)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const plants = await driver.findElements(By.tagName('li'));
  
```

```kotlin
val plants: List<WebElement> = driver.findElements(By.tagName("li"))
  
```

```java
List<WebElement> elements = driver.findElements(By.tagName("li"));

for (WebElement element : elements) {
    System.out.println("Paragraph text:" + element.getText());
}
  
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Firefox()

    # Navigate to Url
driver.get("https://www.example.com")

    # Get all the elements available with tag name 'p'
elements = driver.find_elements(By.TAG_NAME, 'p')

for e in elements:
    print(e.text)
  
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using System.Collections.Generic;

namespace FindElementsExample {
 class FindElementsExample {
  public static void Main(string[] args) {
   IWebDriver driver = new FirefoxDriver();
   try {
    // Navigate to Url
    driver.Navigate().GoToUrl("https://example.com");

    // Get all the elements available with tag name 'p'
    IList < IWebElement > elements = driver.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }

   } finally {
    driver.Quit();
   }
  }
 }
}
  
```

```rb
      elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L27-L28)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
   
   require 'spec_helper'
   
   RSpec.describe 'Element Finders' do
     let(:driver) { start_session }
   
     context 'without executing finders', skip: 'these are just examples, not actual tests' do
       it 'finds the first matching element' do
         driver.find_element(class: 'tomatoes')
       end
   
       it 'uses a subset of the dom to find an element' do
         fruits = driver.find_element(id: 'fruits')
         fruits.find_element(class: 'tomatoes')
       end
   
       it 'uses an optimized locator' do
         driver.find_element(css: '#fruits .tomatoes')
       end
   
       it 'finds all matching elements' do
         driver.find_elements(tag_name: 'li')
       end
   
       it 'gets an element from a collection' do
         elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'finds element from element' do
         element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'find active element' do
         driver.find_element(css: '[name="q"]').send_keys('webElement')
         driver.switch_to.active_element.attribute('title')
       end
     end
   end
   
```

```javascript
const {Builder, By} = require('selenium-webdriver');
(async function example() {
    let driver = await new Builder().forBrowser('firefox').build();
    try {
        // Navigate to Url
        await driver.get('https://www.example.com');

        // Get all the elements available with tag 'p'
        let elements = await driver.findElements(By.css('p'));
        for(let e of elements) {
            console.log(await e.getText());
        }
    }
    finally {
        await driver.quit();
    }
})();
  
```

```kotlin
import org.openqa.selenium.By
import org.openqa.selenium.firefox.FirefoxDriver

fun main() {
    val driver = FirefoxDriver()
    try {
        driver.get("https://example.com")
        // Get all the elements available with tag name 'p'
        val elements = driver.findElements(By.tagName("p"))
        for (element in elements) {
            println("Paragraph text:" + element.text)
        }
    } finally {
        driver.quit()
    }
}
  
```

```java
  import org.openqa.selenium.By;
  import org.openqa.selenium.WebDriver;
  import org.openqa.selenium.WebElement;
  import org.openqa.selenium.chrome.ChromeDriver;
  import java.util.List;

  public class findElementsFromElement {
      public static void main(String[] args) {
          WebDriver driver = new ChromeDriver();
          try {
              driver.get("https://example.com");

              // Get element with tag name 'div'
              WebElement element = driver.findElement(By.tagName("div"));

              // Get all the elements available with tag name 'p'
              List<WebElement> elements = element.findElements(By.tagName("p"));
              for (WebElement e : elements) {
                  System.out.println(e.getText());
              }
          } finally {
              driver.quit();
          }
      }
  }
  
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://www.example.com")
##get elements from parent element using TAG_NAME

    # Get element with tag name 'div'
element = driver.find_element(By.TAG_NAME, 'div')

    # Get all the elements available with tag name 'p'
elements = element.find_elements(By.TAG_NAME, 'p')
for e in elements:
    print(e.text)

##get elements from parent element using XPATH
##NOTE: in order to utilize XPATH from current element, you must add "." to beginning of path

    # Get first element of tag 'ul'
element = driver.find_element(By.XPATH, '//ul')

    # get children of tag 'ul' with tag 'li'
elements  = element.find_elements(By.XPATH, './/li')
for e in elements:
    print(e.text)
  
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace FindElementsFromElement {
 class FindElementsFromElement {
  public static void Main(string[] args) {
   IWebDriver driver = new ChromeDriver();
   try {
    driver.Navigate().GoToUrl("https://example.com");

    // Get element with tag name 'div'
    IWebElement element = driver.FindElement(By.TagName("div"));

    // Get all the elements available with tag name 'p'
    IList < IWebElement > elements = element.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }
   } finally {
    driver.Quit();
   }
  }
 }
}
  
```

```rb
      element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L32-L34)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
   
   require 'spec_helper'
   
   RSpec.describe 'Element Finders' do
     let(:driver) { start_session }
   
     context 'without executing finders', skip: 'these are just examples, not actual tests' do
       it 'finds the first matching element' do
         driver.find_element(class: 'tomatoes')
       end
   
       it 'uses a subset of the dom to find an element' do
         fruits = driver.find_element(id: 'fruits')
         fruits.find_element(class: 'tomatoes')
       end
   
       it 'uses an optimized locator' do
         driver.find_element(css: '#fruits .tomatoes')
       end
   
       it 'finds all matching elements' do
         driver.find_elements(tag_name: 'li')
       end
   
       it 'gets an element from a collection' do
         elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'finds element from element' do
         element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'find active element' do
         driver.find_element(css: '[name="q"]').send_keys('webElement')
         driver.switch_to.active_element.attribute('title')
       end
     end
   end
   
```

```javascript
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = new Builder()
          .forBrowser('chrome')
          .build();

      await driver.get('https://www.example.com');

      // Get element with tag name 'div'
      let element = driver.findElement(By.css("div"));

      // Get all the elements available with tag name 'p'
      let elements = await element.findElements(By.css("p"));
      for(let e of elements) {
          console.log(await e.getText());
      }
  })();
  
```

```kotlin
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://example.com")

          // Get element with tag name 'div'
          val element = driver.findElement(By.tagName("div"))

          // Get all the elements available with tag name 'p'
          val elements = element.findElements(By.tagName("p"))
          for (e in elements) {
              println(e.text)
          }
      } finally {
          driver.quit()
      }
  }
  
```

```java
  import org.openqa.selenium.*;
  import org.openqa.selenium.chrome.ChromeDriver;

  public class activeElementTest {
    public static void main(String[] args) {
      WebDriver driver = new ChromeDriver();
      try {
        driver.get("http://www.google.com");
        driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement");

        // Get attribute of current active element
        String attr = driver.switchTo().activeElement().getAttribute("title");
        System.out.println(attr);
      } finally {
        driver.quit();
      }
    }
  }
  
```

```python
  from selenium import webdriver
  from selenium.webdriver.common.by import By

  driver = webdriver.Chrome()
  driver.get("https://www.google.com")
  driver.find_element(By.CSS_SELECTOR, '[name="q"]').send_keys("webElement")

    # Get attribute of current active element
  attr = driver.switch_to.active_element.get_attribute("title")
  print(attr)
  
```

```csharp
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;

    namespace ActiveElement {
     class ActiveElement {
      public static void Main(string[] args) {
       IWebDriver driver = new ChromeDriver();
       try {
        // Navigate to Url
        driver.Navigate().GoToUrl("https://www.google.com");
        driver.FindElement(By.CssSelector("[name='q']")).SendKeys("webElement");

        // Get attribute of current active element
        string attr = driver.SwitchTo().ActiveElement().GetAttribute("title");
        System.Console.WriteLine(attr);
       } finally {
        driver.Quit();
       }
      }
     }
    }
  
```

```rb
      driver.find_element(css: '[name="q"]').send_keys('webElement')
        driver.switch_to.active_element.attribute('title')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L38-L39)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
  
  require 'spec_helper'
  
  RSpec.describe 'Element Finders' do
    let(:driver) { start_session }
  
    context 'without executing finders', skip: 'these are just examples, not actual tests' do
      it 'finds the first matching element' do
        driver.find_element(class: 'tomatoes')
      end
  
      it 'uses a subset of the dom to find an element' do
        fruits = driver.find_element(id: 'fruits')
        fruits.find_element(class: 'tomatoes')
      end
  
      it 'uses an optimized locator' do
        driver.find_element(css: '#fruits .tomatoes')
      end
  
      it 'finds all matching elements' do
        driver.find_elements(tag_name: 'li')
      end
  
      it 'gets an element from a collection' do
        elements = driver.find_elements(:tag_name, 'p')
        elements.each { |e| puts e.text }
      end
  
      it 'finds element from element' do
        element = driver.find_element(:tag_name, 'div')
        elements = element.find_elements(:tag_name, 'p')
        elements.each { |e| puts e.text }
      end
  
      it 'find active element' do
        driver.find_element(css: '[name="q"]').send_keys('webElement')
        driver.switch_to.active_element.attribute('title')
      end
    end
  end
  
```

```javascript
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = await new Builder().forBrowser('chrome').build();
      await driver.get('https://www.google.com');
      await  driver.findElement(By.css('[name="q"]')).sendKeys("webElement");

      // Get attribute of current active element
      let attr = await driver.switchTo().activeElement().getAttribute("title");
      console.log(`${attr}`)
  })();
  
```

```kotlin
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://www.google.com")
          driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement")

          // Get attribute of current active element
          val attr = driver.switchTo().activeElement().getAttribute("title")
          print(attr)
      } finally {
          driver.quit()
      }
  }
  
```

最后修改 January 21, 2026: [docs(zh-cn): update finders documentation for clarity and accuracy (#2567) (bdae90a14de)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/bdae90a14de616c980e977d1db9fab547cced81d)

----
url: https://www.selenium.dev/ja/documentation/webdriver/drivers/
----

# ドライバーセッション

```java
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L23)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L9)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            driver = new ChromeDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BaseTest.cs#L48)

##### /examples/dotnet/SeleniumDocs/BaseTest.cs

```cs
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs
{
    public class BaseTest
    {
        protected IWebDriver driver;
        protected Uri GridUrl;
        private Process _webserverProcess;
        private const string ServerJarName = "selenium-server-4.44.0.jar";
        private static readonly string BaseDirectory = AppContext.BaseDirectory;
        private const string RelativePathToGrid = "../../../../../";
        private readonly string _examplesDirectory = Path.GetFullPath(Path.Combine(BaseDirectory, RelativePathToGrid));

        [TestCleanup]
        public void Cleanup()
        {
            driver?.Quit();

            if (_webserverProcess != null)
            {
                StopServer();
            }
        }

        protected void StartDriver(string browserVersion = null)
        {
            ChromeOptions options = new ChromeOptions();
            if (browserVersion != null)
            {
                options.BrowserVersion = browserVersion;
                string userDataDir = System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetRandomFileName());
                System.IO.Directory.CreateDirectory(userDataDir);
                options.AddArgument($"--user-data-dir={userDataDir}");
                options.AddArgument("--no-sandbox");
                options.AddArgument("--disable-dev-shm-usage");
            }
            driver = new ChromeDriver(options);
        }

        protected async Task StartServer()
        {
            if (_webserverProcess == null || _webserverProcess.HasExited)
            {
                _webserverProcess = new Process();
                _webserverProcess.StartInfo.FileName =
                    RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "java.exe" : "java";
                string port = GetFreeTcpPort().ToString();
                GridUrl = new Uri("http://localhost:" + port + "/wd/hub");
                _webserverProcess.StartInfo.Arguments = " -jar " + ServerJarName +
                                                        " standalone --port " + port +
                                                        " --selenium-manager true --enable-managed-downloads true";
                _webserverProcess.StartInfo.WorkingDirectory = _examplesDirectory;
                _webserverProcess.Start();
                await EnsureGridIsRunningAsync();
            }
        }

        private void StopServer()
        {
            if (_webserverProcess != null && !_webserverProcess.HasExited)
            {
                _webserverProcess.Kill();
                _webserverProcess.Dispose();
                _webserverProcess = null;
            }
        }

        private static int GetFreeTcpPort()
        {
            TcpListener l = new TcpListener(IPAddress.Loopback, 0);
            l.Start();
            int port = ((IPEndPoint)l.LocalEndpoint).Port;
            l.Stop();
            return port;
        }

        private async Task EnsureGridIsRunningAsync()
        {
            DateTime timeout = DateTime.Now.Add(TimeSpan.FromSeconds(240));
            bool isRunning = false;
            HttpClient client = new HttpClient();

            while (!isRunning && DateTime.Now < timeout)
            {
                try
                {
                    HttpResponseMessage response = await client.GetAsync(GridUrl + "/status");
                    if (response.IsSuccessStatusCode)
                    {
                        isRunning = true;
                    }
                    else
                    {
                        await Task.Delay(1000);
                    }
                }
                catch (HttpRequestException)
                {
                    await Task.Delay(1000);
                }
            }

            if (!isRunning)
            {
                throw new TimeoutException("Could not confirm the remote selenium server is running within 30 seconds");
            }
        }
    }
}
```

```rb
      driver = Selenium::WebDriver.for :chrome, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L14)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options)
      .setChromeService(service)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/drivers/service.spec.js#L46-L50)

##### /examples/javascript/test/drivers/service.spec.js

```js
const fs = require('fs');
const os = require('os');
const path = require('path');
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const {getBinaryPaths} = require("selenium-webdriver/common/driverFinder");

describe('Service Test', function () {
  let driver;
  let userDataDir;
  let service;
  let options;

  afterEach(async function () {
    if (driver) {
      await driver.quit();
      driver = null;
    }
    if (userDataDir) {
      fs.rmSync(userDataDir, { recursive: true, force: true });
      userDataDir = null;
    }
  });

  it('Default service', async function () {
    service = new Chrome.ServiceBuilder();
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });

  it('Set Driver Location', async function () {
    options = new Chrome.Options();
    options.setBrowserVersion("stable");
    let paths = getBinaryPaths(options);
    let driverPath = paths.driverPath;
    let browserPath = paths.browserPath;
    options.setChromeBinaryPath(browserPath);
    userDataDir = fs.mkdtempSync(path.join(os.tmpdir(), 'chrome-profile-'));
    options.addArguments(`--user-data-dir=${userDataDir}`);
    options.addArguments('--no-sandbox');
    options.addArguments('--disable-dev-shm-usage');
    service = new Chrome.ServiceBuilder(driverPath);
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });

  it('Set port', async function () {
    service = new Chrome.ServiceBuilder().setPort(1234);
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
        driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L11)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L28)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L16)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L28)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L35)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

***

##### [ブラウザーオプション](/ja/documentation/webdriver/drivers/options/)

これらの機能はすべてのブラウザで共有されています。

##### [HTTPクライアントの設定](/ja/documentation/webdriver/drivers/http_client/)

##### [ドライバーサービスクラス](/ja/documentation/webdriver/drivers/service/)

##### [リモートWebDriver](/ja/documentation/webdriver/drivers/remote_webdriver/)

最終更新 October 30, 2025: [Issue 2452- fixed line number for CSharp to show correct line for driver (#2489) (fe610b23e9b)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/fe610b23e9b91b7314fc8ae3c3d24deb73afee22)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/elements/information/
----

```java
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L27-L29)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L12-L15)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L18-L22)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    displayed_value = driver.find_element(name: 'email_input').displayed?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L12)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L16-L17)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
 driver.get("https://www.selenium.dev/selenium/web/inputs.html")

 //returns true if element is displayed else returns false
 val flag = driver.findElement(By.name("email_input")).isDisplayed()
```

```java
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L32-L34)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L19)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L25-L27)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    enabled_value = driver.find_element(name: 'email_input').enabled?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L17)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L23-L24)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//returns true if element is enabled else returns false
val attr = driver.findElement(By.name("button_input")).isEnabled()
```

```java
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L37-L39)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L23)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L30-L32)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    selected_value = driver.find_element(name: 'email_input').selected?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L22)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L30-L31)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
 //navigates to url
 driver.get("https://www.selenium.dev/selenium/web/inputs.html")

 //returns true if element is checked else returns false
 val attr =  driver.findElement(By.name("checkbox_input")).isSelected()
```

```java
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L42-L44)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L27)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L35-L37)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    tag_name = driver.find_element(name: 'email_input').tag_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L27)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L37-L38)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//returns TagName of the element
val attr =  driver.findElement(By.name("email_input")).getTagName()
```

```java
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L47-L50)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    rect = driver.find_element(By.NAME, "range_input").rect
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L31)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L40-L43)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    size = driver.find_element(name: 'email_input').size
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L32)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    let object = await driver.findElement(By.name('range_input')).getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L45)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

// Returns height, width, x and y coordinates referenced element
val res = driver.findElement(By.name("range_input")).rect

// Rectangle class provides getX,getY, getWidth, getHeight methods
println(res.getX())
```

```java
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L52-L54)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L35-L37)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L49-L50)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L38)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L76-L78)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to Url
driver.get("https://www.selenium.dev/selenium/web/colorPage.html")

// Retrieves the computed style property 'color' of linktext
val cssValue = driver.findElement(By.id("namedColor")).getCssValue("background-color")
```

```java
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L58-L60)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    text = driver.find_element(By.TAG_NAME, "h1").text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L41)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L53-L55)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    text = driver.find_element(xpath: '//h1').text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L43)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L84-L86)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to URL
driver.get("https://www.selenium.dev/selenium/web/linked_image.html")

// retrieves the text of the element
val text = driver.findElement(By.id("justanotherlink")).getText()
```

```java
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L64-L68)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L44-L46)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L58-L62)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L48)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L55-L59)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to URL
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//fetch the value property associated with the textbox
val attr = driver.findElement(By.name("email_input")).getAttribute("value")
```

Última modificação April 17, 2026: [Update code block references in documentation (#2613) (5d614fcd479)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/5d614fcd479d384003f8e4dd949f6a9f4cada711)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/interactions/windows/
----

# Working with windows and tabs

```java
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L16-L20)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L16-L18)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L17-L21)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
driver.window_handle
```

```javascript
await driver.getWindowHandle();
```

```kotlin
driver.windowHandle
```

```java
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L22-L29)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L22-L32)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L23-L30)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
    #Store the ID of the original window
original_window = driver.window_handle

    #Check we don't have other windows open already
assert(driver.window_handles.length == 1, 'Expected one window')

    #Click the link which opens in a new window
driver.find_element(link: 'new window').click

    #Wait for the new window or tab
wait.until { driver.window_handles.length == 2 }

    #Loop through until we find a new window handle
driver.window_handles.each do |handle|
    if handle != original_window
        driver.switch_to.window handle
        break
    end
end

    #Wait for the new tab to finish loading content
wait.until { driver.title == 'Selenium documentation'}
  
```

```javascript
//Store the ID of the original window
const originalWindow = await driver.getWindowHandle();

//Check we don't have other windows open already
assert((await driver.getAllWindowHandles()).length === 1);

//Click the link which opens in a new window
await driver.findElement(By.linkText('new window')).click();

//Wait for the new window or tab
await driver.wait(
    async () => (await driver.getAllWindowHandles()).length === 2,
    10000
  );

//Loop through until we find a new window handle
const windows = await driver.getAllWindowHandles();
windows.forEach(async handle => {
  if (handle !== originalWindow) {
    await driver.switchTo().window(handle);
  }
});

//Wait for the new tab to finish loading content
await driver.wait(until.titleIs('Selenium documentation'), 10000);
  
```

```kotlin
//Store the ID of the original window
val originalWindow = driver.getWindowHandle()

//Check we don't have other windows open already
assert(driver.getWindowHandles().size() === 1)

//Click the link which opens in a new window
driver.findElement(By.linkText("new window")).click()

//Wait for the new window or tab
wait.until(numberOfWindowsToBe(2))

//Loop through until we find a new window handle
for (windowHandle in driver.getWindowHandles()) {
    if (!originalWindow.contentEquals(windowHandle)) {
        driver.switchTo().window(windowHandle)
        break
    }
}

//Wait for the new tab to finish loading content
wait.until(titleIs("Selenium documentation"))

  
```

```java
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L31-L34)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L46-L46)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L32-L35)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
    #Close the tab or window
driver.close

    #Switch back to the old tab or window
driver.switch_to.window original_window
  
```

```javascript
//Close the tab or window
await driver.close();

//Switch back to the old tab or window
await driver.switchTo().window(originalWindow);
  
```

```kotlin
//Close the tab or window
driver.close()

//Switch back to the old tab or window
driver.switchTo().window(originalWindow)

  
```

```java
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L36-L42)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L53-L58)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L37-L43)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

Opens a new tab and switches to new tab

```rb
    driver.switch_to.new_window(:tab)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/windows_spec.rb#L9)

##### /examples/ruby/spec/interactions/windows\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Windows' do
  let(:driver) { start_session }

  it 'opens new tab' do
    driver.switch_to.new_window(:tab)

    expect(driver.window_handles.size).to eq 2
  end

  it 'opens new window' do
    driver.switch_to.new_window(:window)

    expect(driver.window_handles.size).to eq 2
  end
end
```

Opens a new window and switches to new window

```rb
    driver.switch_to.new_window(:window)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/windows_spec.rb#L15)

##### /examples/ruby/spec/interactions/windows\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Windows' do
  let(:driver) { start_session }

  it 'opens new tab' do
    driver.switch_to.new_window(:tab)

    expect(driver.window_handles.size).to eq 2
  end

  it 'opens new window' do
    driver.switch_to.new_window(:window)

    expect(driver.window_handles.size).to eq 2
  end
end
```

Opens a new tab and switches to new tab

```js
    await driver.switchTo().newWindow('tab');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L70)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

Opens a new window and switches to new window:

```js
    await driver.switchTo().newWindow('window');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L75)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Opens a new tab and switches to new tab
driver.switchTo().newWindow(WindowType.TAB)

// Opens a new window and switches to new window
driver.switchTo().newWindow(WindowType.WINDOW)
  
```

```java
        //quitting driver
        driver.quit(); //close all windows
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L44-L45)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L13-L13)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //quitting driver
              driver.Quit(); //close all windows
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L45-L46)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
driver.quit
```

```javascript
await driver.quit();
```

```kotlin
driver.quit()
```

```java
/**
 * Example using JUnit
 * https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
 */
@AfterAll
public static void tearDown() {
    driver.quit();
}
  
```

```python
    # unittest teardown
    # https://docs.python.org/3/library/unittest.html?highlight=teardown#unittest.TestCase.tearDown
def tearDown(self):
    self.driver.quit()
  
```

```csharp
/*
    Example using Visual Studio's UnitTesting
    https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.aspx
*/
[TestCleanup]
public void TearDown()
{
    driver.Quit();
}
  
```

```ruby
    # UnitTest Teardown
    # https://www.rubydoc.info/github/test-unit/test-unit/Test/Unit/TestCase
def teardown
    @driver.quit
end
  
```

```javascript
/**
 * Example using Mocha
 * https://mochajs.org/#hooks
 */
after('Tear down', async function () {
  await driver.quit();
});
  
```

```kotlin
/**
 * Example using JUnit
 * https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
 */
@AfterAll
fun tearDown() {
    driver.quit()
}
  
```

```java
try {
    //WebDriver code here...
} finally {
    driver.quit();
}
  
```

```python
try:
    #WebDriver code here...
finally:
    driver.quit()
  
```

```csharp
try {
    //WebDriver code here...
} finally {
    driver.Quit();
}
  
```

```ruby
begin
    #WebDriver code here...
ensure
    driver.quit
end
  
```

```javascript
try {
    //WebDriver code here...
} finally {
    await driver.quit();
}
  
```

```kotlin
try {
    //WebDriver code here...
} finally {
    driver.quit()
}
  
```

O WebDriver do Python agora suporta o gerenciador de contexto python, que ao usar a palavra-chave `with` pode encerrar automaticamente o driver no fim da execução.

```python
with webdriver.Firefox() as driver:
  # WebDriver code here...

# WebDriver will automatically quit after indentation
```

```java
//Access each dimension individually
int width = driver.manage().window().getSize().getWidth();
int height = driver.manage().window().getSize().getHeight();

//Or store the dimensions and query them later
Dimension size = driver.manage().window().getSize();
int width1 = size.getWidth();
int height1 = size.getHeight();
  
```

```python
    # Access each dimension individually
width = driver.get_window_size().get("width")
height = driver.get_window_size().get("height")

    # Or store the dimensions and query them later
size = driver.get_window_size()
width1 = size.get("width")
height1 = size.get("height")
  
```

```csharp
//Access each dimension individually
int width = driver.Manage().Window.Size.Width;
int height = driver.Manage().Window.Size.Height;

//Or store the dimensions and query them later
System.Drawing.Size size = driver.Manage().Window.Size;
int width1 = size.Width;
int height1 = size.Height;
  
```

```ruby
    # Access each dimension individually
width = driver.manage.window.size.width
height = driver.manage.window.size.height

    # Or store the dimensions and query them later
size = driver.manage.window.size
width1 = size.width
height1 = size.height
  
```

Access each dimension individually

```js
    const { width, height } = await driver.manage().window().getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L93)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

(or) store the dimensions and query them later

```js
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L96-L98)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
//Access each dimension individually
val width = driver.manage().window().size.width
val height = driver.manage().window().size.height

//Or store the dimensions and query them later
val size = driver.manage().window().size
val width1 = size.width
val height1 = size.height
  
```

```java
driver.manage().window().setSize(new Dimension(1024, 768));
```

```python
driver.set_window_size(1024, 768)
```

```csharp
driver.Manage().Window.Size = new Size(1024, 768);
```

```ruby
driver.manage.window.resize_to(1024,768)
```

```javascript
await driver.manage().window().setRect({ width: 1024, height: 768 });
```

```kotlin
driver.manage().window().size = Dimension(1024, 768)
```

```java
// Access each dimension individually
int x = driver.manage().window().getPosition().getX();
int y = driver.manage().window().getPosition().getY();

// Or store the dimensions and query them later
Point position = driver.manage().window().getPosition();
int x1 = position.getX();
int y1 = position.getY();
  
```

```python
    # Access each dimension individually
x = driver.get_window_position().get('x')
y = driver.get_window_position().get('y')

    # Or store the dimensions and query them later
position = driver.get_window_position()
x1 = position.get('x')
y1 = position.get('y')
  
```

```csharp
//Access each dimension individually
int x = driver.Manage().Window.Position.X;
int y = driver.Manage().Window.Position.Y;

//Or store the dimensions and query them later
Point position = driver.Manage().Window.Position;
int x1 = position.X;
int y1 = position.Y;
  
```

```ruby
    #Access each dimension individually
x = driver.manage.window.position.x
y = driver.manage.window.position.y

    # Or store the dimensions and query them later
rect  = driver.manage.window.rect
x1 = rect.x
y1 = rect.y
  
```

Access each dimension individually

```js
    const { x, y } = await driver.manage().window().getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L108)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

(or) store the dimensions and query them later

```js
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L111-L113)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Access each dimension individually
val x = driver.manage().window().position.x
val y = driver.manage().window().position.y

// Or store the dimensions and query them later
val position = driver.manage().window().position
val x1 = position.x
val y1 = position.y

  
```

```java
// Move the window to the top left of the primary monitor
driver.manage().window().setPosition(new Point(0, 0));
  
```

```python
    # Move the window to the top left of the primary monitor
driver.set_window_position(0, 0)
  
```

```csharp
// Move the window to the top left of the primary monitor
driver.Manage().Window.Position = new Point(0, 0);
  
```

```ruby
driver.manage.window.move_to(0,0)
  
```

```javascript
// Move the window to the top left of the primary monitor
await driver.manage().window().setRect({ x: 0, y: 0 });
  
```

```kotlin
// Move the window to the top left of the primary monitor
driver.manage().window().position = Point(0,0)
    
```

```java
driver.manage().window().maximize();
```

```python
driver.maximize_window()
```

```csharp
driver.Manage().Window.Maximize();
```

```ruby
driver.manage.window.maximize
```

```javascript
await driver.manage().window().maximize();
```

```kotlin
driver.manage().window().maximize()
```

```java
driver.manage().window().minimize();
```

```python
driver.minimize_window()
```

```csharp
driver.Manage().Window.Minimize();
```

```ruby
driver.manage.window.minimize
```

```javascript
await driver.manage().window().minimize();
```

```kotlin
driver.manage().window().minimize()
```

```java
driver.manage().window().fullscreen();
```

```python
driver.fullscreen_window()
```

```csharp
driver.Manage().Window.FullScreen();
```

```ruby
driver.manage.window.full_screen
```

```javascript
await driver.manage().window().fullscreen();
```

```kotlin
driver.manage().window().fullscreen()
```

```java
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.*;
import org.openqa.selenium.*;

public class SeleniumTakeScreenshot {
    public static void main(String args[]) throws IOException {
        WebDriver driver = new ChromeDriver();
        driver.get("http://www.example.com");
        File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(scrFile, new File("./image.png"));
        driver.quit();
    }
}
  
```

```python
from selenium import webdriver

driver = webdriver.Chrome()

    # Navigate to url
driver.get("http://www.example.com")

    # Returns and base64 encoded string into image
driver.save_screenshot('./image.png')

driver.quit()
```

```csharp
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using OpenQA.Selenium.Support.UI;

  var driver = new ChromeDriver();
  driver.Navigate().GoToUrl("http://www.example.com");
  Screenshot screenshot = (driver as ITakesScreenshot).GetScreenshot();
  screenshot.SaveAsFile("screenshot.png", ScreenshotImageFormat.Png); // Format values are Bmp, Gif, Jpeg, Png, Tiff
  
```

```ruby
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://example.com/'

      # Takes and Stores the screenshot in specified path
  driver.save_screenshot('./image.png')

end
  
```

```js
    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L56-L59)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
import com.oracle.tools.packager.IOUtils.copyFile
import org.openqa.selenium.*
import org.openqa.selenium.chrome.ChromeDriver
import java.io.File

fun main(){
    val driver =  ChromeDriver()
    driver.get("https://www.example.com")
    val scrFile = (driver as TakesScreenshot).getScreenshotAs<File>(OutputType.FILE)
    copyFile(scrFile, File("./image.png"))
    driver.quit()
}
   
```

```java
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.File;
import java.io.IOException;

public class SeleniumelementTakeScreenshot {
  public static void main(String args[]) throws IOException {
    WebDriver driver = new ChromeDriver();
    driver.get("https://www.example.com");
    WebElement element = driver.findElement(By.cssSelector("h1"));
    File scrFile = element.getScreenshotAs(OutputType.FILE);
    FileUtils.copyFile(scrFile, new File("./image.png"));
    driver.quit();
  }
}
  
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

    # Navigate to url
driver.get("http://www.example.com")

ele = driver.find_element(By.CSS_SELECTOR, 'h1')

    # Returns and base64 encoded string into image
ele.screenshot('./image.png')

driver.quit()
  
```

```csharp
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;
    using OpenQA.Selenium.Support.UI;

    // Webdriver
    var driver = new ChromeDriver();
    driver.Navigate().GoToUrl("http://www.example.com");

    // Fetch element using FindElement
    var webElement = driver.FindElement(By.CssSelector("h1"));

    // Screenshot for the element
    var elementScreenshot = (webElement as ITakesScreenshot).GetScreenshot();
    elementScreenshot.SaveAsFile("screenshot_of_element.png");
  
```

```ruby
    # Works with Selenium4-alpha7 Ruby bindings and above
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://example.com/'
  ele = driver.find_element(:css, 'h1')

      # Takes and Stores the element screenshot in specified path
  ele.save_screenshot('./image.jpg')
end
  
```

```js
    let header = await driver.findElement(By.css('h1'));
      // Captures the element screenshot
      let encodedString = await header.takeScreenshot(true);
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
  
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L44-L48)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
  const chrome = require('selenium-webdriver/chrome');
  const assert = require("node:assert");
  let opts = new chrome.Options();
  opts.addArguments('--headless');
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let imgMagicNumber = 'iVBOR'
  let base64Code
  
  describe('Interactions - Windows', function () {
    let driver;
    before(async function () {
      driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
    });
  
    after(async () => await driver.quit());
  
    it('Should be able to print page to pdf', async function () {
  
      await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
      let base64 = await driver.printPage({pageRanges: ["1-2"]});
      // page can be saved as a PDF as below
      // await fs.writeFileSync('./test.pdf', base64, 'base64');
  
      base64Code = base64.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, pdfMagicNumber)
    });
  
    it('Should be able to get text using executeScript', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
      // Stores the header element
      let header = await driver.findElement(By.css('h1'));
  
      // Executing JavaScript to capture innerText of header element
      let text = await driver.executeScript('return arguments[0].innerText', header);
      assert.strictEqual(text, `Type Stuff`)
    });
  
    it('Should be able to take Element Screenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      let header = await driver.findElement(By.css('h1'));
      // Captures the element screenshot
      let encodedString = await header.takeScreenshot(true);
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to takeScreenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      // Captures the screenshot
      let encodedString = await driver.takeScreenshot();
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to switch to newWindow and newTab and close', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
      const initialWindow = await driver.getAllWindowHandles();
      assert.strictEqual(initialWindow.length, 1)
  
      // Opens a new tab and switches to new tab
      await driver.switchTo().newWindow('tab');
      const browserTabs = await driver.getAllWindowHandles();
      assert.strictEqual(browserTabs.length, 2)
  
      // Opens a new window and switches to new window
      await driver.switchTo().newWindow('window');
      const windows = await driver.getAllWindowHandles();
      assert.strictEqual(windows.length, 3)
  
      //Close the tab or window
      await driver.close();
  
      //Switch back to the old tab or window
      await driver.switchTo().window(windows[1]);
  
      const windowsAfterClose = await driver.getAllWindowHandles();
      assert.strictEqual(windowsAfterClose.length, 2);
    });
  
    it('Should be able to getWindow Size', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { width, height } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const windowWidth = rect.width;
      const windowHeight = rect.height;
  
      assert.ok(windowWidth>0);
      assert.ok(windowHeight>0);
    });
  
    it('Should be able to getWindow position', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { x, y } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const x1 = rect.x;
      const y1 = rect.y;
  
      assert.ok(x1>=0);
      assert.ok(y1>=0);
    });
  });
```

```kotlin
import org.apache.commons.io.FileUtils
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.*
import java.io.File

fun main() {
    val driver = ChromeDriver()
    driver.get("https://www.example.com")
    val element = driver.findElement(By.cssSelector("h1"))
    val scrFile: File = element.getScreenshotAs(OutputType.FILE)
    FileUtils.copyFile(scrFile, File("./image.png"))
    driver.quit()
}
  
```

```java
    //Creating the JavascriptExecutor interface object by Type casting
      JavascriptExecutor js = (JavascriptExecutor)driver;
    //Button Element
      WebElement button =driver.findElement(By.name("btnLogin"));
    //Executing JavaScript to click on element
      js.executeScript("arguments[0].click();", button);
    //Get return value from script
      String text = (String) js.executeScript("return arguments[0].innerText", button);
    //Executing JavaScript directly
      js.executeScript("console.log('hello world')");
  
```

```python
    # Stores the header element
header = driver.find_element(By.CSS_SELECTOR, "h1")

    # Executing JavaScript to capture innerText of header element
driver.execute_script('return arguments[0].innerText', header)
  
```

```csharp
   //creating Chromedriver instance
	IWebDriver driver = new ChromeDriver();
	//Creating the JavascriptExecutor interface object by Type casting
	IJavaScriptExecutor js = (IJavaScriptExecutor) driver;
	//Button Element
	IWebElement button = driver.FindElement(By.Name("btnLogin"));
	//Executing JavaScript to click on element
	js.ExecuteScript("arguments[0].click();", button);
	//Get return value from script
	String text = (String)js.ExecuteScript("return arguments[0].innerText", button);
	//Executing JavaScript directly
	js.ExecuteScript("console.log('hello world')");
  
```

```ruby
    # Stores the header element
header = driver.find_element(css: 'h1')

    # Get return value from script
result = driver.execute_script("return arguments[0].innerText", header)

    # Executing JavaScript directly
driver.execute_script("alert('hello world')")
  
```

```js
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L33-L37)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Stores the header element
val header = driver.findElement(By.cssSelector("h1"))

// Get return value from script
val result = driver.executeScript("return arguments[0].innerText", header)

// Executing JavaScript directly
driver.executeScript("alert('hello world')")
  
```

```java
    import org.openqa.selenium.print.PrintOptions;

    driver.get("https://www.selenium.dev");
    printer = (PrintsPage) driver;

    PrintOptions printOptions = new PrintOptions();
    printOptions.setPageRanges("1-2");

    Pdf pdf = printer.print(printOptions);
    String content = pdf.getContent();
  
```

```python
    from selenium.webdriver.common.print_page_options import PrintOptions

    print_options = PrintOptions()
    print_options.page_ranges = ['1-2']

    driver.get("printPage.html")

    base64code = driver.print_page(print_options)
  
```

```csharp
    // code sample not available please raise a PR
  
```

```ruby
    driver.navigate_to 'https://www.selenium.dev'

    base64encodedContent = driver.print_page(orientation: 'landscape')
  
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
      let base64 = await driver.printPage({pageRanges: ["1-2"]});
      // page can be saved as a PDF as below
      // await fs.writeFileSync('./test.pdf', base64, 'base64');
  
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L22-L25)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
  const chrome = require('selenium-webdriver/chrome');
  const assert = require("node:assert");
  let opts = new chrome.Options();
  opts.addArguments('--headless');
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let imgMagicNumber = 'iVBOR'
  let base64Code
  
  describe('Interactions - Windows', function () {
    let driver;
    before(async function () {
      driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
    });
  
    after(async () => await driver.quit());
  
    it('Should be able to print page to pdf', async function () {
  
      await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
      let base64 = await driver.printPage({pageRanges: ["1-2"]});
      // page can be saved as a PDF as below
      // await fs.writeFileSync('./test.pdf', base64, 'base64');
  
      base64Code = base64.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, pdfMagicNumber)
    });
  
    it('Should be able to get text using executeScript', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
      // Stores the header element
      let header = await driver.findElement(By.css('h1'));
  
      // Executing JavaScript to capture innerText of header element
      let text = await driver.executeScript('return arguments[0].innerText', header);
      assert.strictEqual(text, `Type Stuff`)
    });
  
    it('Should be able to take Element Screenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      let header = await driver.findElement(By.css('h1'));
      // Captures the element screenshot
      let encodedString = await header.takeScreenshot(true);
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to takeScreenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      // Captures the screenshot
      let encodedString = await driver.takeScreenshot();
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to switch to newWindow and newTab and close', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
      const initialWindow = await driver.getAllWindowHandles();
      assert.strictEqual(initialWindow.length, 1)
  
      // Opens a new tab and switches to new tab
      await driver.switchTo().newWindow('tab');
      const browserTabs = await driver.getAllWindowHandles();
      assert.strictEqual(browserTabs.length, 2)
  
      // Opens a new window and switches to new window
      await driver.switchTo().newWindow('window');
      const windows = await driver.getAllWindowHandles();
      assert.strictEqual(windows.length, 3)
  
      //Close the tab or window
      await driver.close();
  
      //Switch back to the old tab or window
      await driver.switchTo().window(windows[1]);
  
      const windowsAfterClose = await driver.getAllWindowHandles();
      assert.strictEqual(windowsAfterClose.length, 2);
    });
  
    it('Should be able to getWindow Size', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { width, height } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const windowWidth = rect.width;
      const windowHeight = rect.height;
  
      assert.ok(windowWidth>0);
      assert.ok(windowHeight>0);
    });
  
    it('Should be able to getWindow position', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { x, y } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const x1 = rect.x;
      const y1 = rect.y;
  
      assert.ok(x1>=0);
      assert.ok(y1>=0);
    });
  });
```

```kotlin
    driver.get("https://www.selenium.dev")
    val printer = driver as PrintsPage

    val printOptions = PrintOptions()
    printOptions.setPageRanges("1-2")
    
    val pdf: Pdf = printer.print(printOptions)
    val content = pdf.content
  
```

Última modificação May 11, 2026: [Move Python examples in Windows interactions docs (#2629) (d368a9324d6)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/d368a9324d6aa6bb62c016bb5572d28966a7f091)

----
url: https://www.selenium.dev/documentation/about/contributing/
----

# Contributing to the Selenium site & documentation

Information on improving documentation and code examples for Selenium

Selenium is a big software project, its site and documentation are key to understanding how things work and learning effective ways to exploit its potential.

This project contains both Selenium’s site and documentation. This is an ongoing effort (not targeted at any specific release) to provide updated information on how to use Selenium effectively, how to get involved and how to contribute to Selenium.

Contributions toward the site and docs follow the process described in the below section about contributions.

***

```
    {{< tab header="Ruby" >}}
    {{< gh-codeblock path="/examples/ruby/spec/browsers/chrome_spec.rb#L8-L9" >}}
    {{< /tab >}}
```

```shell
% git clone git@github.com:seleniumhq/seleniumhq.github.io.git
% cd seleniumhq.github.io
```

#### Dependencies: Hugo

We use [Hugo](https://gohugo.io/) and the [Docsy theme](https://www.docsy.dev/) to build and render the site. You will need the “extended” Sass/SCSS version of the Hugo binary to work on this site. We recommend to use Hugo 0.148.2 .

Please follow the [Install Hugo](https://www.docsy.dev/docs/getting-started/#install-hugo) instructions from Docsy.

### Step 2: Branch

Create a feature branch and start hacking:

```shell
% git checkout -b my-feature-branch
```

We practice HEAD-based development, which means all changes are applied directly on top of `dev`.

### Step 3: Make changes

The repository contains the site and docs. To make changes to the site, work on the `website_and_docs` directory. To see a live preview of your changes, run `hugo server` on the site’s root directory.

```shell
% cd website_and_docs
% hugo server
```

The project loads code from GitHub, if that code has been updated, and it isn’t reflected in your preview, you can run hugo without the cache: `hugo server --ignoreCache`

See [Style Guide](https://www.selenium.dev/documentation/about/style/) for more information on our conventions for contribution

### Step 4: Commit

First make sure git knows your name and email address:

```shell
% git config --global user.name 'Santa Claus'
% git config --global user.email 'santa@example.com'
```

**Writing good commit messages is important.** A commit message should describe what changed, why, and reference issues fixed (if any). Follow these guidelines when writing one:

1. The first line should be around 50 characters or less and contain a short description of the change.
2. Keep the second line blank.
3. Wrap all other lines at 72 columns.
4. Include `Fixes #N`, where *N* is the issue number the commit fixes, if any.

A good commit message can look like this:

```text
explain commit normatively in one line

Body of commit message is a few lines of text, explaining things
in more detail, possibly giving some background about the issue
being fixed, etc.

The body of the commit message can be several paragraphs, and
please do proper word-wrap and keep columns shorter than about
72 characters or so. That way `git log` will show things
nicely even when it is indented.

Fixes #141
```

The first line must be meaningful as it’s what people see when they run `git shortlog` or `git log --oneline`.

### Step 5: Rebase

Use `git rebase` (not `git merge`) to sync your work from time to time.

```shell
% git fetch origin
% git rebase origin/trunk
```

### Step 6: Test

Always remember to [run the local server](https://gohugo.io/getting-started/usage/#livereload), with this you can be sure that your changes have not broken anything.

### Step 7: Push

```shell
% git push origin my-feature-branch
```

Go to <https://github.com/yourusername/seleniumhq.github.io.git> and press the *Pull Request* and fill out the form. **Please indicate that you’ve signed the CLA** (see Step 7).

Pull requests are usually reviewed within a few days. If there are comments to address, apply your changes in new commits (preferably [fixups](http://git-scm.com/docs/git-commit)) and push to the same branch.

### Step 8: Integration

When code review is complete, a committer will take your PR and integrate it on the repository’s trunk branch. Because we like to keep a linear history on the trunk branch, we will normally squash and rebase your branch history.

## Communication

All details on how to communicate with the project contributors and the community overall can be found at <https://selenium.dev/support>

Last modified November 4, 2025: [added information about web examples for english document (#2492) (4dc5f22359d)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/4dc5f22359dfceb83b43afb473ca2ef7882abd19)

----
url: https://www.selenium.dev/ja/documentation/webdriver/bidi/w3c/script/
----

# Script

```java
        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));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L52-L75)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L32-L53)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L201-L210)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L202-L204)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L219-L229)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L222-L227)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L239-L242)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L237-L239)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L280-L283)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L279-L283)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L293-L299)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L292-L299)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            script.disownBrowsingContextScript(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L322-L322)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    await manager.disownBrowsingContextScript(id, boxId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L330-L330)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            script.disownRealmScript(realmId, List.of(boxId));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L375-L375)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    await manager.disownRealmScript(realmId, boxId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L372-L372)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L391-L392)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L383-L385)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L401-402)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L393-L395)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L411-412)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L403-L405)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L422-423)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L416-L416)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L463-463)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L424-L426)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
                script.removePreloadScript(id);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L486-486)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    await manager.removePreloadScript(scriptId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L471-L471)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L37-L51)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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,
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L26-L43)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L58-L68)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L52-L65)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L75-L85)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.19](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.19.0)

```js
    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()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L73-L86)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

[Add Example](/documentation/about/contributing/#creating-examples)

----
url: https://www.selenium.dev/pt-br/documentation/legacy/selenium_1/
----

# Selenium RC (Selenium 1)

```shell
    java -jar selenium-server-standalone-<version-number>.jar
```

Isso pode ser simplificado criando um arquivo executável em lote ou shell (.bat no Windows e .sh no Linux) contendo o comando acima. Em seguida, faça um atalho para esse executável em seu desktop e simplesmente clique duas vezes no ícone para iniciar o servidor.

Para o servidor funcionar, você precisa do Java instalado e a variável de ambiente PATH configurada corretamente para executá-lo a partir do console. Você pode verificar se o Java está instalado corretamente executando o seguinte em um console.

```shell
       java -version
```

|                   |                            |             |
| ----------------- | -------------------------- | ----------- |
| open              | /                          |             |
| type              | q                          | selenium rc |
| clickAndWait      | btnG                       |             |
| assertTextPresent | Results \* for selenium rc |             |

Observação: este exemplo funcionaria com a página de pesquisa do Google <http://www.google.com>

### Selenese como código

Aqui está o script de teste exportado (via Selenium-IDE) para cada uma das linguagens de programação. Se você tem pelo menos conhecimento básico de linguagem de programação orientada a objetos (OOP), você vai entender como o Selenium executa comandos em Selenese lendo um destes exemplos. Para ver um exemplo em uma linguagem específica, selecione um desses botões.

#### CSharp

```csharp

        using System;
        using System.Text;
        using System.Text.RegularExpressions;
        using System.Threading;
        using NUnit.Framework;
        using Selenium;

        namespace SeleniumTests
        {
            [TestFixture]
            public class NewTest
            {
                private ISelenium selenium;
                private StringBuilder verificationErrors;
                
                [SetUp]
                public void SetupTest()
                {
                    selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
                    selenium.Start();
                    verificationErrors = new StringBuilder();
                }
                
                [TearDown]
                public void TeardownTest()
                {
                    try
                    {
                        selenium.Stop();
                    }
                    catch (Exception)
                    {
                        // Ignore errors if unable to close the browser
                    }
                    Assert.AreEqual("", verificationErrors.ToString());
                }
                
                [Test]
                public void TheNewTest()
                {
                    selenium.Open("/");
                    selenium.Type("q", "selenium rc");
                    selenium.Click("btnG");
                    selenium.WaitForPageToLoad("30000");
                    Assert.AreEqual("selenium rc - Google Search", selenium.GetTitle());
                }
            }
        }
```

#### Java

```java
      
	  /** Add JUnit framework to your classpath if not already there 
	   *  for this example to work
	  */
      package com.example.tests;

      import com.thoughtworks.selenium.*;
      import java.util.regex.Pattern;

      public class NewTest extends SeleneseTestCase {
          public void setUp() throws Exception {
              setUp("http://www.google.com/", "*firefox");
          }
            public void testNew() throws Exception {
                selenium.open("/");
                selenium.type("q", "selenium rc");
                selenium.click("btnG");
                selenium.waitForPageToLoad("30000");
                assertTrue(selenium.isTextPresent("Results * for selenium rc"));
          }
      }
```

#### Php

```php
      <?php

      require_once 'PHPUnit/Extensions/SeleniumTestCase.php';

      class Example extends PHPUnit_Extensions_SeleniumTestCase
      {
        function setUp()
        {
          $this->setBrowser("*firefox");
          $this->setBrowserUrl("http://www.google.com/");
        }

        function testMyTestCase()
        {
          $this->open("/");
          $this->type("q", "selenium rc");
          $this->click("btnG");
          $this->waitForPageToLoad("30000");
          $this->assertTrue($this->isTextPresent("Results * for selenium rc"));
        }
      }
      ?>
```

#### Python

```python

     from selenium import selenium
      import unittest, time, re

      class NewTest(unittest.TestCase):
          def setUp(self):
              self.verificationErrors = []
              self.selenium = selenium("localhost", 4444, "*firefox",
                      "http://www.google.com/")
              self.selenium.start()
         
          def test_new(self):
              sel = self.selenium
              sel.open("/")
              sel.type("q", "selenium rc")
              sel.click("btnG")
              sel.wait_for_page_to_load("30000")
              self.failUnless(sel.is_text_present("Results * for selenium rc"))
         
          def tearDown(self):
              self.selenium.stop()
              self.assertEqual([], self.verificationErrors)
```

#### Ruby

```ruby

      require "selenium/client"
      require "test/unit"

      class NewTest < Test::Unit::TestCase
        def setup
          @verification_errors = []
          if $selenium
            @selenium = $selenium
          else
            @selenium =  Selenium::Client::Driver.new("localhost", 4444, "*firefox", "http://www.google.com/", 60);
            @selenium.start
          end
          @selenium.set_context("test_new")
        end

        def teardown
          @selenium.stop unless $selenium
          assert_equal [], @verification_errors
        end

        def test_new
          @selenium.open "/"
          @selenium.type "q", "selenium rc"
          @selenium.click "btnG"
          @selenium.wait_for_page_to_load "30000"
          assert @selenium.is_text_present("Results * for selenium rc")
        end
      end
```

```java
    selenium = new DefaultSelenium("localhost", 4444, "*iehta", "http://www.google.com/");
```

O código gerado pela Selenium-IDE terá a seguinte aparência. Este exemplo tem comentários adicionados manualmente para maior clareza.

```java
   package com.example.tests;
   // We specify the package of our tests

   import com.thoughtworks.selenium.*;
   // This is the driver's import. You'll use this for instantiating a
   // browser and making it do what you need.

   import java.util.regex.Pattern;
   // Selenium-IDE add the Pattern module because it's sometimes used for 
   // regex validations. You can remove the module if it's not used in your 
   // script.

   public class NewTest extends SeleneseTestCase {
   // We create our Selenium test case

         public void setUp() throws Exception {
           setUp("http://www.google.com/", "*firefox");
                // We instantiate and start the browser
         }

         public void testNew() throws Exception {
              selenium.open("/");
              selenium.type("q", "selenium rc");
              selenium.click("btnG");
              selenium.waitForPageToLoad("30000");
              assertTrue(selenium.isTextPresent("Results * for selenium rc"));
              // These are the real test steps
        }
   }
```

### `C#`

O driver do cliente .NET funciona com o Microsoft.NET. Pode ser usado com qualquer framework de teste .NET como o NUnit ou o Visual Studio 2005 Team System.

Selenium-IDE assume que você usará NUnit como sua estrutura de teste. Você pode ver isso no código gerado abaixo. Inclui a declaração *using* para NUnit junto com os atributos NUnit correspondentes que identificam o papel de cada função-membro da classe de teste.

Você provavelmente terá que renomear a classe de teste de “NewTest” para algo de sua própria escolha. Além disso, você precisará alterar os parâmetros abertos pelo navegador na declaração

```csharp
    selenium = new DefaultSelenium("localhost", 4444, "*iehta", "http://www.google.com/");
```

O código gerado será semelhante a este.

```csharp

    using System;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading;
    using NUnit.Framework;
    using Selenium;
    
    namespace SeleniumTests

    {
        [TestFixture]

        public class NewTest

        {
        private ISelenium selenium;

        private StringBuilder verificationErrors;

        [SetUp]

        public void SetupTest()

        {
            selenium = new DefaultSelenium("localhost", 4444, "*iehta",
            "http://www.google.com/");

            selenium.Start();

            verificationErrors = new StringBuilder();
        }

        [TearDown]

        public void TeardownTest()
        {
            try
            {
            selenium.Stop();
            }

            catch (Exception)
            {
            // Ignore errors if unable to close the browser
            }

            Assert.AreEqual("", verificationErrors.ToString());
        }
        [Test]

        public void TheNewTest()
        {
            // Open Google search engine.        
            selenium.Open("http://www.google.com/"); 
            
            // Assert Title of page.
            Assert.AreEqual("Google", selenium.GetTitle());
            
            // Provide search term as "Selenium OpenQA"
            selenium.Type("q", "Selenium OpenQA");
            
            // Read the keyed search term and assert it.
            Assert.AreEqual("Selenium OpenQA", selenium.GetValue("q"));
            
            // Click on Search button.
            selenium.Click("btnG");
            
            // Wait for page to load.
            selenium.WaitForPageToLoad("5000");
            
            // Assert that "www.openqa.org" is available in search results.
            Assert.IsTrue(selenium.IsTextPresent("www.openqa.org"));
            
            // Assert that page title is - "Selenium OpenQA - Google Search"
            Assert.AreEqual("Selenium OpenQA - Google Search", 
                         selenium.GetTitle());
        }
        }
    }
```

Você pode permitir que o NUnit gerencie a execução de seus testes. Ou, alternativamente, você pode escrever um programa `main()` simples que instancia o objeto de teste e executa cada um dos três métodos, `SetupTest()`, `TheNewTest()` e `TeardownTest()` por sua vez.

### Python

Pyunit é a estrutura de teste a ser usada para Python.

A estrutura básica do teste é:

```python

   from selenium import selenium
   # This is the driver's import.  You'll use this class for instantiating a
   # browser and making it do what you need.

   import unittest, time, re
   # This are the basic imports added by Selenium-IDE by default.
   # You can remove the modules if they are not used in your script.

   class NewTest(unittest.TestCase):
   # We create our unittest test case

       def setUp(self):
           self.verificationErrors = []
           # This is an empty array where we will store any verification errors
           # we find in our tests

           self.selenium = selenium("localhost", 4444, "*firefox",
                   "http://www.google.com/")
           self.selenium.start()
           # We instantiate and start the browser

       def test_new(self):
           # This is the test code.  Here you should put the actions you need
           # the browser to do during your test.
            
           sel = self.selenium
           # We assign the browser to the variable "sel" (just to save us from 
           # typing "self.selenium" each time we want to call the browser).
            
           sel.open("/")
           sel.type("q", "selenium rc")
           sel.click("btnG")
           sel.wait_for_page_to_load("30000")
           self.failUnless(sel.is_text_present("Results * for selenium rc"))
           # These are the real test steps

       def tearDown(self):
           self.selenium.stop()
           # we close the browser (I'd recommend you to comment this line while
           # you are creating and debugging your tests)

           self.assertEqual([], self.verificationErrors)
           # And make the test fail if we found that any verification errors
           # were found
```

### Ruby

Versões antigas (pré 2.0) da Selenium-IDE geram código Ruby que requer o *gem* antigo do Selenium. Portanto, é aconselhável atualizar todos os scripts Ruby gerados pela IDE da seguinte forma:

1. Na linha 1, altere `require "selenium"` para `require "selenium/client"`

2. Na linha 11, altere `Selenium::SeleniumDriver.new` para `Selenium::Client::Driver.new`

Você provavelmente também deseja alterar o nome da classe para algo mais informativo do que “Untitled” e alterar o nome do método de teste para algo diferente de “test\_untitled.”

Aqui está um exemplo simples criado pela modificação do código Ruby gerado pela Selenium IDE, conforme descrito acima.

```ruby

   # load the Selenium-Client gem
   require "selenium/client"

   # Load Test::Unit, Ruby's default test framework.
   # If you prefer RSpec, see the examples in the Selenium-Client
   # documentation.
   require "test/unit"

   class Untitled < Test::Unit::TestCase

     # The setup method is called before each test.
     def setup

       # This array is used to capture errors and display them at the
       # end of the test run.
       @verification_errors = []

       # Create a new instance of the Selenium-Client driver.
       @selenium = Selenium::Client::Driver.new \
         :host => "localhost",
         :port => 4444,
         :browser => "*chrome",
         :url => "http://www.google.com/",
         :timeout_in_second => 60

       # Start the browser session
       @selenium.start

       # Print a message in the browser-side log and status bar
       # (optional).
       @selenium.set_context("test_untitled")

     end

     # The teardown method is called after each test.
     def teardown

       # Stop the browser session.
       @selenium.stop

       # Print the array of error messages, if any.
       assert_equal [], @verification_errors
     end

     # This is the main body of your test.
     def test_untitled
     
       # Open the root of the site we specified when we created the
       # new driver instance, above.
       @selenium.open "/"

       # Type 'selenium rc' into the field named 'q'
       @selenium.type "q", "selenium rc"

       # Click the button named "btnG"
       @selenium.click "btnG"

       # Wait for the search results page to load.
       # Note that we don't need to set a timeout here, because that
       # was specified when we created the new driver instance, above.
       @selenium.wait_for_page_to_load

       begin

          # Test whether the search results contain the expected text.
	  # Notice that the star (*) is a wildcard that matches any
	  # number of characters.
	  assert @selenium.is_text_present("Results * for selenium rc")
	  
       rescue Test::Unit::AssertionFailedError
       
          # If the assertion fails, push it onto the array of errors.
	  @verification_errors << $!

       end
     end
   end
```

### Perl, PHP

Os membros da equipe de documentação não usaram Selenium RC com Perl ou PHP. Se você estiver usando Selenium RC com qualquer um desses dois idiomas, entre em contato com a Equipe de Documentação (consulte o capítulo sobre Contribuições). Gostaríamos muito de incluir alguns exemplos seus e de suas experiências, para oferecer suporte a usuários Perl e PHP.

## Aprendendo a API

A API Selenium RC usa convenções de nomenclatura que, supondo que você entenda Selenese, será em grande parte autoexplicativo. Aqui, no entanto, explicamos os aspectos mais críticos e possivelmente menos óbvios.

### Iniciando o navegador

#### CSharp

```csharp
      selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
      selenium.Start();
```

#### Java

```java

      setUp("http://www.google.com/", "*firefox");
```

#### Perl

```perl
      my $sel = Test::WWW::Selenium->new( host => "localhost", 
                                          port => 4444, 
                                          browser => "*firefox", 
                                          browser_url => "http://www.google.com/" );
```

#### Php

```php
      $this->setBrowser("*firefox");
      $this->setBrowserUrl("http://www.google.com/");
```

#### Python

```python
      self.selenium = selenium("localhost", 4444, "*firefox",
                               "http://www.google.com/")
      self.selenium.start()
```

#### Ruby

```ruby
      @selenium = Selenium::ClientDriver.new("localhost", 4444, "*firefox", "http://www.google.com/", 10000);
      @selenium.start
```

```
    selenium.type("field-id", "string to type")
```

|                   |                              |               |
| ----------------- | ---------------------------- | ------------- |
| open              | /                            |               |
| type              | q                            | selenium rc   |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium rc   |               |
| type              | q                            | selenium ide  |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium ide  |               |
| type              | q                            | selenium grid |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium grid |               |

O código foi repetido para executar as mesmas etapas 3 vezes. Mas ter múltiplas cópias do mesmo código não é uma boa prática de programação porque é mais trabalhoso para manter. Usando uma linguagem de programação, podemos iterar sobre os resultados da pesquisa para uma solução mais flexível e sustentável.

#### In `C#`

```csharp
   // Collection of String values.
   String[] arr = {"ide", "rc", "grid"};    
        
   // Execute loop for each String in array 'arr'.
   foreach (String s in arr) {
       sel.open("/");
       sel.type("q", "selenium " +s);
       sel.click("btnG");
       sel.waitForPageToLoad("30000");
       assertTrue("Expected text: " +s+ " is missing on page."
       , sel.isTextPresent("Results * for selenium " + s));
    }
```

### Declarações de condição

Para ilustrar o uso de condições em testes, começaremos com um exemplo. Um problema comum encontrado durante a execução de testes Selenium ocorre quando o elemento esperado não está disponível na página. Por exemplo, ao executar a seguinte linha:

```
   selenium.type("q", "selenium " +s);
```

Se o elemento ‘q’ não estiver na página, então uma exceção é lançada:

```java
   com.thoughtworks.selenium.SeleniumException: ERROR: Element q not found
```

Isso pode fazer com que seu teste seja interrompido. Para alguns testes, é isso que você deseja. Mas frequentemente isso não é desejável, pois seu script de teste tem muitos outros testes subsequentes para realizar.

Uma abordagem melhor é primeiro validar se o elemento está realmente presente e então escolher alternativas quando não estiver. Vejamos isso usando Java.

```java
   // If element is available on page then perform type operation.
   if(selenium.isElementPresent("q")) {
       selenium.type("q", "Selenium rc");
   } else {
       System.out.printf("Element: " +q+ " is not available on page.")
   }
```

A vantagem desta abordagem é continuar com a execução do teste, mesmo se alguns elementos de IU não estão disponíveis na página.

### Executando JavaScript a partir do seu teste

JavaScript é muito útil para exercitar uma aplicação que não é diretamente suportada por Selenium. O método **getEval** da API Selenium pode ser usado para executar JavaScript a partir de Selenium RC.

Considere um aplicativo com caixas de seleção sem identificadores estáticos. Neste caso, pode-se avaliar o JavaScript do Selenium RC para obter ids de todas caixas de seleção e, em seguida, exercitá-las.

```java
   public static String[] getAllCheckboxIds () { 
		String script = "var inputId  = new Array();";// Create array in java script.
		script += "var cnt = 0;"; // Counter for check box ids.  
		script += "var inputFields  = new Array();"; // Create array in java script.
		script += "inputFields = window.document.getElementsByTagName('input');"; // Collect input elements.
		script += "for(var i=0; i<inputFields.length; i++) {"; // Loop through the collected elements.
		script += "if(inputFields[i].id !=null " +
		"&& inputFields[i].id !='undefined' " +
		"&& inputFields[i].getAttribute('type') == 'checkbox') {"; // If input field is of type check box and input id is not null.
		script += "inputId[cnt]=inputFields[i].id ;" + // Save check box id to inputId array.
		"cnt++;" + // increment the counter.
		"}" + // end of if.
		"}"; // end of for.
		script += "inputId.toString();" ;// Convert array in to string.			
		String[] checkboxIds = selenium.getEval(script).split(","); // Split the string.
		return checkboxIds;
    }
```

Para contar as imagens em uma página

```java
   selenium.getEval("window.document.images.length;");
```

Lembre-se de usar o objeto window no caso de expressões DOM já que por padrão a janela Selenium é referida, não a janela de teste.

## Opções do servidor

Quando o servidor é iniciado, as opções de linha de comando podem ser usadas para alterar o comportamento padrão do servidor.

Lembre-se de que o servidor é iniciado executando o seguinte.

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar
```

Para ver a lista de opções, execute o servidor com a opção `-h`.

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar -h
```

Você verá uma lista de todas as opções que pode usar com o servidor e uma breve descrição de cada. As descrições fornecidas nem sempre serão suficientes, então fornecemos explicações para algumas das opções mais importantes.

### Configuração do Proxy

Se o seu aplicação estiver atrás de um proxy HTTP que requer autenticação, você deve configurar http.proxyHost, http.proxyPort, http.proxyUser e http.proxyPassword usando o seguinte comando.

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar -Dhttp.proxyHost=proxy.com -Dhttp.proxyPort=8080 -Dhttp.proxyUser=username -Dhttp.proxyPassword=password
```

### Modo multi-janela

Se você estiver usando Selenium 1.0, você provavelmente pode pular esta seção, uma vez que o modo multijanela é o comportamento padrão. No entanto, antes da versão 1.0, o Selenium executava por padrão o aplicativo em teste em um subquadro, conforme mostrado aqui.

Alguns aplicativos não funcionavam corretamente em um subquadro e precisavam ser carregados no quadro superior da janela. A opção de modo multi-janela permitida a aplicação testada ser executada em uma janela separada, em vez do quadro padrão onde poderia então ter o quadro superior necessário.

Para versões mais antigas do Selenium você deve especificar o modo multijanela explicitamente com a seguinte opção:

```bash
   -multiwindow 
```

A partir do Selenium RC 1.0, se você deseja executar seu teste dentro de um quadro único (ou seja, usando o padrão para versões anteriores do Selenium) você pode declarar isso ao servidor Selenium usando a opção

```bash
   -singlewindow 
```

### Especificando o perfil do Firefox

O Firefox não executará duas instâncias simultaneamente, a menos que você especifique um perfil separado para cada instância. Selenium RC 1.0 e posterior é executado em um perfil separado automaticamente, então se você estiver usando Selenium 1.0, você pode provavelmente pular esta seção. No entanto, se você estiver usando uma versão mais antiga do Selenium ou se você precisar usar um perfil específico para seus testes (como adicionar um certificado https ou ter alguns complementos instalados), você precisa especificar explicitamente o perfil.

Primeiro, para criar um perfil separado do Firefox, siga este procedimento. Abra o menu Iniciar do Windows, selecione “Executar”, digite e entre um dos seguintes:

```bash
   firefox.exe -profilemanager 
```

```bash
   firefox.exe -P 
```

Crie o novo perfil usando a caixa de diálogo. Então, quando você executar o Selenium Server, diga a ele para usar este novo perfil do Firefox com a opção de linha de comando do servidor *-firefoxProfileTemplate* e especifique o caminho para o perfil usando seu nome de arquivo e o caminho do diretório.

```bash
   -firefoxProfileTemplate "path to the profile" 
```

**Aviso**: certifique-se de colocar seu perfil em uma nova pasta separada da padrão!!! A ferramenta gerenciadora de perfil do Firefox irá deletar todos os arquivos em uma pasta se você excluir um perfil, independentemente de serem arquivos de perfil ou não.

Mais informações sobre os perfis do Firefox podem ser encontradas em [Mozilla’s Knowledge Base](http://support.mozilla.com/en/kb/Managing+profiles)

### Execute Selenese diretamente dentro do servidor usando -htmlSuite

Você pode executar arquivos Selenese html diretamente no servidor Selenium passando o arquivo html para a linha de comando do servidor. Por exemplo:

```bash
   java -jar selenium-server-standalone-<version-number>.jar -htmlSuite "*firefox" 
   "http://www.google.com" "c:\absolute\path\to\my\HTMLSuite.html" 
   "c:\absolute\path\to\my\results.html"
```

Isso iniciará automaticamente seu pacote HTML, executará todos os testes e salvará um bom relatório HTML com os resultados.

*Nota:* ao usar esta opção, o servidor irá iniciar os testes e aguardar um número especificado de segundos para o teste ser concluído; se o teste não completar dentro desse período de tempo, o comando sairá com um código de saída diferente de zero e nenhum arquivo de resultados será gerado.

Esta linha de comando é muito longa, então tome cuidado com o que você digita. Observe que isso requer que você passe uma suíte de arquivos HTML Selenese, não um único teste. Também esteja ciente de que a opção -htmlSuite é incompatível com `-interactive`. Você não pode executar os dois ao mesmo tempo.

### Logging do servidor Selenium

#### logs do lado do servidor

Ao iniciar o servidor Selenium, a opção **-log** pode ser usada para gravar informações valiosas de depuração relatadas pelo servidor Selenium em um arquivo de texto.

```bash
   java -jar selenium-server-standalone-<version-number>.jar -log selenium.log
```

Este arquivo de log é mais detalhado do que os logs do console padrão (inclui mensagens de registro de nível DEBUG ). O arquivo de log também inclui o nome do registrador e o número do thread que registrou a mensagem. Por exemplo:

```bash
   20:44:25 DEBUG [12] org.openqa.selenium.server.SeleniumDriverResourceHandler - 
   Browser 465828/:top frame1 posted START NEW
```

O formato da mensagem é

```bash
   TIMESTAMP(HH:mm:ss) LEVEL [THREAD] LOGGER - MESSAGE
```

Esta mensagens pode ter múltiplas linhas.

#### Logs do lado do navegador

O JavaScript no lado do navegador (Selenium Core) também registra mensagens importantes; em muitos casos, eles podem ser mais úteis para o usuário final do que os Logs normais do servidor. Para acessar os registros do lado do navegador, passe o argumento **-browserSideLog** para o servidor Selenium.

```bash
   java -jar selenium-server-standalone-<version-number>.jar -browserSideLog
```

**-browserSideLog** deve ser combinado com o argumento **-log**, para registrar browserSideLogs (bem como todas as outras mensagens de log de nível DEBUG) em um arquivo.

## Especificando o caminho para um navegador específico

Você pode especificar para o Selenium RC o caminho para um navegador. Isto é útil se você possui diferentes versões do mesmo navegador e você deseja usar uma em específico. Isto também pode ser usado para executar seus testes em um navegador que não é suportado diretamente pelo Selenium RC. Quando especificar o modo de execução, use o especificador \*custom seguido do caminho completo para o executável do navegador.

```bash
   *custom <path to browser> 
```

```bash
   cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\MyBrowser.exe&2=http://www.google.com
```

### Executando testes com diferentes configurações de navegador

Normalmente o Selenium RC configura automaticamente o navegador, mas se você iniciar o navegador usando o modo de execução “\*custom”, você pode forçar o Selenium RC a iniciar o navegador como está, sem usar uma configuração automática.

Por exemplo, você pode iniciar o Firefox com uma configuração personalizada como esta:

```bash
   cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\firefox.exe&2=http://www.google.com
```

Observe que ao iniciar o navegador desta forma, você deve manualmente configurar o navegador para usar o servidor Selenium como proxy. Normalmente, isso apenas significa abrir as preferências do navegador e especificar “localhost: 4444” como um proxy HTTP, mas as instruções para isso podem diferir radicalmente de navegador para navegador. Consulte a documentação do seu navegador para obter detalhes.

Esteja ciente de que os navegadores Mozilla podem variar em como eles iniciam e param. Pode ser necessário definir a variável de ambiente MOZ\_NO\_REMOTE para fazer com que os navegadores Mozilla se comportem de maneira mais previsível. Os usuários Unix devem evitar iniciar o navegador usando um script de shell; geralmente é melhor usar o executável binário (por exemplo, firefox-bin) diretamente.

## Resolução de problemas comuns

Ao começar a usar o Selenium RC, há alguns problemas potenciais que são comumente encontrados. Nós os apresentamos junto com suas soluções aqui.

### Incapaz de conectar ao servidor

Quando seu programa de teste não pode se conectar ao servidor Selenium, o Selenium lança uma exceção em seu programa de teste. Ele deve exibir esta mensagem ou outra semelhante:

```bash
    "Unable to connect to remote server (Inner Exception Message: 
	No connection could be made because the target machine actively 
	refused it )"
    
	(using .NET and XP Service Pack 2) 
```

Se você vir uma mensagem como esta, certifique-se de iniciar o servidor Selenium. E se então, há um problema com a conectividade entre a biblioteca cliente Selenium e o servidor Selenium.

Ao começar com Selenium RC, a maioria das pessoas começa executando seu programa de teste (com uma biblioteca de cliente Selenium) e o servidor Selenium na mesma máquina. Para fazer isso use “localhost” como parâmetro de conexão. Recomendamos começar dessa forma, pois reduz a influência de possíveis problemas de rede que você está começando. Supondo que seu sistema operacional tenha uma rede típica e configurações TCP/IP, você deve ter pouca dificuldade. Na verdade, muitas pessoas optam por executar os testes desta forma.

Se, no entanto, você deseja executar o Selenium Server em uma máquina remota, a conectividade deve ser boa, supondo que você tenha uma conexão TCP/IP válida entre as duas máquinas.

Se tiver dificuldade para se conectar, você pode usar ferramentas de rede comuns como *ping*, *telnet*, *ifconfig (Unix) / ipconfig* (Windows), etc para garantir que você tenha uma conexão de rede. Se não estiver familiarizado com eles, o administrador do sistema pode ajudá-lo.

### Incapaz de carregar o navegador

Ok, não é uma mensagem de erro amigável, desculpe, mas se o servidor Selenium não pode carregar o navegador você provavelmente verá este erro.

```bash
    (500) Internal Server Error
```

```bash
    Error:  java.lang.RuntimeException: Firefox refused shutdown while 
    preparing a profile 
```

Esta é a mensagem de erro completa do servidor:

```bash
    16:20:03.919 INFO - Preparing Firefox profile... 
    16:20:27.822 WARN - GET /selenium-server/driver/?cmd=getNewBrowserSession&1=*fir 
    efox&2=http%3a%2f%2fsage-webapp1.qa.idc.com HTTP/1.1 
    java.lang.RuntimeException: Firefox refused shutdown while preparing a profile 
            at org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLaunc 
    her.waitForFullProfileToBeCreated(FirefoxCustomProfileLauncher.java:277) 
    ... 
    Caused by: org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLaunc 
    her$FileLockRemainedException: Lock file still present! C:\DOCUME~1\jsvec\LOCALS 
    ~1\Temp\customProfileDir203138\parent.lock 
```

Para resolver isso, consulte a seção Especificando um perfil separado do Firefox

### Problemas de versionamento

Certifique-se de que sua versão do Selenium é compatível com a versão do seu navegador. Por exemplo, Selenium RC 0.92 não suporta Firefox 3. Às vezes você pode ter sorte (eu tive). Mas não se esqueça de verificar quais versões do navegador são compatíveis com a versão do Selenium que você está usando. Quando em dúvida, use a versão mais recente do Selenium com a versão mais usada do seu navegador.

### Mensagem de erro: “(Unsupported major.minor version 49.0)” ao inicializar o servidor

Este erro diz que você não está usando uma versão correta do Java. O Selenium Server requer Java 1.5 ou superior.

Para verificar novamente sua versão java, execute na linha de comando:

```bash
   java -version
```

Você deve ver uma mensagem mostrando a versão do Java.

```bash
   java version "1.5.0_07"
   Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03)
   Java HotSpot(TM) Client VM (build 1.5.0_07-b03, mixed mode)
```

```bash
   cmd=getNewBrowserSession&1=*firefox /usr/local/firefox/firefox-bin&2=http://www.google.com
```

```bash
   /usr/lib/firefox-x.x.x/ 
```

Onde x.x.x é o número da versão que você possui atualmente. Então, para adicionar esse caminho no *path* do usuário. você terá que adicionar o seguinte ao seu arquivo .bashrc:

```bash
   export PATH="$PATH:/usr/lib/firefox-x.x.x/"
```

Se necessário, você pode especificar o caminho para o firefox-bin diretamente em seu teste, assim:

```bash
   "*firefox /usr/lib/firefox-x.x.x/firefox-bin"
```

### IE e atributos de estilo

Se você estiver executando seus testes no Internet Explorer e não conseguir localizar elementos usando seu atributo `style`. Por exemplo:

```bash
    //td[@style="background-color:yellow"]
```

Isso funcionaria perfeitamente no Firefox, Opera ou Safari, mas não com o IE. O IE interpreta as chaves em `@style` como maiúsculas. Então, mesmo que o o código-fonte está em letras minúsculas, você deve usar:

```bash
    //td[@style="BACKGROUND-COLOR:yellow"]
```

Isso é um problema se o seu teste se destina a funcionar em vários navegadores, mas você pode facilmente codificar seu teste para detectar a situação e tentar o localizador alternativo que só funciona no IE.

### Erro encontrado - “Cannot convert object to primitive value” no delsigamento do navegador \*googlechrome

Para evitar esse erro, você deve iniciar o navegador com uma opção que desativa as verificações da política de mesma origem:

```bash
   selenium.start("commandLineFlags=--disable-web-security");
```

### Erro encontrado no IE - “Couldn’t open app window; is the pop-up blocker enabled?”

Para evitar esse erro, você deve configurar o navegador: desative o bloqueador de pop-ups e desmarque a opção ‘Ativar modo protegido’ em Ferramentas » Opções » Segurança.

***

1. O proxy é uma terceira pessoa no meio que passa a bola entre as duas partes. Ele atua como um “servidor da web” que entrega a aplicação ao navegador. Ser um proxy dá ao Selenium Server a capacidade de “mentir” sobre a URL real da aplicação. [↩︎](#fnref:1)

2. O navegador é iniciado com um perfil de configuração que definiu localhost:4444 como o proxy HTTP, é por isso que qualquer solicitação HTTP que o navegador fizer passará pelo servidor Selenium e a resposta passará por ele e não pelo servidor real. [↩︎](#fnref:2)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/browsers/edge/
----

# Edge 特定功能

这些是特定于微软Edge浏览器的功能和特性.

微软Edge是用Chromium实现的, 最早支持版本是v79. 与Chrome类似, Edge驱动的主版本号必须与Edge浏览器的主要版本匹配.

在 [Chrome 页面](https://www.selenium.dev/zh-cn/documentation/webdriver/browsers/chrome/) 上找到的所有capabilities和选项也适用于Edge.

## 选项

所有浏览器的共有功能在 [Options 页面](https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/options/).

Chromium独有的功能记录在谷歌的 [Capabilities & ChromeOptions](https://chromedriver.chromium.org/capabilities)

使用基本定义的选项启动 Edge 会话如下所示:

*
*
*
*
*
*

```java

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L38-L39)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options = get_default_edge_options()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L9-L10)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        {
            var options = new EdgeOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L30-L31)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let options = new edge.Options();
    driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/openEdgeTest.spec.js#L11-L15)

##### /examples/javascript/test/getting\_started/openEdgeTest.spec.js

```js
const {Browser, Builder} = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');


describe('Open Edge', function () {
  let driver;



  before(async function () {
    let options = new edge.Options();
    driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options)
      .build();
  });

  after(async () => await driver.quit());

  it('Basic Edge test', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

### 参数

`args` 参数用于列出启动浏览器时使用的命令行开关. 有两个很好的资源可用于研究这些参数:

* [Chrome Flags for Tooling](https://github.com/GoogleChrome/chrome-launcher/blob/main/docs/chrome-flags-for-tools.md)
* [List of Chromium Command Line Switches](https://peter.sh/experiments/chromium-command-line-switches/)

常用参数包括 `--start-maximized` 、 `--headless=new` 和 `--user-data-dir=...`

为options添加参数:

*
*
*
*
*
*

```java
  public void arguments() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L46)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L18)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L39)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.args << '--start-maximized'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L17)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.addArguments('--headless=new'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L12)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

### 在指定位置启动浏览器

`binary` 参数包含要使用的浏览器备用位置的路径. 使用此参数, 您可以使用 chromedriver 驱动各种基于 Chromium 的浏览器.

在options中添加浏览器位置:

*
*
*
*
*
*

```java
  public void setBrowserLocation() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L55)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L29)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L49)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.binary = edge_location
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L25)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### 添加扩展

`extensions`参数接受 crx 文件. 至于已解压的目录、中提到, 请使用[本文](https://chromedriver.chromium.org/extensions)中提及的 `load-extension`.

在options中添加扩展:

*
*
*
*
*
*

```java
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L66)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L40)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L61)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.add_extension(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L34)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L55)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

### 保持浏览器打开

将 `detach` 参数设置为 true后, 只要不向driver发送退出命令, 就可以在进程结束后保持浏览器打开.

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L51)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

**Note**: This is already the default behavior in .NET.

```rb
      options.detach = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L45)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.detachDriver(true))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L32)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

### 排除参数

MSEdgedriver 有几个用于启动浏览器的默认参数. 如果不希望添加这些参数, 可将它们传递到 `excludeSwitches` 中. 一个常见的例子就是重新打开弹出窗口拦截器. 默认参数的完整列表参考 [Chromium Source Code](https://source.chromium.org/chromium/chromium/src/+/main:chrome/test/chromedriver/chrome_launcher.cc)

在options中设置排除参数:

*
*
*
*
*
*

```java
  public void excludeSwitches() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L79)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L62)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L76)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.exclude_switches << 'disable-popup-blocking'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L53)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L22)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

## 服务

创建默认服务对象, 设置驱动程序位置和端口的示例可以参考 [Driver服务](https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/service/) 页面.

### 日志输出

获取驱动程序日志有助于调试问题。 服务类可让您配置日志的输出。 日志输出会被忽略, 除非用户显示指定.

```java
  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L101)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Java同样允许在系统属性中配置文件输出:\
Property key: `EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY`\
Property value: String representing path to log file

```py
def test_log_to_file(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L71)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L86)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L67)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    File logLocation = getTempFile("logsToConsole", ".log");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L114)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Java同样允许在系统属性中配置控制台输出:\
属性键: `EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY`\
属性值: `DriverService.LOG_STDOUT` 或 `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
def test_log_to_stdout(capfd):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L82)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

`$stdout` and `$stderr` are both valid values

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L76)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### 日志级别

有 6 种可用的日志级别: `ALL`, `DEBUG`, `INFO`, `WARNING`, `SEVERE`, 以及 `OFF`. 请注意, `--verbose` 等同于 `--log-level=ALL` , 而 `--silent` 等同于 `--log-level=OFF`, 因此, 本例只是一般性地设置日志级别:

```java
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L127-L128)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Java同样允许在系统属性中配置日志级别:\
属性键: `EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY`\
属性值: String representation of `ChromiumDriverLogLevel` enum

```py
def test_log_level(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L93)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '--log-level=DEBUG'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L87)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### 日志文件功能

有 2 项功能只有在记录到文件时才可用:

* 追加日志
* 可读时间戳

要使用它们, 还需要明确指定日志路径和日志级别. 日志输出将由driver而非进程管理, 因此可能会出现细微差别.

```java
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L143-L144)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Java同样允许在系统属性中配置开闭这些功能:\
属性键: `EdgeDriverService.EDGE_DRIVER_APPEND_LOG_PROPERTY` 以及 `EdgeDriverService.EDGE_DRIVER_READABLE_TIMESTAMP`\
属性值: `"true"` 或 `"false"`

```py
def test_log_features(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L104)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << '--append-log'
      service.args << '--readable-timestamp'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L97-L98)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### 禁用构建检查

Edge 浏览器和 msedgedriver 版本应该匹配, 如果不匹配, 驱动程序就会出错. 如果禁用构建检查, 则可以强制驱动程序与任何版本的 Edge 一起使用. 请注意, 这是一项不受支持的功能, 而且不会对错误进行调查.

```java
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L161-L162)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Java同样允许在系统属性中配置禁用构建检查:\
属性键: `EdgeDriverService.EDGE_DRIVER_DISABLE_BUILD_CHECK`\
属性值: `"true"` 或 `"false"`

```py
def test_build_checks(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L115)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L155)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << '--disable-build-check'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L108)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## Internet Explorer 兼容模式

微软Edge可以被"Internet Explorer兼容模式"驱动, 该模式使用Internet Explorer驱动类与微软Edge结合使用. 阅读 [Internet Explorer 页面](https://www.selenium.dev/zh-cn/documentation/webdriver/browsers/internet_explorer/) 了解更多详情.

## 特殊功能

某些浏览器实现了其特有的附加功能.

### Cast

您可以使用 Edge 驱动 Chrome Cast 设备, 包括共享标签页

*
*
*
*
*
*

```java
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L225-L230)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L170-L174)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L119-L123)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### 网络状况

您可以模拟各种网络状况.

*
*
*
*
*
*

```java
  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L198-L204)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L129-L135)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L129)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    consoleLogButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L242)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L186)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      sleep 1
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L141)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    EdgeDriver driver = new EdgeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L184)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L149)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L149-L150)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### 开发者工具

有关在 Edge 中使用 DevTools 的更多信息, 请参阅 \[Chrome DevTools] 部分.

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/troubleshooting/logging/
----

# 记录 Selenium 命令

```java
    public void logging() throws IOException {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Java日志并不简单直接, 如果您只是在寻找一种简单的方法 查看重要的Selenium日志, 请参阅 [Selenium Logger 项目](https://github.com/titusfortner/selenium-logger#selenium-logger)

Python logs are typically created per module. You can match all submodules by referencing the top level module. So to work with all loggers in selenium module, you can do this:

```py
    logger = logging.getLogger('selenium')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L5)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

You must also create and add a log handler (`StreamHandler`, `FileHandler`, etc).

To save logs to a file, you can do this:

```py
log_path = '/path/to/log'
handler = logging.FileHandler(log_path)
logger.addHandler(handler)
```

To display logs in the console, you can do this:

```py
handler = logging.StreamHandler()
logger.addHandler(handler)
```

.NET logger is managed with a static class, so all access to logging is managed simply by referencing `Log` from the `OpenQA.Selenium.Internal.Logging` namespace.

If you want to see as much debugging as possible in all the classes, you can turn on debugging globally in Ruby by setting `$DEBUG = true`.

For more fine-tuned control, Ruby Selenium created its own Logger class to wrap the default `Logger` class. This implementation provides some interesting additional features. Obtain the logger directly from the `#logger`class method on the `Selenium::WebDriver` module:

```rb
    logger = Selenium::WebDriver.logger
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L11)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

```javascript
const logging = require('selenium-webdriver/lib/logging')
logger = logging.getLogger('webdriver')
```

```java
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L32-L35)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Python has 6 logger levels: `CRITICAL`, `ERROR`, `WARNING`, `INFO`, `DEBUG`, and `NOTSET`. The default is `WARNING`

To change the level of the logger:

```py
    logger.setLevel(logging.DEBUG)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L7)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

Things get complicated when you use PyTest, though. By default, PyTest hides logging unless the test fails. You need to set 3 things to get PyTest to display logs on passing tests.

To always output logs with PyTest you need to run with additional arguments. First, `-s` to prevent PyTest from capturing the console. Second, `-p no:logging`, which allows you to override the default PyTest logging settings so logs can be displayed regardless of errors.

So you need to set these flags in your IDE, or run PyTest on command line like:

```bash
pytest -s -p no:logging
```

Finally, since you turned off logging in the arguments above, you now need to add configuration to turn it back on:

```py
logging.basicConfig(level=logging.WARN)
```

.NET has 6 logger levels: `Error`, `Warn`, `Info`, `Debug`, `Trace` and `None`. The default level is `Warn`.

To change the level of the logger:

```cs
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L18)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

Ruby logger has 5 logger levels: `:debug`, `:info`, `:warn`, `:error`, `:fatal`. As of Selenium v4.9.1, The default is `:info`.

To change the level of the logger:

```rb
    logger.level = :debug
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L13)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

JavaScript has 9 logger levels: `OFF`, `SEVERE`, `WARNING`, `INFO`, `DEBUG`, `FINE`, `FINER`, `FINEST`, `ALL`. The default is `OFF`.

To change the level of the logger:

```javascript
logger.setLevel(logging.Level.INFO)
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
WARNING: this is a warning
```

Python logs actionable content at logger level — `WARNING` Details about deprecations are logged at this level.

Example:

```text
WARNING  selenium:test_logging.py:23 this is a warning
```

.NET logs actionable content at logger level `Warn`.

Example:

```text
11:04:40.986 WARN LoggingTest: this is a warning
```

Ruby logs actionable content at logger level — `:warn`. Details about deprecations are logged at this level.

For example:

```text
2023-05-08 20:53:13 WARN Selenium [:example_id] this is a warning 
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
INFO: this is useful information
```

Python logs useful information at logger level — `INFO`

Example:

```text
INFO     selenium:test_logging.py:22 this is useful information
```

.NET logs useful information at logger level `Info`.

Example:

```text
11:04:40.986 INFO LoggingTest: this is useful information
```

Ruby logs useful information at logger level — `:info`.

Example:

```text
2023-05-08 20:53:13 INFO Selenium [:example_id] this is useful information 
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
FINE: this is detailed debug information
```

Python logs debugging details at logger level — `DEBUG`

Example:

```text
DEBUG    selenium:test_logging.py:24 this is detailed debug information
```

.NET logs most debug content at logger level `Debug`.

Example:

```text
11:04:40.986 DEBUG LoggingTest: this is detailed debug information
```

Ruby only provides one level for debugging, so all details are at logger level — `:debug`.

Example:

```text
2023-05-08 20:53:13 DEBUG Selenium [:example_id] this is detailed debug information 
```

```java

      Path output = artifactsDir().resolve("selenium.xml");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L37-L38)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

By default all logs are sent to `sys.stderr`. To direct output somewhere else, you need to add a handler with either a `StreamHandler` or a `FileHandler`:

```py
    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L9-L10)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

By default all logs are sent to `System.Console.Error` output. To direct output somewhere else, you need to add a handler with a `FileLogHandler`:

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L20)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

By default, logs are sent to the console in `stdout`.\
To store the logs in a file:

```rb
    logger.output = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L15)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

JavaScript does not currently support sending output to a file.

To send logs to console output:

```javascript
logging.installConsoleHandler()
```

```java
        logger.addHandler(handler);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L40-L41)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Because logging is managed by module, instead of working with just "selenium", you can specify different levels for different modules:

```py
    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L12-L13)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

.NET logging is managed on a per class level, set the level you want to use on a per-class basis:

```cs

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

Ruby’s logger allows you to opt in (“allow”) or opt out (“ignore”) of log messages based on their IDs. Everything that Selenium logs includes an ID. You can also turn on or off all deprecation notices by using `:deprecations`.

These methods accept one or more symbols or an array of symbols:

```rb
    logger.ignore(:jwp_caps, :logger_info)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L17)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

or

```rb
    logger.allow(%i[selenium_manager example_id])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L18)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

最后修改 August 13, 2025: [\[dotnet\] Change default internal log level to Warn (#2409) (22fad037ea6)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/22fad037ea6c457abc65c64d37d6c299bde40a4d)

----
url: https://www.selenium.dev/documentation/legacy/developers/drivers/
----

# Adding new drivers to Selenium 2 code

----
url: https://www.selenium.dev/pt-br/_print/documentation/webdriver/getting_started/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/webdriver/getting_started/).

# Começando

Se você é novo no Selenium, nós temos alguns recursos que podem te ajudar a se atualizar imediatamente.

* 1: [Instalando bibliotecas do Selenium](#pg-22263cce048e0595eb85efd82d18b192)
* 2: [Programe o seu primeiro script Selenium](#pg-7dc0370f8c170fa53f4fec31facd65fb)
* 3: [Organizando e executando o código Selenium](#pg-58de84d59b707fb04e73e343ddc3ebad)

# 1 - Instalando bibliotecas do Selenium

```xml
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/pom.xml#L35-L38)

##### /examples/java/pom.xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>dev.selenium</groupId>
    <artifactId>selenium-examples</artifactId>
    <version>1.0.0</version>

    <properties>
        <surefire.parallel>1</surefire.parallel>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <selenium.version>4.41.0</selenium.version>
    </properties>

    <repositories>
        <repository>
            <name>Central Portal Snapshots</name>
            <id>central-portal-snapshots</id>
            <url>https://central.sonatype.com/repository/maven-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-grid</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>6.0.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.titusfortner</groupId>
            <artifactId>selenium-logger</artifactId>
            <version>2.4.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.5.5</version>
                <configuration>
                    <properties>
                        <configurationParameters>
                            junit.jupiter.execution.parallel.enabled = true
                            junit.jupiter.execution.parallel.mode.default = concurrent
                            junit.jupiter.execution.parallel.config.strategy = fixed
                            junit.jupiter.execution.parallel.config.fixed.parallelism = ${surefire.parallel}
                            junit.jupiter.execution.parallel.config.fixed.max-pool-size = ${surefire.parallel}
                        </configurationParameters>
                    </properties>
                    <rerunFailingTestsCount>3</rerunFailingTestsCount>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
```

### Gradle

Especifique a dependência no `build.gradle` do seu projeto como `testImplementation`:

```gradle

dependencies {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/build.gradle#L13-L14)

##### /examples/java/build.gradle

```gradle
plugins {
    id 'java'
}

group 'dev.selenium'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

ext['seleniumVersion'] = System.getProperty('selenium.version', '4.41.0')

dependencies {
    testImplementation "org.seleniumhq.selenium:selenium-java:${seleniumVersion}"
    testImplementation "org.seleniumhq.selenium:selenium-grid:${seleniumVersion}"
    testImplementation platform("org.junit:junit-bom:6.0.2")
    testImplementation 'org.junit.jupiter:junit-jupiter-engine'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    testImplementation 'com.titusfortner:selenium-logger:2.4.0'
}

test {
    useJUnitPlatform()
}
```

A mínima versão suportada do Python para cada versão do Selenium pode ser encontrada em “Supported Python Versions” no [PyPi](https://pypi.org/project/selenium/).

Existe muitas formas diferentes de instalar Selenium.

### Pip

```shell
pip install selenium
```



### Download

Como uma alternativa você pode baixar o [código fonte PyPI](https://pypi.org/project/selenium/#files) (selenium-x.x.x.-py3-none-any.whl) e instalar usando *pip*:

```shell
pip install selenium-x.x.x.-py3-none-any.whl
```



### Exigir em um projeto

Para usar em um projeto, adicione no arquivo `requirements.txt`.

```txt
selenium==4.41.0
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/requirements.txt#L1)

##### /examples/python/requirements.txt

```txt
selenium==4.41.0
pytest==9.0.3
trio==0.31.0
pytest-trio==0.8.0
pytest-rerunfailures==16.1
flake8==7.3.0
requests==2.33.0
tox==4.32.0
pytest-xdist==3.8.0
```

Uma lista com todos os frameworks suportados para cada versão do Selenium pode ser encontrada em [Nuget](https://www.nuget.org/packages/Selenium.WebDriver)

Existe algumas opções para instalar o Selenium.

### Packet Manager

```shell
Install-Package Selenium.WebDriver
```



### .NET CLI

```shell
dotnet add package Selenium.WebDriver
```



### CSProj

No arquivo `csproj` do seu projeto, especifique a dependência como `PackageReference` no `ItemGroup`:

```csproj
      <PackageReference Include="Selenium.WebDriver" Version="4.41.0" />
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/SeleniumDocs.csproj#L14)

##### /examples/dotnet/SeleniumDocs/SeleniumDocs.csproj

```csproj
<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <GenerateProgramFile>false</GenerateProgramFile>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
      <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="7.7.1" />
      <PackageReference Include="MSTest.TestAdapter" Version="3.6.0" />
      <PackageReference Include="MSTest.TestFramework" Version="3.6.0" />
      <PackageReference Include="Selenium.Support" Version="4.41.0" />
      <PackageReference Include="Selenium.WebDriver" Version="4.41.0" />
    </ItemGroup>

    <ItemGroup>
      <Folder Include="LocalPackages" />
    </ItemGroup>

</Project>
```

### Considerações adicionais

Outras observações para usar o Visual Studio Code (vscode) e C#

Instale a versão compatível do .NET SDK conforme a seção acima. Instale também as extensões do vscode (Ctrl-Shift-X) para C# e NuGet. Siga as instruções [aqui ](https://docs.microsoft.com/en-us/dotnet/core/tutorials/with-visual-studio-code?pivots=dotnet-5-0)para criar e rodar o seu projeto de “Hello World” no console usando C#.

Você também pode criar um projeto inicial do NUnit usando a linha de comando `dotnet new NUnit`. Certifique-se de que o arquivo `%appdata%\NuGet\nuget.config` esteja configurado corretamente, pois alguns desenvolvedores relataram que ele estará vazio devido a alguns problemas. Se o `nuget.config` estiver vazio ou não estiver configurado corretamente, as compilações .NET falharão para projetos que estiverem usando Selenium. Adicione a seguinte seção ao arquivo `nuget.config` se esse estiver vazio:

```
<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />   
  </packageSources>
...
```

Para mais informações sobre `nuget.config` [clique aqui](https://docs.microsoft.com/en-us/nuget/reference/nuget-config-file). Você pode ter que customizar `nuget.config` para atender às suas necessidades.

Agora, volte para o vscode, aperte Ctrl-Shift-P, e digite “NuGet Add Package”, e adicione os pacotes necessários para o Selenium como o `Selenium.WebDriver`. Aperte Enter e selecione a versão. Agora você pode usar os exemplos da documentação relacionados ao C# com o vscode.

Você pode ver a minima versão suportada do Ruby para cada versão do Selenium em [rubygems.org](https://rubygems.org/gems/selenium-webdriver/)

O Selenium pode ser instalado de duas formas diferentes.

### Instalação manual

```shell
gem install selenium-webdriver
```



### Adicione para o gemfile do projeto

```gemfile
gem 'selenium-devtools', '= 0.147.0'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/Gemfile#L10)

##### /examples/ruby/Gemfile

```gemfile
# frozen_string_literal: true

source 'https://rubygems.org'

gem 'ffi', '~> 1.15', '>= 1.15.5' if Gem.win_platform? # Windows only
gem 'rake', '~> 13.0'
gem 'rspec', '~> 3.0'
gem 'rubocop', '~> 1.35'
gem 'rubocop-rspec', '~> 3.0'
gem 'selenium-devtools', '= 0.147.0'
gem 'selenium-webdriver', '= 4.43.0'
```

Você pode encontrar a mínima versão suportada do Node para cada versão do Selenium na seção `Node Support Policy` no site [npmjs](https://www.npmjs.com/package/selenium-webdriver)

Selenium é normalmente instalado usando npm.

### Instalação local

```shell
npm install selenium-webdriver
```



### Adicione ao seu projeto

No `package.json` do seu projeto, adicione os requisitos em `dependencies`:

```json
        "mocha": "11.7.5"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/package.json#L14)

##### /examples/javascript/package.json

```json
{
    "name": "javascript-examples",
    "version": "1.0.0",
    "scripts": {
        "test": "npx mocha test/**/*.spec.js --timeout 120000 --parallel --retries 2"
    },
    "author": "The Selenium project",
    "license": "Apache-2.0",
    "dependencies": {
        "assert": "2.1.0",
        "selenium-webdriver": "4.41.0"
    },
    "devDependencies": {
        "mocha": "11.7.5"
    }
}
```

Use as ligações Java para Kotlin.

## Próximo passo

[Programando o seu primeiro script Selenium](https://www.selenium.dev/pt-br/documentation/webdriver/getting_started/first_script/)

# 2 - Programe o seu primeiro script Selenium

```java
        WebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver = webdriver.Chrome()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L4)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L11)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver = Selenium::WebDriver.for :chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L3)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    driver = await new Builder().forBrowser(Browser.CHROME).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L8)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver = ChromeDriver()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L16)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.get("https://www.selenium.dev/selenium/web/web-form.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L6)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L13)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.get('https://www.selenium.dev/selenium/web/web-form.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L5)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L9)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.get("https://www.selenium.dev/selenium/web/web-form.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L18)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#16)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L8)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var title = driver.Title;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L15)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L7)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let title = await driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L11)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L20)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L18)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.implicitly_wait(0.5)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L10)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L17)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.manage.timeouts.implicit_wait = 500
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L9)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.manage().setTimeouts({implicit: 500});
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L14)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L23)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L20-L21)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L12-L13)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L19-L20)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L11-L12)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L16-L17)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L25-L26)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        textBox.sendKeys("Selenium");
        submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L23-L24)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
text_box.send_keys("Selenium")
submit_button.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L15-L16)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        textBox.SendKeys("Selenium");
        submitButton.Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
text_box.send_keys('Selenium')
submit_button.click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L14-L15)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await textBox.sendKeys('Selenium');
    await submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L19-L20)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        textBox.sendKeys("Selenium")
        submitButton.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L28-L29)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        WebElement message = driver.findElement(By.id("message"));
        message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-27)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
message = driver.find_element(by=By.ID, value="message")
text = message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L18-19)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-26)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
message = driver.find_element(id: 'message')
message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L17-18)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L22-23)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val message = driver.findElement(By.id("message"))
        val value = message.getText()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-32)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L21)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L28)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L20)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L28)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L35)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```md
mvn exec:java -D"exec.mainClass"="dev.selenium.getting_started.FirstScript" -D"exec.classpathScope"=test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/README.md#L60)

##### /examples/java/README.md

````md
# Running Selenium Java Tests
The following steps will guide you on how to 
run Selenium Java tests using a repository 
of `SeleniumHQ/seleniumhq.github.io` examples.

## Initial Setup

### Prerequisites

Ensure that Java Development Kit (JDK) and Maven 
are installed on your system. If they are not installed, 
you will need to download and install them. You can 
find detailed installation guides for both on their 
respective official sites.

### Clone the repository
First, we need to get the Selenium Java examples 
on your local machine. This can be done by 
cloning the `SeleniumHQ/seleniumhq.github.io` Git repository. 
Run the following command in your terminal:

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```
## Navigate to the java directory
After cloning the repository, navigate into the 
directory where the Selenium Java examples are 
located. Run the following command:

```bash
cd seleniumhq.github.io/examples/java
```

## Running the Tests
### Install dependencies
Before running the tests, we need to install all 
necessary dependencies. Maven, a software 
project management tool, can do this for us. 
Run the following command:

```bash
mvn test-compile
```

### Run all tests
To verify if everything is installed correctly and 
functioning properly, we should run all 
available tests. This can be done with the following command:

```bash
mvn test
```

Please be patient! If this is your first time running these tests, 
it might take a while to download and verify all necessary browser drivers.

## Execute a specific example
To run a specific Selenium Java example, use the following command:
```bash
mvn exec:java -D"exec.mainClass"="dev.selenium.getting_started.FirstScript" -D"exec.classpathScope"=test
```

Make sure to replace `dev.selenium.getting_started.FirstScript` with the path and name of the example you want to run.
````

````md
```
````

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/README.md#L35)

##### /examples/python/README.md

````md
# Running tests from Selenium Python examples

#### 1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

#### 2. Navigate to `python` directory

```
cd seleniumhq.github.io/examples/python
```

#### 3. Create a virtual environment

- On Windows:

```
py -m venv venv
venv\Scripts\activate
```

- On Linux/Mac:

```
python3 -m venv venv
source venv/bin/activate
```

#### 4. Install dependencies:

```
pip install -r requirements.txt
```

> for help, see: https://packaging.python.org/en/latest/tutorials/installing-packages

#### 5. Run tests

- Run all tests with the default Python interpreter:

```
pytest
```

- Run all tests with every installed/supported Python interpreter:

```
tox
```

> Please have some patience - If you are doing it for the first time, it will take a little while to download the browser drivers

- Run a specific example:

```
pytest path/to/test_script.py
```

> Make sure to replace `path/to/test_script.py` with the path and name of the example you want to run
````

```md
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/README.md#L55)

##### /examples/dotnet/README.md

````md

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

## Navigate to the .NET directory
### Change into the .NET examples directory:

```bash
cd seleniumhq.github.io/examples/dotnet/SeleniumDocs
```

## Running the Tests
### Restore dependencies
Install necessary dependencies using the .NET CLI:

```bash
dotnet restore
```

### Run all tests
To run all available tests:

```bash
dotnet test
```

### Run a Specific Test Method
To run a specific test method using its fully qualified name:

```bash
dotnet test --filter "FullyQualifiedName=Namespace.ClassName.MethodName"
```
For example:
```bash
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

You can also filter by test name only (if it's unique):
```bash
dotnet test --filter "Name=EightComponents"
```
````

```md
ruby example_script.rb
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/README.md#L36)

##### /examples/ruby/README.md

````md
# Running all tests from Selenium ruby example

Follow these steps to run all test example from selenium ruby

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `ruby` directory

```
cd seleniumhq.github.io/examples/ruby
```

3. Install dependencies using bundler

```
bundler install
```

4. Run all tests

```
bundle exec rspec
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a ruby script

Use this command to run a ruby script and follow the first script example

```
ruby example_script.rb
```
````

```md
node example_script.spec.js
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/README.md#L36)

##### /examples/javascript/README.md

````md
# Running all tests from Selenium javascript example

Follow these steps to run all test example from selenium javascript

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `javascript` directory

```
cd seleniumhq.github.io/examples/javascript
```

3. Install dependencies using node

```
npm install
```

4. Run all all tests

```
npm test
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a javascript test

Use this command to run a JavaScript and follow the first script example

```
node example_script.spec.js
```
````

[Add Example](/documentation/about/contributing/#creating-examples)

## Próximos Passos

Most Selenium users execute many sessions and need to organize them to minimize duplication and keep the code more maintainable. Read on to learn about how to put this code into context for your use case with [Using Selenium](https://www.selenium.dev/pt-br/documentation/webdriver/getting_started/using_selenium/).

# 3 - Organizando e executando o código Selenium

Escalonamento da execução do Selenium com um IDE e uma biblioteca do Test Runner

Se quiser executar mais do que um punhado de scripts pontuais, precisa de ser capaz de organizar e trabalhar com seu código. Esta página deve dar a você ideias de como fazer coisas produtivas com seu código Selenium.

## Usos comuns

A maioria das pessoas usa o Selenium para executar testes automatizados para aplicações web, mas o Selenium suporta qualquer caso de uso de automação de navegador.

### Tarefas Repetitivas

Talvez seja necessário fazer login em um site e baixar algo ou enviar um formulário. Você pode criar um script Selenium para ser executado com um serviço em horários pré-definidos.

### Web Scrapping

Está a tentar recolher dados de um site que não tem uma API? O Selenium permitirá que você faça isso, mas certifique-se de estar familiarizado com os termos de serviço do site termos de serviço do site, pois alguns sites não permitem isso e outros até bloqueiam o Selenium.

### Testes

Executar o Selenium para testes requer fazer asserções sobre as ações tomadas pelo Selenium. Então uma boa biblioteca de asserções é necessária. Características adicionais para prover estrutura para testes requerem o uso de [Executador de teste](/pt-br/documentation/webdriver/getting_started/using_selenium/#executador-de-teste).

## IDEs

Independentemente de como você usa o código do Selenium, não será muito eficaz escrevendo ou executando-o sem um bom ambiente de desenvolvimento integrado. Aqui estão algumas opções comuns…

* [Eclipse](https://www.eclipse.org/)
* [IntelliJ IDEA](https://www.jetbrains.com/idea/)
* [PyCharm](https://www.jetbrains.com/pycharm/)
* [RubyMine](https://www.jetbrains.com/ruby/)
* [Rider](https://www.jetbrains.com/rider/)
* [WebStorm](https://www.jetbrains.com/webstorm/)
* [VS Code](https://code.visualstudio.com/)

## Executador de teste

Mesmo que não esteja a usar o Selenium para testes, se tiver casos de uso avançado, pode fazer sentido usar um executor de testes para organizar melhor seu código. Ser capaz de usar hooks antes/depois e executar coisas em grupos ou em paralelo pode ser muito útil.

### Escolhendo

Há muitos executores de teste diferentes disponíveis.

Todos os exemplos de código nesta documentação podem ser encontrados em (ou estão sendo movidos para) nossos diretórios que usam test runners e são executados a cada lançamento para garantir que todo o código esteja correto e atualizado. Aqui está uma lista de executores de teste com links. O primeiro item é o que é usado por este repositório e o que que será usado para todos os exemplos nesta página.

*
*
*
*
*
*

- [JUnit](https://junit.org/junit5/) - Uma estrutura de teste amplamente utilizada para testes Selenium baseados em Java.
- [TestNG](https://testng.org/) - Oferece recursos extras, como execução de testes paralelos e testes parametrizados.

* [pytest](https://pytest.org/) -Uma escolha preferida por muitos, graças à sua simplicidade e aos seus poderosos plugins.
* [unittest](https://docs.python.org/3/library/unittest.html) - A estrutura de testes da biblioteca padrão do Python.

- [NUnit](https://nunit.org/) - Um popular framework de teste unitário para .NET.
- [MS Test](https://docs.microsoft.com/en-us/visualstudio/test/getting-started-with-unit-testing?view=vs-2019) - O Framework de testes unitários da Microsoft.

* [RSpec](https://rspec.info/) - A biblioteca de testes mais utilizada para executar testes Selenium em Ruby.
* [Minitest](https://github.com/seattlerb/minitest) - Um framework de testes leve que vem com a biblioteca padrão do Ruby.

- [Jest](https://jestjs.io/) - Principalmente conhecido como um framework de teste para React, também pode ser utilizado para testes Selenium.
- [Mocha](https://mochajs.org/) - A biblioteca JS mais comum para executar testes Selenium.

* [Kotest](https://kotest.io/) - Uma estrutura de testes flexível e abrangente, projetada especificamente para Kotlin.
* [JUnit5](https://junit.org/junit5/) - A estrutura de testes padrão do Java, totalmente compatível com Kotlin.

### Instalando

Isto é muito semelhante ao que foi requerido em [Install a Selenium Library](https://www.selenium.dev/pt-br/documentation/webdriver/getting_started/install_library/). Este código está apenas a mostrar exemplos do que está a ser usado no nosso projeto de Exemplos de Documentação.

*
*
*
*
*
*

**Maven**

**Gradle**

Para usá-lo em um projeto, adicione-o ao arquivo `requirements.txt`:

in the project’s `csproj` especifique a dependência como `PackageReference` em `ItemGroup`:

Add to project’s gemfile

In your project’s `package.json`, adicionar requisito às `dependências`:

### Afirmar

*
*
*
*
*
*

```java
		String title = driver.getTitle();
		assertEquals("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L30-L31)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

```py
    title = driver.title
    assert title == "Web form"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L8-L9)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

```cs
            var title = driver.Title;
            Assert.AreEqual("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs#L19-L20)

##### /examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted
{
    [TestClass]
    public class UsingSeleniumTest
    {

        [TestMethod]
        public void EightComponents()
        {
            IWebDriver driver = new ChromeDriver();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

            var title = driver.Title;
            Assert.AreEqual("Web form", title);

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            var textBox = driver.FindElement(By.Name("my-text"));
            var submitButton = driver.FindElement(By.TagName("button"));
            
            textBox.SendKeys("Selenium");
            submitButton.Click();
            
            var message = driver.FindElement(By.Id("message"));
            var value = message.Text;
            Assert.AreEqual("Received!", value);
            
            driver.Quit();
        }
    }
}
```

```rb
    title = @driver.title
    expect(title).to eq('Web form')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb#L14-L15)

##### /examples/ruby/spec/getting\_started/using\_selenium\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

```js
    let title = await driver.getTitle();
    assert.equal("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L14-L15)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

```kt
        val title = driver.title
        assertEquals("Web form", title)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L20-21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt

    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

### Configuarar e Desconfigurar

*
*
*
*
*
*

### Set Up

```java
	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L19-L22)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

### Tear Down

```java
	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L45-L48)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

### Set Up

```py
def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L25-L28)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

### Tear Down

```py
def teardown(driver):
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L30-31)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

### Set Up

```rb
  before do
    @driver = Selenium::WebDriver.for :chrome
  end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb#L7-L9)

##### /examples/ruby/spec/getting\_started/using\_selenium\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

### Tear Down

```rb
  config.after { @driver&.quit }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/spec_helper.rb#L30)

##### /examples/ruby/spec/spec\_helper.rb

```rb

    c.syntax = :expect
  end

  config.before do |example|
    bug_tracker = 'https://github.com/SeleniumHQ/seleniumhq.github.io/issues'
    guards = Selenium::WebDriver::Support::Guards.new(example,
                                                      bug_tracker: bug_tracker)
    guards.add_condition(:platform, Selenium::WebDriver::Platform.os)
    guards.add_condition(:ci, Selenium::WebDriver::Platform.ci)

    results = guards.disposition
    send(*results) if results
  end

  config.after { @driver&.quit }

  def start_session
    options = Selenium::WebDriver::Chrome::Options.new
    options.add_argument('disable-search-engine-choice-screen')
    options.add_argument('--no-sandbox')
    @driver = Selenium::WebDriver.for(:chrome, options: options)
  end

  def start_bidi_session
    options = Selenium::WebDriver::Chrome::Options.new(web_socket_url: true)
    @driver = Selenium::WebDriver.for :chrome, options: options
  end

  def start_firefox
    options = Selenium::WebDriver::Options.firefox(timeouts: {implicit: 1500})
    @driver = Selenium::WebDriver.for :firefox, options: options
  end
end
```

\### Set Up

```js
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L7-L9)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

\### Tear Down

```js
  after(async () => await driver.quit());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L30)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

### Executando

*
*
*
*
*
*

### Maven

```shell
mvn clean test
```

### Gradle

```shell
gradle clean test
```

````md
```
````

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/README.md#L35)

##### /examples/python/README.md

````md
# Running tests from Selenium Python examples

#### 1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

#### 2. Navigate to `python` directory

```
cd seleniumhq.github.io/examples/python
```

#### 3. Create a virtual environment

- On Windows:

```
py -m venv venv
venv\Scripts\activate
```

- On Linux/Mac:

```
python3 -m venv venv
source venv/bin/activate
```

#### 4. Install dependencies:

```
pip install -r requirements.txt
```

> for help, see: https://packaging.python.org/en/latest/tutorials/installing-packages

#### 5. Run tests

- Run all tests with the default Python interpreter:

```
pytest
```

- Run all tests with every installed/supported Python interpreter:

```
tox
```

> Please have some patience - If you are doing it for the first time, it will take a little while to download the browser drivers

- Run a specific example:

```
pytest path/to/test_script.py
```

> Make sure to replace `path/to/test_script.py` with the path and name of the example you want to run
````

```md
dotnet test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/README.md#L44)

##### /examples/dotnet/README.md

````md
# Running Selenium .NET (C#) Tests

The following steps will guide you on how to  
run Selenium .NET (C#) tests using the examples  
from the `SeleniumHQ/seleniumhq.github.io` repository.

## Initial Setup

### Prerequisites

Ensure you have the following installed:

- [.NET SDK (8.0 or later)](https://dotnet.microsoft.com/en-us/download)
- An IDE like [Visual Studio](https://visualstudio.microsoft.com/) or [Visual Studio Code](https://code.visualstudio.com/)
- [.NET CLI tools](https://learn.microsoft.com/en-us/dotnet/core/tools/)

### Clone the repository

Clone the Selenium documentation repository to your local machine:

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

## Navigate to the .NET directory
### Change into the .NET examples directory:

```bash
cd seleniumhq.github.io/examples/dotnet/SeleniumDocs
```

## Running the Tests
### Restore dependencies
Install necessary dependencies using the .NET CLI:

```bash
dotnet restore
```

### Run all tests
To run all available tests:

```bash
dotnet test
```

### Run a Specific Test Method
To run a specific test method using its fully qualified name:

```bash
dotnet test --filter "FullyQualifiedName=Namespace.ClassName.MethodName"
```
For example:
```bash
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

You can also filter by test name only (if it's unique):
```bash
dotnet test --filter "Name=EightComponents"
```
````

```md
bundle exec rspec
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/README.md#L26)

##### /examples/ruby/README.md

````md
# Running all tests from Selenium ruby example

Follow these steps to run all test example from selenium ruby

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `ruby` directory

```
cd seleniumhq.github.io/examples/ruby
```

3. Install dependencies using bundler

```
bundler install
```

4. Run all tests

```
bundle exec rspec
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a ruby script

Use this command to run a ruby script and follow the first script example

```
ruby example_script.rb
```
````

### Mocha

```shell
mocha runningTests.spec.js
```

### npx

```shell
npx mocha runningTests.spec.js
```

[Add Example](/documentation/about/contributing/#creating-examples)

### Examplos

In [First script](https://www.selenium.dev/pt-br/documentation/webdriver/getting_started/first_script/), we saw each of the components of a Selenium script. Here’s an example of that code using a test runner:

*
*
*
*
*
*

```java
package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java)

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py)

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted
{
    [TestClass]
    public class UsingSeleniumTest
    {

        [TestMethod]
        public void EightComponents()
        {
            IWebDriver driver = new ChromeDriver();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

            var title = driver.Title;
            Assert.AreEqual("Web form", title);

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            var textBox = driver.FindElement(By.Name("my-text"));
            var submitButton = driver.FindElement(By.TagName("button"));
            
            textBox.SendKeys("Selenium");
            submitButton.Click();
            
            var message = driver.FindElement(By.Id("message"));
            var value = message.Text;
            Assert.AreEqual("Received!", value);
            
            driver.Quit();
        }
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs)

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb)

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js)

[Add Example](/documentation/about/contributing/#creating-examples)

## Proximos passos

Pegue no que aprendeu e desenvolva o seu código Selenium!

À medida que encontrar mais funcionalidades de que precisa, leia o resto da nossa [documentação do WebDriver](https://www.selenium.dev/pt-br/documentation/webdriver/).

----
url: https://www.selenium.dev/documentation/webdriver/bidi/w3c/network/
----

# Network

```java
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L36-L38)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    assert.notEqual(intercept, null)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L29)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L46-L50)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L34-L35)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                    responseDetails ->
                            network.continueWithAuth(
                                    responseDetails.getRequest().getRequestId(),
                                    new UsernameAndPassword("admin", "admin")));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L57-L64)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L42-L46)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                            // Does not handle the alert
                            network.continueWithAuthNoCredentials(responseDetails.getRequest().getRequestId()));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L74-L80)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L56-L60)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                            network.cancelAuth(responseDetails.getRequest().getRequestId()));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L90-L96)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L71-L75)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
            }
    }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L104-L108)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L30-L35)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L23-L29)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L45-L51)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L82-L88)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L62-L68)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L96-L102)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L101-L106)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

Last modified May 27, 2025: [Update dependency selenium-webdriver to v4.33.0 (#2316) (5f5285aba17)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/5f5285aba177977a839ac8377929dc999623a4bb)

----
url: https://www.selenium.dev/documentation/webdriver/elements/interactions/
----

# Interacting with web elements

```java
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L18-L22)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L12-L17)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L17-L21)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'color_input').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L11)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
    await submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L20)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
  const assert = require("assert");
  
  (async function firstTest() {
    let driver;
    
    try {
      driver = await new Builder().forBrowser(Browser.CHROME).build();
      await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
    
      let title = await driver.getTitle();
      assert.equal("Web form", title);
    
      await driver.manage().setTimeouts({implicit: 500});
    
      let textBox = await driver.findElement(By.name('my-text'));
      let submitButton = await driver.findElement(By.css('button'));
    
      await textBox.sendKeys('Selenium');
      await submitButton.click();
    
      let message = await driver.findElement(By.id('message'));
      let value = await message.getText();
      assert.equal("Received!", value);
    } catch (e) {
      console.log(e)
    } finally {
      await driver.quit();
    }
  }())
  
```

```kotlin
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    // Click the element
    driver.findElement(By.name("color_input")).click();
  
  
```

```java
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L27-L32)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L22-L27)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L27-L33)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L16)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
      let inputField = await driver.findElement(By.name('no_type'));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/interactions.spec.js#L21)

##### /examples/javascript/test/elements/interactions.spec.js

```js

  const {By, Browser, Builder} = require('selenium-webdriver');
  const assert = require("node:assert");
  
  
  describe('Element Interactions', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('should Clear input and send keys into input field', async function () {
  
      try {
        await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
        let inputField = await driver.findElement(By.name('no_type'));
        await inputField.clear();
        await inputField.sendKeys('Selenium');
        const text = await inputField.getAttribute('value');
        assert.strictEqual(text, "Selenium");
      } catch (e) {
        console.log(e)
      }
    });
  });
```

```kotlin
  
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

	//Clear field to empty it from any previous data
	driver.findElement(By.name("email_input")).clear()
	
    // Enter text 
    driver.findElement(By.name("email_input")).sendKeys("admin@localhost.dev")
  
  
```

```java
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L38-L40)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    email_input.clear()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L34)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L40-L43)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'email_input').clear
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L15)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
      await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/interactions.spec.js#L20)

##### /examples/javascript/test/elements/interactions.spec.js

```js

  const {By, Browser, Builder} = require('selenium-webdriver');
  const assert = require("node:assert");
  
  
  describe('Element Interactions', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('should Clear input and send keys into input field', async function () {
  
      try {
        await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
        let inputField = await driver.findElement(By.name('no_type'));
        await inputField.clear();
        await inputField.sendKeys('Selenium');
        const text = await inputField.getAttribute('value');
        assert.strictEqual(text, "Selenium");
      } catch (e) {
        console.log(e)
      }
    });
  });
```

```kotlin
  
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

	//Clear field to empty it from any previous data
	driver.findElement(By.name("email_input")).clear()
	
  
  
```

## Submit

In Selenium 4 this is no longer implemented with a separate endpoint and functions by executing a script. As such, it is recommended not to use this method and to click the applicable form submission button instead.

Last modified September 6, 2025: [changed editable to keyboard interactable as per W3C doc (#2472) (5e333fc2769)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/5e333fc2769a9e0ca541477eb2bfc5220da04951)

----
url: https://www.selenium.dev/documentation/legacy/selenium_2/focus_stealing/
----

# Stealing focus from Firefox in Linux

----
url: https://www.selenium.dev/pt-br/documentation/grid/configuration/cli_options/
----

# Opções CLI

Todas os detalhes das opções CLI de cada componente Grid.

Diferentes secções estão disponíveis para configurar uma Grid. Cada secção tem opções que podem ser configuradas através de opções CLI.

Pode ver abaixo um mapeamento entre o componente e a secção respectiva.

Note que esta documentação pode estar desactualizada se uma opção foi adicionada ou modificada, mas ainda não ter havido oportunidade de actualizar a documentação. Caso depare com esta situação, verifique a secção [“ajuda de configuração”](https://www.selenium.dev/pt-br/documentation/grid/configuration/help/) e esteja à vontade para nos enviar um pull request com alterações a esta página.

## Secções

|                               | Standalone | Hub | Node | Distributor | Router | Sessions | SessionQueue |
| ----------------------------- | ---------- | --- | ---- | ----------- | ------ | -------- | ------------ |
| [Distributor](#distributor)   | **         | **  |      | **          | **     |          |              |
| [Docker](#docker)             | **         |     | **   |             |        |          |              |
| [Events](#events)             |            | **  | **   | **          |        | **       | **           |
| [Logging](#logging)           | **         | **  | **   | **          | **     | **       | **           |
| [Network](#network)           | **         | **  |      |             | **     |          |              |
| [Node](#node)                 | **         |     | **   |             |        |          |              |
| [Router](#router)             | **         | **  |      |             | **     |          |              |
| [Relay](#relay)               | **         |     | **   |             |        |          |              |
| [Server](#server)             | **         | **  | **   | **          | **     | **       | **           |
| [SessionQueue](#sessionqueue) | **         | **  |      | **          | **     |          | **           |
| [Sessions](#sessions)         |            |     |      | **          | **     | **       |              |

### Distributor

| Opção                          | Tipo    | Valor/Exemplo                                                       | Descrição                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| ------------------------------ | ------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--healthcheck-interval`       | int     | `120`                                                               | Tempo em segundos em que se verifica o estado dos Nodes. Isto garante que o servidor consecontactar cada um dos Nodes com sucesso.                                                                                                                                                                                                                                                                                                                  |
| `--distributor`                | uri     | `http://localhost:5553`                                             | Url do Distributor.                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `--distributor-host`           | string  | `localhost`                                                         | Host onde o Distributor está à escuta.                                                                                                                                                                                                                                                                                                                                                                                                              |
| `--distributor-implementation` | string  | `org.openqa.selenium.grid.distributor.local.LocalDistributor`       | Nome completo da class para uma implementação não padrão do Distributor.                                                                                                                                                                                                                                                                                                                                                                            |
| `--distributor-port`           | int     | `5553`                                                              | Porta onde o Distributor está à escuta.                                                                                                                                                                                                                                                                                                                                                                                                             |
| `--reject-unsupported-caps`    | boolean | `false`                                                             | Permitir que o Distributor rejeite imediatamente um pedido de sessão se a Grid não suportar a capacidade pedida. Esta configuração é a ideal para Grid que não inicie Nodes a pedido.                                                                                                                                                                                                                                                               |
| `--slot-matcher`               | string  | `org.openqa.selenium.grid.data.DefaultSlotMatcher`                  | Nome completo da class para uma implementação não padrão do comparador de slots. Isto é usado para determinar se um Node pode suportar uma sessão em particular.                                                                                                                                                                                                                                                                                    |
| `--slot-selector`              | string  | `org.openqa.selenium.grid.distributor.selector.DefaultSlotSelector` | Nome completo da class para uma implementação não padrão do selector de slots. Isto é usado para selecionar um slot no Node caso tenha sido “matched”.                                                                                                                                                                                                                                                                                              |
| `--newsession-threadpool-size` | int     | `24`                                                                | The Distributor uses a fixed-sized thread pool to create new sessions as it consumes new session requests from the queue. This allows configuring the size of the thread pool. The default value is no. of available processors \* 3. Note: If the no. of threads is way greater than the available processors it will not always increase the performance. A high number of threads causes more context switching which is an expensive operation. |
| `--purge-nodes-interval`       | int     | `30`                                                                | How often, in seconds, will the Distributor purge Nodes that have been down for a while. This is calculated based on the heartbeat received from a particular node.                                                                                                                                                                                                                                                                                 |

### Docker

| Opção                       | Tipo      | Valor/Exemplo                                                     | Descrição                                                                                                                                                                                                                                                                                   |
| --------------------------- | --------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--docker-assets-path`      | string    | `/opt/selenium/assets`                                            | Absolute path where assets will be stored                                                                                                                                                                                                                                                   |
| `--docker-`                 | string\[] | `selenium/standalone-firefox:latest '{"browserName": "firefox"}'` | Docker configs which map image name to stereotype capabilities (example \`-D selenium/standalone-firefox:latest ‘{“browserName”: “firefox”}’)                                                                                                                                               |
| `--docker-devices`          | string\[] | `/dev/kvm:/dev/kvm`                                               | Exposes devices to a container. Each device mapping declaration must have at least the path of the device in both host and container separated by a colon like in this example: /device/path/in/host:/device/path/in/container                                                              |
| `--docker-host`             | string    | `localhost`                                                       | Host name where the Docker daemon is running                                                                                                                                                                                                                                                |
| `--docker-port`             | int       | `2375`                                                            | Port where the Docker daemon is running                                                                                                                                                                                                                                                     |
| `--docker-url`              | string    | `http://localhost:2375`                                           | URL for connecting to the Docker daemon                                                                                                                                                                                                                                                     |
| `--docker-video-image`      | string    | `selenium/video:latest`                                           | Docker image to be used when video recording is enabled                                                                                                                                                                                                                                     |
| `--docker-host-config-keys` | string\[] | `Dns DnsOptions DnsSearch ExtraHosts Binds`                       | Specify which docker host configuration keys should be passed to browser containers. Keys name can be found in the Docker API [documentation](https://docs.docker.com/engine/api/v1.41/#tag/Container/operation/ContainerCreate), or by running `docker inspect` the node-docker container. |

### Events

| Opção                     | Tipo    | Valor/Exemplo                                      | Descrição                                                                                                                                                                                                                                                                           |
| ------------------------- | ------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--bind-bus`              | boolean | `false`                                            | Whether the connection string should be bound or connected. When true, the component will be bound to the Event Bus (as in the Event Bus will also be started by the component, typically by the Distributor and the Hub). When false, the component will connect to the Event Bus. |
| `--events-implementation` | string  | `org.openqa.selenium.events.zeromq.ZeroMqEventBus` | Full class name of non-default event bus implementation                                                                                                                                                                                                                             |
| `--publish-events`        | string  | `tcp://*:4442`                                     | Connection string for publishing events to the event bus                                                                                                                                                                                                                            |
| `--subscribe-events`      | string  | `tcp://*:4443`                                     | Connection string for subscribing to events from the event bus                                                                                                                                                                                                                      |

### Logging

| Opção                    | Tipo    | Valor/Exemplo                                                                                                                                              | Descrição                                                                                                                                                              |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--http-logs`            | boolean | `false`                                                                                                                                                    | Enable http logging. Tracing should be enabled to log http logs.                                                                                                       |
| `--log-encoding`         | string  | `UTF-8`                                                                                                                                                    | Log encoding                                                                                                                                                           |
| `--log`                  | string  | Windows path example : `'\path\to\file\gridlog.log'` or `'C:\path\path\to\file\gridlog.log'` Linux/Unix/MacOS path example : `'/path/to/file/gridlog.log'` | File to write out logs. Ensure the file path is compatible with the operating system’s file path.                                                                      |
| `--log-level`            | string  | `“INFO”`                                                                                                                                                   | Log level. Default logging level is INFO. Log levels are described here <https://docs.oracle.com/en/java/javase/11/docs/api/java.logging/java/util/logging/Level.html> |
| `--plain-logs`           | boolean | `true`                                                                                                                                                     | Use plain log lines                                                                                                                                                    |
| `--structured-logs`      | boolean | `false`                                                                                                                                                    | Use structured logs                                                                                                                                                    |
| `--tracing`              | boolean | `true`                                                                                                                                                     | Enable trace collection                                                                                                                                                |
| `--log-timestamp-format` | string  | `HH:mm:ss.SSS`                                                                                                                                             | Allows the configure log timestamp format                                                                                                                              |

### Network

| Opção            | Tipo    | Valor/Exemplo | Descrição                                                                                                            |
| ---------------- | ------- | ------------- | -------------------------------------------------------------------------------------------------------------------- |
| `--relax-checks` | boolean | `false`       | Relax checks on origin header and content type of incoming requests, in contravention of strict W3C spec compliance. |

### Node

| Opção                            | Tipo      | Valor/Exemplo                                                                                                                                                                                                                                                              | Descrição                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                               |   |
| -------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - |
| `--detect-drivers`               | boolean   | `true`                                                                                                                                                                                                                                                                     | Autodetect which drivers are available on the current system, and add them to the Node.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |   |
| `--driver-configuration`         | string\[] | `display-name="Firefox Nightly" max-sessions=2 webdriver-path="/usr/local/bin/geckodriver" stereotype="{\"browserName\": \"firefox\", \"browserVersion\": \"86\", \"moz:firefoxOptions\": {\"binary\":\"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"` | List of configured drivers a Node supports. It is recommended to provide this type of configuration through a toml config file to improve readability                                                                                                                                                                                                                                                                                                                                                                                                                                                   |   |
| `--driver-factory`               | string\[] | `org.openqa.selenium.example.LynxDriverFactory '{"browserName": "lynx"}'`                                                                                                                                                                                                  | Mapping of fully qualified class name to a browser configuration that this matches against.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |   |
| `--driver-implementation`        | string\[] | `"firefox"`                                                                                                                                                                                                                                                                | Drivers that should be checked. If specified, will skip autoconfiguration.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |   |
| `--node-implementation`          | string    | `"org.openqa.selenium.grid.node.local.LocalNodeFactory"`                                                                                                                                                                                                                   | Full classname of non-default Node implementation. This is used to manage a session’s lifecycle.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |   |
| `--grid-url`                     | string    | `https://grid.example.com`                                                                                                                                                                                                                                                 | Public URL of the Grid as a whole (typically the address of the Hub or the Router)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |   |
| `--heartbeat-period`             | int       | `60`                                                                                                                                                                                                                                                                       | How often, in seconds, will the Node send heartbeat events to the Distributor to inform it that the Node is up.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |   |
| `--max-sessions`                 | int       | `8`                                                                                                                                                                                                                                                                        | Maximum number of concurrent sessions. Default value is the number of available processors.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |   |
| `--override-max-sessions`        | boolean   | `false`                                                                                                                                                                                                                                                                    | The # of available processors is the recommended max sessions value (1 browser session per processor). Setting this flag to true allows the recommended max value to be overwritten. Session stability and reliability might suffer as the host could run out of resources.                                                                                                                                                                                                                                                                                                                             |   |
| `--register-cycle`               | int       | `10`                                                                                                                                                                                                                                                                       | How often, in seconds, the Node will try to register itself for the first time to the Distributor.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |   |
| `--register-period`              | int       | `120`                                                                                                                                                                                                                                                                      | How long, in seconds, will the Node try to register to the Distributor for the first time. After this period is completed, the Node will not attempt to register again.                                                                                                                                                                                                                                                                                                                                                                                                                                 |   |
| `--session-timeout`              | int       | `300`                                                                                                                                                                                                                                                                      | Let X be the session-timeout in seconds. The Node will automatically kill a session that has not had any activity in the last X seconds. This will release the slot for other tests.                                                                                                                                                                                                                                                                                                                                                                                                                    |   |
| `--vnc-env-var`                  | string\[] | `SE_START_XVFB SE_START_VNC SE_START_NO_VNC`                                                                                                                                                                                                                               | Environment variable to check in order to determine if a vnc stream is available or not.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |   |
| `--no-vnc-port`                  | int       | `7900`                                                                                                                                                                                                                                                                     | If VNC is available, sets the port where the local noVNC stream can be obtained                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |   |
| `--drain-after-session-count`    | int       | `1`                                                                                                                                                                                                                                                                        | Drain and shutdown the Node after X sessions have been executed. Useful for environments like Kubernetes. A value higher than zero enables this feature.                                                                                                                                                                                                                                                                                                                                                                                                                                                |   |
| `--hub`                          | string    | `http://localhost:4444`                                                                                                                                                                                                                                                    | The address of the Hub in a Hub-and-Node configuration. Can be a hostname or IP address (`hostname`), in which case the Hub will be assumed to be `http://hostname:4444`, the `--grid-url` will be the same `--publish-events` will be `tcp://hostname:4442` and `--subscribe-events` will be `tcp://hostname:4443`. If `hostname` contains a port number, that will be used for `--grid-url` but the URIs for the event bus will remain the same. Any of these default values may be overridden but setting the correct flags. If the hostname has a protocol (such as `https`) that will be used too. |   |
| `--enable-cdp`                   | boolean   | `true`                                                                                                                                                                                                                                                                     | Enable CDP proxying in Grid. A Grid admin can disable CDP if the network does not allow websockets. True by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |   |
| `--enable-managed-downloads`     | boolean   | `false`                                                                                                                                                                                                                                                                    | This causes the Node to auto manage files downloaded for a given session on the Node.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |   |
| `--selenium-manager`             | boolean   | `false`                                                                                                                                                                                                                                                                    | When drivers are not available on the current system, use Selenium Manager. False by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |   |
| `--connection-limit-per-session` | int       | `10`                                                                                                                                                                                                                                                                       | Let X be the maximum number of websocket connections per session.This will ensure one session is not able to exhaust the connection limit of the host.                                                                                                                                                                                                                                                                                                                                                                                                                                                  |   |

### Relay

| Opção                        | Tipo      | Valor/Exemplo                                                                                                     | Descrição                                                                                                                                                                |
| ---------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--service-url`              | string    | `http://localhost:4723`                                                                                           | URL for connecting to the service that supports WebDriver commands like an Appium server or a cloud service.                                                             |
| `--service-host`             | string    | `localhost`                                                                                                       | Host name where the service that supports WebDriver commands is running                                                                                                  |
| `--service-port`             | int       | `4723`                                                                                                            | Port where the service that supports WebDriver commands is running                                                                                                       |
| `--service-status-endpoint`  | string    | `/status`                                                                                                         | Optional, endpoint to query the WebDriver service status, an HTTP 200 response is expected                                                                               |
| `--service-protocol-version` | string    | `HTTP/1.1`                                                                                                        | Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status                                                          |
| `--service-configuration`    | string\[] | `max-sessions=2 stereotype='{"browserName": "safari", "platformName": "iOS", "appium:platformVersion": "14.5"}}'` | Configuration for the service where calls will be relayed to. It is recommended to provide this type of configuration through a toml config file to improve readability. |

### Router

| Opção          | Tipo    | Valor/Exemplo              | Descrição                                                                                                           |
| -------------- | ------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `--password`   | string  | `myStrongPassword`         | Password clients must use to connect to the server. Both this and the username need to be set in order to be used.  |
| `--username`   | string  | `admin`                    | User name clients must use to connect to the server. Both this and the password need to be set in order to be used. |
| `--sub-path`   | string  | `my_company/selenium_grid` | A sub-path that should be considered for all user facing routes on the Hub/Router/Standalone.                       |
| `--disable-ui` | boolean | `true`                     | Disable the Grid UI.                                                                                                |

### Server

| Opção                 | Tipo    | Valor/Exemplo        | Descrição                                                                                                                                                                                                                                                                             |
| --------------------- | ------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--allow-cors`        | boolean | `true`               | Whether the Selenium server should allow web browser connections from any host                                                                                                                                                                                                        |
| `--host`              | string  | `localhost`          | Server IP or hostname: usually determined automatically.                                                                                                                                                                                                                              |
| `--bind-host`         | boolean | `true`               | Whether the server should bind to the host address/name, or only use it to" report its reachable url. Helpful in complex network topologies where the server cannot report itself with the current IP/hostname but rather an external IP or hostname (e.g. inside a Docker container) |
| `--https-certificate` | path    | `/path/to/cert.pem`  | Server certificate for https. Get more detailed information by running “java -jar selenium-server.jar info security”                                                                                                                                                                  |
| `--https-private-key` | path    | `/path/to/key.pkcs8` | Private key for https. Get more detailed information by running “java -jar selenium-server.jar info security”                                                                                                                                                                         |
| `--max-threads`       | int     | `24`                 | Maximum number of listener threads. Default value is: (available processors) \* 3.                                                                                                                                                                                                    |
| `--port`              | int     | `4444`               | Port to listen on. There is no default as this parameter is used by different components, for example, Router/Hub/Standalone will use 4444 and Node will use 5555.                                                                                                                    |

### SessionQueue

| Opção                       | Tipo   | Valor/Exemplo           | Descrição                                                                                                                                                 |
| --------------------------- | ------ | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--sessionqueue`            | uri    | `http://localhost:1237` | Address of the session queue server.                                                                                                                      |
| `-sessionqueue-host`        | string | `localhost`             | Host on which the session queue server is listening.                                                                                                      |
| `--sessionqueue-port`       | int    | `1234`                  | Port on which the session queue server is listening.                                                                                                      |
| `--session-request-timeout` | int    | `300`                   | Timeout in seconds. A new incoming session request is added to the queue. Requests sitting in the queue for longer than the configured time will timeout. |
| `--session-retry-interval`  | int    | `5`                     | Retry interval in seconds. If all slots are busy, new session request will be retried after the given interval.                                           |
| `--maximum-response-delay`  | int    | `8`                     | How often, in seconds, will the the SessionQueue response in case there is no data, to reduce the http requests while polling for new session requests.   |

### Sessions

| Opção             | Tipo   | Valor/Exemplo           | Descrição                                          |
| ----------------- | ------ | ----------------------- | -------------------------------------------------- |
| `--sessions`      | uri    | `http://localhost:1234` | Address of the session map server.                 |
| `--sessions-host` | string | `localhost`             | Host on which the session map server is listening. |
| `--sessions-port` | int    | `1234`                  | Port on which the session map server is listening. |

## Configuration examples

All the options mentioned above can be used when starting the Grid components. They are a good way of exploring the Grid options, and trying out values to find a suitable configuration.

We recommend the use of [Toml files](https://www.selenium.dev/pt-br/documentation/grid/configuration/toml_options/) to configure a Grid. Configuration files improve readability, and you can also check them in source control.

When needed, you can combine a Toml file configuration with CLI arguments.

### Command-line flags

To pass config options as command-line flags, identify the valid options for the component and follow the template below.

```
java -jar selenium-server-<version>.jar <component> --<option> value
```

#### Standalone, setting max sessions and main port

```
java -jar selenium-server-<version>.jar standalone --max-sessions 4 --port 4444
```

#### Hub, setting a new session request timeout, a main port, and disabling tracing

```
java -jar selenium-server-<version>.jar hub --session-request-timeout 500 --port 3333 --tracing false
```

#### Node, with 4 max sessions, with debug(fine) log, 7777 as port, and only with Firefox and Edge

```
java -jar selenium-server-<version>.jar node --max-sessions 4 --log-level "fine" --port 7777 --driver-implementation "firefox" --driver-implementation "edge"
```

#### Distributor, setting Session Map server url, Session Queue server url, and disabling bus

```
java -jar selenium-server-<version>.jar distributor --sessions http://localhost:5556 --sessionqueue http://localhost:5559 --bind-bus false
```

#### Setting custom capabilities for matching specific Nodes

**Important:** Custom capabilities need to be set in the configuration in all Nodes. They also need to be included always in every session request.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node A with custom cap set to `true`

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":true}' --port 6161
```

##### Start the Node B with custom cap set to `false`

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":false}' --port 6262
```

##### Matching Node A

```java
ChromeOptions options = new ChromeOptions();
options.setCapability("gsg:customcap", true);
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

Set the custom capability to `false` in order to match the Node B.

#### Enabling Managed downloads by the Node

At times a test may need to access files that were downloaded by it on the Node. To retrieve such files, following can be done.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node with manage downloads enabled

```
java -jar selenium-server-<version>.jar node --enable-managed-downloads true
```

##### Set the capability at the test level

Tests that want to use this feature should set the capability `"se:downloadsEnabled"`to `true`

```java
options.setCapability("se:downloadsEnabled", true);
```

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

In the response the list of file names appear under the key `names`.

##### Dowloading a file:

* The endpoint to `POST` from is `/session/<sessionId>/se/files` with a payload of the form `{"name": "fileNameGoesHere}`
* The session needs to be active in order for the command to work.
* The raw response looks like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "Base64EncodedStringContentsOfDownloadedFileAsZipGoesHere"
  }
}
```

* The response blob contains two keys,

  * `filename` - The file name that was downloaded.
  * `contents` - Base64 encoded zipped contents of the file.

* The file contents are Base64 encoded and they need to be unzipped.

##### List files that can be downloaded

The below mentioned `curl` example can be used to list all the files that were downloaded by the current session in the Node, and which can be retrieved locally.

```bash
curl -X GET "http://localhost:4444/session/90c0149a-2e75-424d-857a-e78734943d4c/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

##### Retrieve a downloaded file

Assuming the downloaded file is named `Red-blue-green-channel.jpg`, and using `curl`, the file could be downloaded with the following command:

```bash
curl -H "Accept: application/json" \
-H "Content-Type: application/json; charset=utf-8" \
-X POST -d '{"name":"Red-blue-green-channel.jpg"}' \
"http://localhost:4444/session/18033434-fa4f-4d11-a7df-9e6d75920e19/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "UEsDBBQACAgIAJpagVYAAAAAAAAAAAAAAAAaAAAAUmVkLWJsAAAAAAAAAAAAUmVkLWJsdWUtZ3JlZW4tY2hhbm5lbC5qcGdQSwUGAAAAAAEAAQBIAAAAcNkAAAAA"
  }
}
```

##### Complete sample code in Java

Below is an example in Java that does the following:

* Sets the capability to indicate that the test requires automatic managing of downloaded files.
* Triggers a file download via a browser.
* Lists the files that are available for retrieval from the remote node (These are essentially files that were downloaded in the current session)
* Picks one file and downloads the file from the remote node to the local machine.

```java
import com.google.common.collect.ImmutableMap;

import org.openqa.selenium.By;
import org.openqa.selenium.io.Zip;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.io.File;
import java.net.URL;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import static org.openqa.selenium.remote.http.Contents.asJson;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.HttpMethod.GET;
import static org.openqa.selenium.remote.http.HttpMethod.POST;

public class DownloadsSample {

  public static void main(String[] args) throws Exception {
    // Assuming the Grid is running locally.
    URL gridUrl = new URL("http://localhost:4444");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("se:downloadsEnabled", true);
    RemoteWebDriver driver = new RemoteWebDriver(gridUrl, options);
    try {
      demoFileDownloads(driver, gridUrl);
    } finally {
      driver.quit();
    }
  }

	private static void demoFileDownloads(RemoteWebDriver driver, URL gridUrl) throws Exception {
		driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
		// Download the two available files on the page
		driver.findElement(By.id("file-1")).click();
		driver.findElement(By.id("file-2")).click();

		// The download happens in a remote Node, which makes it difficult to know when the file
		// has been completely downloaded. For demonstration purposes, this example uses a
		// 10-second sleep which should be enough time for a file to be downloaded.
		// We strongly recommend to avoid hardcoded sleeps, and ideally, to modify your
		// application under test, so it offers a way to know when the file has been completely
		// downloaded.
		TimeUnit.SECONDS.sleep(10);

		//This is the endpoint which will provide us with list of files to download and also to
		//let us download a specific file.
		String downloadsEndpoint = String.format("/session/%s/se/files", driver.getSessionId());

		String fileToDownload;

		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To list all files that are were downloaded on the remote node for the current session
			// we trigger GET request.
			HttpRequest request = new HttpRequest(GET, downloadsEndpoint);
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			@SuppressWarnings("unchecked")
			List<String> names = (List<String>) value.get("names");
			// Let's say there were "n" files downloaded for the current session, we would like
			// to retrieve ONLY the first file.
			fileToDownload = names.get(0);
		}

		// Now, let's download the file
		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To retrieve a specific file from one or more files that were downloaded by the current session
			// on a remote node, we use a POST request.
			HttpRequest request = new HttpRequest(POST, downloadsEndpoint);
			request.setContent(asJson(ImmutableMap.of("name", fileToDownload)));
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			// The returned map would contain 2 keys,
			// filename - This represents the name of the file (same as what was provided by the test)
			// contents - Base64 encoded String which contains the zipped file.
			String zippedContents = value.get("contents").toString();
			// The file contents would always be a zip file and has to be unzipped.
			File downloadDir = Zip.unzipToTempDir(zippedContents, "download", "");
			// Read the file contents
			File downloadedFile = Optional.ofNullable(downloadDir.listFiles()).orElse(new File[]{})[0];
			String fileContent = String.join("", Files.readAllLines(downloadedFile.toPath()));
			System.out.println("The file which was "
					+ "downloaded in the node is now available in the directory: "
					+ downloadDir.getAbsolutePath() + " and has the contents: " + fileContent);
		}
	}


}
```

Última modificação October 3, 2025: [Correct a typo (\*doesnot\*) (#2487) (e189ca8ab39)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e189ca8ab397e914b15658a80c68c84db2274edb)

----
url: https://www.selenium.dev/ja/documentation/legacy/selenium_3/
----

# Selenium 3

Selenium 3 was the implementation of WebDriver without the Selenium RC Code. It has since been replaced with Selenium 4, which implements the W3C WebDriver specification.

***

##### [Grid 3](/ja/documentation/legacy/selenium_3/grid_3/)

Selenium Grid 3 supported WebDriver without Selenium RC code. Grid 3 was completely rewritten for the new Grid 4.

##### [独自のグリッドを設定する](/ja/documentation/legacy/selenium_3/grid_setup/)

Quick start guide for setting up Grid 3.

##### [グリッドのコンポーネント](/ja/documentation/legacy/selenium_3/grid_components/)

Description of Hub and Nodes for Grid 3.

----
url: https://www.selenium.dev/_print/documentation/legacy/selenium_ide/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/legacy/selenium_ide/).

# Legacy Selenium IDE

Selenium IDE was the original Firefox extension for Record and Playback.

* 1: [HTML runner](#pg-113130e01fcfca255f15dc478eda5567)
* 2: [Legacy Selenium IDE Release Notes](#pg-b425a5d462ec0ada7528ac53a83879b2)

## Introduction

The Selenium-IDE (Integrated Development Environment) is the tool you use to develop your Selenium test cases. It’s an easy-to-use Firefox plug-in and is generally the most efficient way to develop test cases. It also contains a context menu that allows you to first select a UI element from the browser’s currently displayed page and then select from a list of Selenium commands with parameters pre-defined according to the context of the selected UI element. This is not only a time-saver, but also an excellent way of learning Selenium script syntax.

This chapter is all about the Selenium IDE and how to use it effectively.

## Installing the IDE

Using Firefox, first, download the IDE from the SeleniumHQ [downloads page](https://selenium.dev/downloads)

Firefox will protect you from installing addons from unfamiliar locations, so you will need to click ‘Allow’ to proceed with the installation, as shown in the following screenshot.

When downloading from Firefox, you’ll be presented with the following window.

Select Install Now. The Firefox Add-ons window pops up, first showing a progress bar, and when the download is complete, displays the following.

Restart Firefox. After Firefox reboots you will find the Selenium-IDE listed under the Firefox Tools menu.

## Opening the IDE

To run the Selenium-IDE, simply select it from the Firefox Tools menu. It opens as follows with an empty script-editing window and a menu for loading, or creating new test cases.

## IDE Features

### Menu Bar

The File menu has options for Test Case and Test Suite (suite of Test Cases). Using these you can add a new Test Case, open a Test Case, save a Test Case, export Test Case in a language of your choice. You can also open the recent Test Case. All these options are also available for Test Suite.

The Edit menu allows copy, paste, delete, undo, and select all operations for editing the commands in your test case. The Options menu allows the changing of settings. You can set the timeout value for certain commands, add user-defined user extensions to the base set of Selenium commands, and specify the format (language) used when saving your test cases. The Help menu is the standard Firefox Help menu; only one item on this menu–UI-Element Documentation–pertains to Selenium-IDE.

### Toolbar

The toolbar contains buttons for controlling the execution of your test cases, including a step feature for debugging your test cases. The right-most button, the one with the red-dot, is the record button.

Speed Control: controls how fast your test case runs.

Run All: Runs the entire test suite when a test suite with multiple test cases is loaded.

Run: Runs the currently selected test. When only a single test is loaded this button and the Run All button have the same effect.

Pause/Resume: Allows stopping and re-starting of a running test case.

Step: Allows you to “step” through a test case by running it one command at a time. Use for debugging test cases.

TestRunner Mode: Allows you to run the test case in a browser loaded with the Selenium-Core TestRunner. The TestRunner is not commonly used now and is likely to be deprecated. This button is for evaluating test cases for backwards compatibility with the TestRunner. Most users will probably not need this button.

Apply Rollup Rules: This advanced feature allows repetitive sequences of Selenium commands to be grouped into a single action. Detailed documentation on rollup rules can be found in the UI-Element Documentation on the Help menu.

### Test Case Pane

Your script is displayed in the test case pane. It has two tabs, one for displaying the command and their parameters in a readable “table” format.

The other tab - Source displays the test case in the native format in which the file will be stored. By default, this is HTML although it can be changed to a programming language such as Java or C#, or a scripting language like Python. See the Options menu for details. The Source view also allows one to edit the test case in its raw form, including copy, cut and paste operations.

The Command, Target, and Value entry fields display the currently selected command along with its parameters. These are entry fields where you can modify the currently selected command. The first parameter specified for a command in the Reference tab of the bottom pane always goes in the Target field. If a second parameter is specified by the Reference tab, it always goes in the Value field.

If you start typing in the Command field, a drop-down list will be populated based on the first characters you type; you can then select your desired command from the drop-down.

### Log/Reference/UI-Element/Rollup Pane

The bottom pane is used for four different functions–Log, Reference, UI-Element, and Rollup–depending on which tab is selected.

#### Log

When you run your test case, error messages and information messages showing the progress are displayed in this pane automatically, even if you do not first select the Log tab. These messages are often useful for test case debugging. Notice the Clear button for clearing the Log. Also notice the Info button is a drop-down allowing selection of different levels of information to log.

#### Reference

The Reference tab is the default selection whenever you are entering or modifying Selenese commands and parameters in Table mode. In Table mode, the Reference pane will display documentation on the current command. When entering or modifying commands, whether from Table or Source mode, it is critically important to ensure that the parameters specified in the Target and Value fields match those specified in the parameter list in the Reference pane. The number of parameters provided must match the number specified, the order of parameters provided must match the order specified, and the type of parameters provided must match the type specified. If there is a mismatch in any of these three areas, the command will not run correctly.

While the Reference tab is invaluable as a quick reference, it is still often necessary to consult the Selenium Reference document.

#### UI-Element and Rollup

Detailed information on these two panes (which cover advanced features) can be found in the UI-Element Documentation on the Help menu of Selenium-IDE.

## Building Test Cases

There are three primary methods for developing test cases. Frequently, a test developer will require all three techniques.

### Recording

Many first-time users begin by recording a test case from their interactions with a website. When Selenium-IDE is first opened, the record button is ON by default. If you do not want Selenium-IDE to begin recording automatically you can turn this off by going under Options > Options… and deselecting “Start recording immediately on open.”

During recording, Selenium-IDE will automatically insert commands into your test case based on your actions. Typically, this will include:

* clicking a link - click or clickAndWait commands
* entering values - type command
* selecting options from a drop-down listbox - select command
* clicking checkboxes or radio buttons - click command

Here are some “gotchas” to be aware of:

* The type command may require clicking on some other area of the web page for it to record.
* Following a link usually records a click command. You will often need to change this to clickAndWait to ensure your test case pauses until the new page is completely loaded. Otherwise, your test case will continue running commands before the page has loaded all its UI elements. This will cause unexpected test case failures.

### Adding Verifications and Asserts With the Context Menu

Your test cases will also need to check the properties of a web-page. This requires assert and verify commands. We won’t describe the specifics of these commands here; that is in the chapter on Selenium Commands – “Selenese”. Here we’ll simply describe how to add them to your test case.

With Selenium-IDE recording, go to the browser displaying your test application and right click anywhere on the page. You will see a context menu showing verify and/or assert commands.

The first time you use Selenium, there may only be one Selenium command listed. As you use the IDE however, you will find additional commands will quickly be added to this menu. Selenium-IDE will attempt to predict what command, along with the parameters, you will need for a selected UI element on the current web-page.

Let’s see how this works. Open a web-page of your choosing and select a block of text on the page. A paragraph or a heading will work fine. Now, right-click the selected text. The context menu should give you a verifyTextPresent command and the suggested parameter should be the text itself.

Also, notice the Show All Available Commands menu option. This shows many, many more commands, again, along with suggested parameters, for testing your currently selected UI element.

Try a few more UI elements. Try right-clicking an image, or a user control like a button or a checkbox. You may need to use Show All Available Commands to see options other than verifyTextPresent. Once you select these other options, the more commonly used ones will show up on the primary context menu. For example, selecting verifyElementPresent for an image should later cause that command to be available on the primary context menu the next time you select an image and right-click.

Again, these commands will be explained in detail in the chapter on Selenium commands. For now though, feel free to use the IDE to record and select commands into a test case and then run it. You can learn a lot about the Selenium commands simply by experimenting with the IDE.

### Editing

#### Insert Command

##### Table View

Select the point in your test case where you want to insert the command. To do this, in the Test Case Pane, left-click on the line where you want to insert a new command. Right-click and select Insert Command; the IDE will add a blank line just ahead of the line you selected. Now use the command editing text fields to enter your new command and its parameters.

##### Source View

Select the point in your test case where you want to insert the command. To do this, in the Test Case Pane, left-click between the commands where you want to insert a new command, and enter the HTML tags needed to create a 3-column row containing the Command, first parameter (if one is required by the Command), and second parameter (again, if one is required to locate an element) and third parameter(again, if one is required to have a value). Example:

```html
<tr>
    <td>Command</td>
    <td>target (locator)</td>
    <td>Value</td>
</tr>
```

|            |              |       |
| ---------- | ------------ | ----- |
| verifyText | //div//a\[2] | Login |

The parameters are not always required; it depends on the command. In some cases both are required, in others one parameter is required, and in still others the command may take no parameters at all. Here are a couple more examples:

|                   |             |                         |
| ----------------- | ----------- | ----------------------- |
| goBackAndWait     |             |                         |
| verifyTextPresent |             | Welcome to My Home Page |
| type              | id=phone    | (555) 666-7066          |
| type              | id=address1 | ${myVariableAddress}    |

```html
<table>
    <tr><td>open</td><td>/download/</td><td></td></tr>
    <tr><td>assertTitle</td><td></td><td>Downloads</td></tr>
    <tr><td>verifyText</td><td>//h2</td><td>Downloads</td></tr>
</table>
```

Rendered as a table in a browser this would look like the following:

|             |            |           |
| ----------- | ---------- | --------- |
| open        | /download/ |           |
| assertTitle |            | Downloads |
| verifyText  | //h2       | Downloads |

The Selenese HTML syntax can be used to write and run tests without requiring knowledge of a programming language. With a basic knowledge of selenese and Selenium-IDE you can quickly produce and run testcases.

## Test Suites

A test suite is a collection of tests. Often one will run all the tests in a test suite as one continuous batch-job.

When using Selenium-IDE, test suites also can be defined using a simple HTML file. The syntax again is simple. An HTML table defines a list of tests where each row defines the filesystem path to each test. An example tells it all.

```html
<html>
<head>
<title>Test Suite Function Tests - Priority 1</title>
</head>
<body>
<table>
  <tr><td><b>Suite Of Tests</b></td></tr>
  <tr><td><a href="./Login.html">Login</a></td></tr>
  <tr><td><a href="./SearchValues.html">Test Searching for Values</a></td></tr>
  <tr><td><a href="./SaveValues.html">Test Save</a></td></tr>
</table>
</body>
</html>
```

| Command     | Target     | Value        |
| ----------- | ---------- | ------------ |
| open        | /download/ |              |
| assertTitle |            | Downloads    |
| verifyText  | //h2       | Downloads    |
| assertTable | 1.2.1      | Selenium IDE |
| verifyTable | 1.2.2      | June 3, 2008 |
| verifyTable | 1.2.3      | 1.0 beta 2   |

The above example first opens a page and then “asserts” that the correct page is loaded by comparing the title with the expected value. Only if this passes will the following command run and “verify” that the text is present in the expected location. The test case then “asserts” the first column in the second row of the first table contains the expected value, and only if this passed will the remaining cells in that row be “verified”.

### **verifyTextPresent**

The command `verifyTextPresent` is used to verify specific text exists somewhere on the page. It takes a single argument–the text pattern to be verified. For example:

| Command           | Target             | Value |
| ----------------- | ------------------ | ----- |
| verifyTextPresent | Marketing Analysis |       |

This would cause Selenium to search for, and verify, that the text string “Marketing Analysis” appears somewhere on the page currently being tested. Use verifyTextPresent when you are interested in only the text itself being present on the page. Do not use this when you also need to test where the text occurs on the page.

### **verifyElementPresent**

Use this command when you must test for the presence of a specific UI element, rather than its content. This verification does not check the text, only the HTML tag. One common use is to check for the presence of an image.

| Command              | Target      | Value |
| -------------------- | ----------- | ----- |
| verifyElementPresent | //div/p/img |       |

This command verifies that an image, specified by the existence of an HTML tag, is present on the page, and that it follows a

tag and a

tag. The first (and only) parameter is a locator for telling the Selenese command how to find the element. Locators are explained in the next section.

`verifyElementPresent` can be used to check the existence of any HTML tag within the page. You can check the existence of links, paragraphs, divisions

, etc. Here are a few more examples.

| Command              | Target                        | Value |
| -------------------- | ----------------------------- | ----- |
| verifyElementPresent | //div/p                       |       |
| verifyElementPresent | //div/a                       |       |
| verifyElementPresent | id=Login                      |       |
| verifyElementPresent | link=Go to Marketing Research |       |
| verifyElementPresent | //a\[2]                       |       |
| verifyElementPresent | //head/title                  |       |

These examples illustrate the variety of ways a UI element may be tested. Again, locators are explained in the next section.

### **verifyText**

Use `verifyText` when both the text and its UI element must be tested. verifyText must use a locator. If you choose an *XPath* or *DOM* locator, you can verify that specific text appears at a specific location on the page relative to other UI components on the page.

| Command    | Target              | Value                                                               |
| ---------- | ------------------- | ------------------------------------------------------------------- |
| verifyText | //table/tr/td/div/p | This is my text and it occurs right after the div inside the table. |

## Locating Elements

For many Selenium commands, a target is required. This target identifies an element in the content of the web application, and consists of the location strategy followed by the location in the format `locatorType=location`. The locator type can be omitted in many cases. The various locator types are explained below with examples for each.

### Locating by Identifier

This is probably the most common method of locating elements and is the catch-all default when no recognized locator type is used. With this strategy, the first element with the id attribute value matching the location will be used. If no element has a matching id attribute, then the first element with a name attribute matching the location will be used.

For instance, your page source could have id and name attributes as follows:

```html
  <html>
   <body>
    <form id="loginForm">
     <input name="username" type="text" />
     <input name="password" type="password" />
     <input name="continue" type="submit" value="Login" />
    </form>
   </body>
  <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
    </body>
   <html>
```

* `id=loginForm` (3)

### Locating by Name

The name locator type will locate the first element with a matching name attribute. If multiple elements have the same value for a name attribute, then you can use filters to further refine your location strategy. The default filter type is value (matching the value attribute).

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
  <html>
   <body>
    <p>Are you sure you want to do this?</p>
    <a href="continue.html">Continue</a> 
    <a href="cancel.html">Cancel</a>
  </body>
  <html>
```

* `link=Continue` (4)
* `link=Cancel` (5)

### Locating by DOM

The Document Object Model represents an HTML document and can be accessed using JavaScript. This location strategy takes JavaScript that evaluates to an element on the page, which can be simply the element’s location using the hierarchical dotted notation.

Since only `dom` locators start with “document”, it is not necessary to include the `dom=` label when specifying a DOM locator.

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input class="required" name="username" type="text" />
      <input class="required passfield" name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | glob:\*Film\*Television\*             |       |

The actual title of the page reached by clicking on the link was “De Anza Film And Television Department - Menu”. By using a pattern rather than the exact text, the `verifyTitle` will pass as long as the two words “Film” and “Television” appear (in that order) anywhere in the page’s title. For example, if the page’s owner should shorten the title to just “Film & Television Department,” the test would still pass. Using a pattern for both a link and a simple test that the link worked (such as the `verifyTitle` above does) can greatly reduce the maintenance for such test cases.

#### Regular Expression Patterns

*Regular expression* patterns are the most powerful of the three types of patterns that Selenese supports. Regular expressions are also supported by most high-level programming languages, many text editors, and a host of tools, including the Linux/Unix command-line utilities **grep**, **sed**, and **awk**. In Selenese, regular expression patterns allow a user to perform many tasks that would be very difficult otherwise. For example, suppose your test needed to ensure that a particular table cell contained nothing but a number. `regexp: [0-9]+` is a simple pattern that will match a decimal number of any length.

Whereas Selenese globbing patterns support only the **\*** and **\[ ]** (character class) features, Selenese regular expression patterns offer the same wide array of special characters that exist in JavaScript. Below are a subset of those special characters:

| PATTERN | MATCH                                                                            |
| ------- | -------------------------------------------------------------------------------- |
| .       | any single character                                                             |
| \[ ]    | character class: any single character that appears inside the brackets           |
| \*      | quantifier: 0 or more of the preceding character (or group)                      |
| +       | quantifier: 1 or more of the preceding character (or group)                      |
| ?       | quantifier: 0 or 1 of the preceding character (or group)                         |
| {1,5}   | quantifier: 1 through 5 of the preceding character (or group)                    |
| \|      | alternation: the character/group on the left or the character/group on the right |
| ( )     | grouping: often used with alternation and/or quantifier                          |

Regular expression patterns in Selenese need to be prefixed with either `regexp:` or `regexpi:`. The former is case-sensitive; the latter is case-insensitive.

A few examples will help clarify how regular expression patterns can be used with Selenese commands. The first one uses what is probably the most commonly used regular expression pattern–**.\*** (“dot star”). This two-character sequence can be translated as “0 or more occurrences of any character” or more simply, “anything or nothing.” It is the equivalent of the one-character globbing pattern **\*** (a single asterisk).

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | regexp:.\*Film.\*Television.\*        |       |

The example above is functionally equivalent to the earlier example that used globbing patterns for this same test. The only differences are the prefix (**regexp:** instead of **glob:**) and the “anything or nothing” pattern (**.\*** instead of just **\***).

The more complex example below tests that the Yahoo! Weather page for Anchorage, Alaska contains info on the sunrise time:

| Command           | Target                                            | Value |
| ----------------- | ------------------------------------------------- | ----- |
| open              | <http://weather.yahoo.com/forecast/USAK0012.html> |       |
| verifyTextPresent | regexp:Sunrise: \*\[0-9]{1,2}:\[0-9]{2} \[ap]m    |       |

Let’s examine the regular expression above one part at a time:

|              |                                                      |
| ------------ | ---------------------------------------------------- |
| `Sunrise: *` | The string **Sunrise:** followed by 0 or more spaces |
| `[0-9]{1,2}` | 1 or 2 digits (for the hour of the day)              |
| `:`          | The character **:** (no special characters involved) |
| `[0-9]{2}`   | 2 digits (for the minutes) followed by a space       |
| `[ap]m`      | “a” or “p” followed by “m” (am or pm)                |

#### Exact Patterns

The **exact** type of Selenium pattern is of marginal usefulness. It uses no special characters at all. So, if you needed to look for an actual asterisk character (which is special for both globbing and regular expression patterns), the **exact** pattern would be one way to do that. For example, if you wanted to select an item labeled “Real \*” from a dropdown, the following code might work or it might not. The asterisk in the `glob:Real *` pattern will match anything or nothing. So, if there was an earlier select option labeled “Real Numbers,” it would be the option selected rather than the “Real \*” option.

| Command | Target   | Value        |
| ------- | -------- | ------------ |
| select  | //select | glob:Real \* |

In order to ensure that the “Real \*” item would be selected, the `exact:` prefix could be used to create an **exact** pattern as shown below:

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| select  | //select | exact:Real \* |

But the same effect could be achieved via escaping the asterisk in a regular expression pattern:

| Command | Target   | Value            |
| ------- | -------- | ---------------- |
| select  | //select | regexp:Real \\\* |

| Command | Target            | Value |
| ------- | ----------------- | ----- |
| store   | <paul@mysite.org> |       |

Later in your script, you’ll want to use the stored value of your variable. To access the value of a variable, enclose the variable in curly brackets ({}) and precede it with a dollar sign like this.

| Command    | Target  | Value         |
| ---------- | ------- | ------------- |
| verifyText | //div/p | \\${userName} |

A common use of variables is for storing input for an input field.

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| type    | id=login | \\${userName} |

| Command         | Target                                         | Value       |
| --------------- | ---------------------------------------------- | ----------- |
| store           | 10                                             | hits        |
| storeXpathCount | //blockquote                                   | blockquotes |
| storeEval       | storedVars\[‘hits’].storedVars\[‘blockquotes’] | paragraphs  |

This next example illustrates how a JavaScript snippet can include calls to methods, in this case the JavaScript String object’s `toUpperCase` method and `toLowerCase` method.

| Command   | Target                            | Value |
| --------- | --------------------------------- | ----- |
| store     | Edith Wharton                     | name  |
| storeEval | storedVars\[’name’].toUpperCase() | uc    |
| storeEval | storedVars\[’name’].toUpperCase() | lc    |

#### JavaScript Usage with Non-Script Parameters

JavaScript can also be used to help generate values for parameters, even when the parameter is not specified to be of type **script**.\
However, in this case, special syntax is required–the *entire* parameter value must be prefixed by `javascript{` with a trailing `}`, which encloses the JavaScript snippet, as in `javascript{*yourCodeHere*}`. Below is an example in which the `type` command’s second parameter `value` is generated via JavaScript code using this special syntax:

| Command | Target            | Value                                                 |
| ------- | ----------------- | ----------------------------------------------------- |
| store   | league of nations | searchString                                          |
| type    | q                 | javascript{storedVars\[‘searchString’].toUpperCase()} |

## *echo* - The Selenese Print Command

Selenese has a simple command that allows you to print text to your test’s output. This is useful for providing informational progress notes in your test which display on the console as your test is running. These notes also can be used to provide context within your test result reports, which can be useful for finding where a defect exists on a page in the event your test finds a problem. Finally, echo statements can be used to print the contents of Selenium variables.

| Command | Target                    | Value |
| ------- | ------------------------- | ----- |
| echo    | Testing page footer now.  |       |
| echo    | Username is \\${userName} |       |

## Alerts, Popups, and Multiple Windows

Suppose that you are testing a page that looks like this.

```html
  <!DOCTYPE HTML>
  <html>
  <head>
    <script type="text/javascript">
      function output(resultText){
        document.getElementById('output').childNodes[0].nodeValue=resultText;
      }

      function show_confirm(){
        var confirmation=confirm("Chose an option.");
        if (confirmation==true){
          output("Confirmed.");
        }
        else{
          output("Rejected!");
        }
      }
      
      function show_alert(){
        alert("I'm blocking!");
        output("Alert is gone.");
      }
      function show_prompt(){
        var response = prompt("What's the best web QA tool?","Selenium");
        output(response);
      }
      function open_window(windowName){
        window.open("newWindow.html",windowName);
      }
      </script>
  </head>
  <body>

    <input type="button" id="btnConfirm" onclick="show_confirm()" value="Show confirm box" />
    <input type="button" id="btnAlert" onclick="show_alert()" value="Show alert" />
    <input type="button" id="btnPrompt" onclick="show_prompt()" value="Show prompt" />
    <a href="newWindow.html" id="lnkNewWindow" target="_blank">New Window Link</a>
    <input type="button" id="btnNewNamelessWindow" onclick="open_window()" value="Open Nameless Window" />
    <input type="button" id="btnNewNamedWindow" onclick="open_window('Mike')" value="Open Named Window" />

    <br />
    <span id="output">
    </span>
  </body>
  </html>
```

The user must respond to alert/confirm boxes, as well as moving focus to newly opened popup windows. Fortunately, Selenium can cover JavaScript pop-ups.

But before we begin covering alerts/confirms/prompts in individual detail, it is helpful to understand the commonality between them. Alerts, confirmation boxes and prompts all have variations of the following

| Command                   | Description                                                           |
| ------------------------- | --------------------------------------------------------------------- |
| assertFoo(pattern)        | throws error if pattern doesn’t match the text of the pop-up          |
| assertFooPresent          | throws error if pop-up is not available                               |
| assertFooNotPresent       | throws error if any pop-up is present                                 |
| storeFoo(variable)        | stores the text of the pop-up in a variable                           |
| storeFooPresent(variable) | stores the text of the pop-up in a variable and returns true or false |

When running under Selenium, JavaScript pop-ups will not appear. This is because the function calls are actually being overridden at runtime by Selenium’s own JavaScript. However, just because you cannot see the pop-up doesn’t mean you don’t have to deal with it. To handle a pop-up, you must call its `assertFoo(pattern)` function. If you fail to assert the presence of a pop-up your next command will be blocked and you will get an error similar to the following `[error] Error: There was an unexpected Confirmation! [Chose an option.]`

### Alerts

Let’s start with alerts because they are the simplest pop-up to handle. To begin, open the HTML sample above in a browser and click on the “Show alert” button. You’ll notice that after you close the alert the text “Alert is gone.” is displayed on the page. Now run through the same steps with Selenium IDE recording, and verify the text is added after you close the alert. Your test will look something like this:

| Command           | Target         | Value |
| ----------------- | -------------- | ----- |
| open              | /              |       |
| click             | btnAlert       |       |
| assertAlert       | I’m blocking!  |       |
| verifyTextPresent | Alert is gone. |       |

You may be thinking “That’s odd, I never tried to assert that alert.” But this is Selenium-IDE handling and closing the alert for you. If you remove that step and replay the test you will get the following error `[error] Error: There was an unexpected Alert! [I'm blocking!]`. You must include an assertion of the alert to acknowledge its presence.

If you just want to assert that an alert is present but either don’t know or don’t care what text it contains, you can use `assertAlertPresent`. This will return true or false, with false halting the test.

### Confirmations

Confirmations behave in much the same way as alerts, with `assertConfirmation` and `assertConfirmationPresent` offering the same characteristics as their alert counterparts. However, by default Selenium will select OK when a confirmation pops up. Try recording clicking on the “Show confirm box” button in the sample page, but click on the “Cancel” button in the popup, then assert the output text. Your test may look something like this:

| Command                        | Target            | Value |
| ------------------------------ | ----------------- | ----- |
| open                           | /                 |       |
| click                          | btnConfirm        |       |
| chooseCancelOnNextConfirmation |                   |       |
| assertConfirmation             | Choose an option. |       |
| verifyTextPresent              | Rejected          |       |

The `chooseCancelOnNextConfirmation` function tells Selenium that all following confirmation should return false. It can be reset by calling chooseOkOnNextConfirmation.

You may notice that you cannot replay this test, because Selenium complains that there is an unhandled confirmation. This is because the order of events Selenium-IDE records causes the click and chooseCancelOnNextConfirmation to be put in the wrong order (it makes sense if you think about it, Selenium can’t know that you’re cancelling before you open a confirmation) Simply switch these two commands and your test will run fine.

### Prompts

Prompts behave in much the same way as alerts, with `assertPrompt` and `assertPromptPresent` offering the same characteristics as their alert counterparts. By default, Selenium will wait for you to input data when the prompt pops up. Try recording clicking on the “Show prompt” button in the sample page and enter “Selenium” into the prompt. Your test may look something like this:

| Command            | Target                       | Value |
| ------------------ | ---------------------------- | ----- |
| open               | /                            |       |
| answerOnNextPrompt | Selenium!                    |       |
| click              | id=btnPrompt                 |       |
| assertPrompt       | What’s the best web QA tool? |       |
| verifyTextPresent  | Selenium!                    |       |

```html
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Sample Selenium Test Suite</title>
    </head>
    <body>
        <table cellpadding="1" cellspacing="1" border="1">
            <thead>
                <tr><td>Test Cases for De Anza A-Z Directory Links</td></tr>
            </thead>
        <tbody>
            <tr><td><a href="./a.html">A Links</a></td></tr>
            <tr><td><a href="./b.html">B Links</a></td></tr>
            <tr><td><a href="./c.html">C Links</a></td></tr>
            <tr><td><a href="./d.html">D Links</a></td></tr>
        </tbody>
        </table>
    </body>
</html>
```

***

*error loading test case: no command found*

You’ve used **File=>Open** to try to open a test suite file. Use **File=>Open Test Suite** instead.

An enhancement request has been raised to improve this error message. See [issue 1010](http://code.google.com/p/selenium/issues/detail?id=1010).

***

This type of **error** may indicate a timing problem, i.e., the element specified by a locator in your command wasn’t fully loaded when the command was executed. Try putting a **pause 5000** before the command to determine whether the problem is indeed related to timing. If so, investigate using an appropriate **waitFor\*** or **\*AndWait** command before the failing command.

***

Whenever your attempt to use variable substitution fails as is the case for the **open** command above, it indicates that you haven’t actually created the variable whose value you’re trying to access. This is sometimes due to putting the variable in the **Value** field when it should be in the **Target** field or vice versa. In the example above, the two parameters for the **store** command have been erroneously placed in the reverse order of what is required. For any Selenese command, the first required parameter must go in the **Target** field, and the second required parameter (if one exists) must go in the **Value** field.

***

*error loading test case: \[Exception… “Component returned failure code: 0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND) \[nsIFileInputStream.init]” nresult: “0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND)” location: “JS frame :: chrome://selenium-ide/content/file-utils.js :: anonymous :: line 48” data: no]*

One of the test cases in your test suite cannot be found. Make sure that the test case is indeed located where the test suite indicates it is located. Also, make sure that your actual test case files have the .html extension both in their filenames, and in the test suite file where they are referenced.

An enhancement request has been raised to improve this error message. See [issue 1011](http://code.google.com/p/selenium/issues/detail?id=1011).

***

Your extension file’s contents have not been read by Selenium-IDE. Be sure you have specified the proper pathname to the extensions file via **Options=>Options=>General** in the **Selenium Core extensions** field. Also, Selenium-IDE must be restarted after any change to either an extensions file *or* to the contents of the **Selenium Core extensions** field.

# 1 - HTML runner

```shell
[user@localhost ~]$ cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

[user@localhost ~]$ rpm -qa | egrep -i "xvfb|java-1.8|firefox"
xorg-x11-server-Xvfb-1.19.3-11.el7.x86_64
firefox-52.4.0-1.el7.centos.x86_64
java-1.8.0-openjdk-1.8.0.151-1.b12.el7_4.x86_64
java-1.8.0-openjdk-headless-1.8.0.151-1.b12.el7_4.x86_64
```

Test Suite example:

```html
[user@localhost ~]$ cat testsuite.html
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
  <title>Test Suite</title>
</head>
<body>
<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium"><tbody>
<tr><td><b>Test Suite</b></td></tr>
<tr><td><a href="YOUR-TEST-SCENARIO.html">YOUR-TEST-SCENARIO</a></td></tr>
</tbody></table>
</body>
</html>
```

## How to run selenium-html-runner headless

Now, the most important part, an example of how to run the selenium-html-runner! Your experience might vary depending on software combinations - geckodriver/FF/html-runner releases.

```shell
xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
```

```shell
[user@localhost ~]$ xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "*firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
Multi-window mode is longer used as an option and will be ignored.
1510061109691   geckodriver     INFO    geckodriver 0.18.0
1510061109708   geckodriver     INFO    Listening on 127.0.0.1:2885
1510061110162   geckodriver::marionette INFO    Starting browser /usr/bin/firefox with args ["-marionette"]
1510061111084   Marionette      INFO    Listening on port 43229
1510061111187   Marionette      WARN    TLS certificate errors will be ignored for this session
Nov 07, 2017 1:25:12 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
2017-11-07 13:25:12.714:INFO::main: Logging initialized @3915ms to org.seleniumhq.jetty9.util.log.StdErrLog
2017-11-07 13:25:12.804:INFO:osjs.Server:main: jetty-9.4.z-SNAPSHOT
2017-11-07 13:25:12.822:INFO:osjsh.ContextHandler:main: Started o.s.j.s.h.ContextHandler@87a85e1{/tests,null,AVAILABLE}
2017-11-07 13:25:12.843:INFO:osjs.AbstractConnector:main: Started ServerConnector@52102734{HTTP/1.1,[http/1.1]}{0.0.0.0:31892}
2017-11-07 13:25:12.843:INFO:osjs.Server:main: Started @4045ms
Nov 07, 2017 1:25:13 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |open | /auth_mellon.php |  |
Nov 07, 2017 1:25:14 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |waitForPageToLoad | 3000 |  |
.
.
.etc

<td>result:</td>
<td>PASS</td>
```

# 2 - Legacy Selenium IDE Release Notes

| 73% (22) | Samit Badle             |
| -------- | ----------------------- |
| 16%( 5)  | Adam Goucher            |
| 6% (2)   | Dave Hunt               |
| 3% (1)   | Santiago Suarez Ordoñez |
| 3% (1)   | Simon Stewart           |

----
url: https://www.selenium.dev/zh-cn/_print/documentation/webdriver/bidi/cdp/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/webdriver/bidi/cdp/).

# Chrome DevTools 协议

使用 Selenium 操作 Chrome DevTools 协议的示例。 CDP 的支持是临时的，直到 WebDriver BiDi 实现为止。

* 1: [Chrome DevTools Logging Features](#pg-9d5465902a3ed9245038d9cc7246ab1b)
* 2: [Chrome DevTools Network Features](#pg-488c9d6e4776351bfd626e77722e2014)
* 3: [Chrome DevTools Script Features](#pg-a44b21884e579ce2bd3057f9030cd923)

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/CdpTest.java#L22-L27)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/CdpTest.java

```java
package dev.selenium.bidi.cdp;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chromium.HasCdp;

import java.util.HashMap;
import java.util.Map;

public class CdpTest extends BaseTest {
  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
  }

  @Test
  public void setCookie() {
    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);

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }
}
```

```py
    cookie = {'name': 'cheese',
              'value': 'gouda',
              'domain': 'www.selenium.dev',
              'secure': True}

    driver.execute_cdp_cmd('Network.setCookie', cookie)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_cdp.py#L2-L7)

##### /examples/python/tests/bidi/cdp/test\_cdp.py

```py
def test_set_cookie(driver):
    cookie = {'name': 'cheese',
              'value': 'gouda',
              'domain': 'www.selenium.dev',
              'secure': True}

    driver.execute_cdp_cmd('Network.setCookie', cookie)

    driver.get('https://www.selenium.dev')
    cheese = driver.get_cookie(cookie['name'])

    assert cheese['value'] == 'gouda'
```

```cs
            var cookie = new Dictionary<string, object>
            {
                { "name", "cheese" },
                { "value", "gouda" },
                { "domain", "www.selenium.dev" },
                { "secure", true }
            };
            ((ChromeDriver)driver).ExecuteCdpCommand("Network.setCookie", cookie);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/CDPTest.cs#L14-L21)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/CDPTest.cs

```cs
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class CDPTest : BaseChromeTest
    {
        [TestMethod]
        public void SetCookie()
        {
            var cookie = new Dictionary<string, object>
            {
                { "name", "cheese" },
                { "value", "gouda" },
                { "domain", "www.selenium.dev" },
                { "secure", true }
            };
            ((ChromeDriver)driver).ExecuteCdpCommand("Network.setCookie", cookie);
            
            driver.Url = "https://www.selenium.dev";
            Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);

        }
    }
}
```

```rb
    driver.execute_cdp('Network.setCookie',
                       name: 'cheese',
                       value: 'gouda',
                       domain: 'www.selenium.dev',
                       secure: true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/cdp_spec.rb#L9-L13)

##### /examples/ruby/spec/bidi/cdp/cdp\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'sets cookie' do
    driver.execute_cdp('Network.setCookie',
                       name: 'cheese',
                       value: 'gouda',
                       domain: 'www.selenium.dev',
                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end
end
```

# 1 - Chrome DevTools Logging Features

```java
    ((HasLogEvents) driver).onLogEvent(consoleEvent(e -> messages.add(e.getMessages().get(0))));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/LoggingTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/LoggingTest.java

```java
package dev.selenium.bidi.cdp;

import static org.openqa.selenium.devtools.events.CdpEventTypes.consoleEvent;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.CopyOnWriteArrayList;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.HasLogEvents;
import org.openqa.selenium.support.ui.WebDriverWait;

public class LoggingTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void consoleLogs() {
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    CopyOnWriteArrayList<String> messages = new CopyOnWriteArrayList<>();

    ((HasLogEvents) driver).onLogEvent(consoleEvent(e -> messages.add(e.getMessages().get(0))));

    driver.findElement(By.id("consoleLog")).click();
    driver.findElement(By.id("consoleError")).click();

    wait.until(_d -> messages.size() > 1);
    Assertions.assertTrue(messages.contains("Hello, world!"));
    Assertions.assertTrue(messages.contains("I am console error"));
  }
}
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_logs.py#L11-12)

##### /examples/python/tests/bidi/cdp/test\_logs.py

```py
import pytest
from selenium.webdriver.common.bidi.console import Console
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log


@pytest.mark.trio
async def test_console_log(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
            driver.find_element(by=By.ID, value='consoleLog').click()

        assert messages["message"] == "Hello, world!"


@pytest.mark.trio
async def test_js_error(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
            driver.find_element(by=By.ID, value='jsException').click()

        assert "Error: Not working" in messages.exception_details.exception.description
```

```cs
            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs#L19-L25)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class LoggingTest : BaseChromeTest
    {
        [TestMethod]
        public async Task ConsoleLogs()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("consoleLog")).Click();
            driver.FindElement(By.Id("consoleError")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => messages.Count > 1);
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Hello, world!"));
            Assert.IsTrue(messages.Contains("I am console error"));
        }
        
        [TestMethod]
        public async Task JsErrors()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("jsException")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !messages.IsNullOrEmpty());
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Uncaught"));
        }
    }
}
```

```rb
    driver.on_log_event(:console) { |log| logs << log.args.first }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/logging_spec.rb#L12)

##### /examples/ruby/spec/bidi/cdp/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'listens for console logs' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    logs = []
    driver.on_log_event(:console) { |log| logs << log.args.first }

    driver.find_element(id: 'consoleLog').click
    driver.find_element(id: 'consoleError').click

    Selenium::WebDriver::Wait.new.until { logs.size > 1 }
    expect(logs).to include 'Hello, world!'
    expect(logs).to include 'I am console error'
  end

  it 'listens for js exception' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    exceptions = []
    driver.on_log_event(:exception) { |exception| exceptions << exception }

    driver.find_element(id: 'jsException').click

    Selenium::WebDriver::Wait.new.until { exceptions.any? }
    expect(exceptions.first&.description).to include 'Error: Not working'
  end
end
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_logs.py#L22-L23)

##### /examples/python/tests/bidi/cdp/test\_logs.py

```py
import pytest
from selenium.webdriver.common.bidi.console import Console
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log


@pytest.mark.trio
async def test_console_log(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
            driver.find_element(by=By.ID, value='consoleLog').click()

        assert messages["message"] == "Hello, world!"


@pytest.mark.trio
async def test_js_error(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
            driver.find_element(by=By.ID, value='jsException').click()

        assert "Error: Not working" in messages.exception_details.exception.description
```

```cs
            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs#L41-L47)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class LoggingTest : BaseChromeTest
    {
        [TestMethod]
        public async Task ConsoleLogs()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("consoleLog")).Click();
            driver.FindElement(By.Id("consoleError")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => messages.Count > 1);
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Hello, world!"));
            Assert.IsTrue(messages.Contains("I am console error"));
        }
        
        [TestMethod]
        public async Task JsErrors()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("jsException")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !messages.IsNullOrEmpty());
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Uncaught"));
        }
    }
}
```

```rb
    driver.on_log_event(:exception) { |exception| exceptions << exception }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/logging_spec.rb#L26)

##### /examples/ruby/spec/bidi/cdp/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'listens for console logs' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    logs = []
    driver.on_log_event(:console) { |log| logs << log.args.first }

    driver.find_element(id: 'consoleLog').click
    driver.find_element(id: 'consoleError').click

    Selenium::WebDriver::Wait.new.until { logs.size > 1 }
    expect(logs).to include 'Hello, world!'
    expect(logs).to include 'I am console error'
  end

  it 'listens for js exception' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    exceptions = []
    driver.on_log_event(:exception) { |exception| exceptions << exception }

    driver.find_element(id: 'jsException').click

    Selenium::WebDriver::Wait.new.until { exceptions.any? }
    expect(exceptions.first&.description).to include 'Error: Not working'
  end
end
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Add Example](/documentation/about/contributing/#creating-examples)

# 2 - Chrome DevTools Network Features

```java
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L41-L43)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
        credentials = base64.b64encode("admin:admin".encode()).decode()
        auth = {'authorization': 'Basic ' + credentials}
        await connection.session.execute(connection.devtools.network.set_extra_http_headers(Headers(auth)))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L13-15)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L25-L32)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L9-L11)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      HttpResponse res = next.execute(req);
                      contentType.add(res.getHeader("Content-Type"));
                      return res;
                    })) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L56-L65)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L46-L51)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L20-L24)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    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!"))))) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L75-L85)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L62-L73)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L31-L35)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L97-L110)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L85-L97)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    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
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L42-L46)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L125-L126)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    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())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L26-L28)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L114-L118)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L56-L57)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    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()));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L142-L157)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L37-L44)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L136-L143)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L68-L71)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    devTools.send(
            Browser.setDownloadBehavior(
                    Browser.SetDownloadBehaviorBehavior.ALLOWANDNAME,
                    Optional.empty(),
                    Optional.of(""),
                    Optional.of(true)));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L171-L176)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    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
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L82-L88)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Add Example](/documentation/about/contributing/#creating-examples)

# 3 - Chrome DevTools Script Features

```java
    ScriptKey key = ((JavascriptExecutor) driver).pin("return arguments;");
    List<Object> arguments =
        (List<Object>) ((JavascriptExecutor) driver).executeScript(key, 1, true, element);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/ScriptTest.java#L32-L34)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/ScriptTest.java

```java
package dev.selenium.bidi.cdp;

import static org.openqa.selenium.devtools.events.CdpEventTypes.domMutation;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.HasLogEvents;
import org.openqa.selenium.support.ui.WebDriverWait;

public class ScriptTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void pinScript() {
    driver.get("https://www.selenium.dev/selenium/web/xhtmlTest.html");
    WebElement element = driver.findElement(By.id("id1"));

    ScriptKey key = ((JavascriptExecutor) driver).pin("return arguments;");
    List<Object> arguments =
        (List<Object>) ((JavascriptExecutor) driver).executeScript(key, 1, true, element);

    Assertions.assertEquals(List.of(1L, true, element), arguments);
  }

  @Test
  public void mutatedElements() {
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    CopyOnWriteArrayList<WebElement> mutations = new CopyOnWriteArrayList<>();

    ((HasLogEvents) driver).onLogEvent(domMutation(e -> mutations.add(e.getElement())));

    driver.findElement(By.id("reveal")).click();

    wait.until(_d -> !mutations.isEmpty());
    Assertions.assertEquals(mutations.get(0), driver.findElement(By.id("revealed")));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs#L21-L22)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs

```cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class ScriptTest : BaseChromeTest
    {
        [TestMethod]
        public async Task PinScript()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/xhtmlTest.html";
            var element = driver.FindElement(By.Id("id1"));

            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);

            var expected = new List<object>
            {
                1L,
                true,
                element
            };
            CollectionAssert.AreEqual(expected, (ICollection)arguments);
        }

        [TestMethod]
        public async Task MutatedElements()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            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();

            driver.FindElement(By.Id("reveal")).Click();
            
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !mutations.IsNullOrEmpty());
            await monitor.DisableDomMutationMonitoring();
            monitor.StopEventMonitoring();

            var revealed = driver.FindElement(By.Id("revealed")); 
            Assert.AreEqual(revealed, mutations[0]);
        }
    }
}
```

```rb
    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/script_spec.rb#L12-L13)

##### /examples/ruby/spec/bidi/cdp/script\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Script' do
  let(:driver) { start_session }

  it 'pins script' do
    driver.get('https://www.selenium.dev/selenium/web/xhtmlTest.html')
    element = driver.find_element(id: 'id1')

    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)

    expect(arguments).to eq([1, true, element])
  end

  it 'gets mutated elements' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'

    mutations = []
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }

    driver.find_element(id: 'reveal').click
    Selenium::WebDriver::Wait.new(timeout: 30).until { mutations.any? }

    expect(mutations).to include(driver.find_element(id: 'revealed'))
  end
end
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).mutation_events() as event:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_script.py#L10-L11)

##### /examples/python/tests/bidi/cdp/test\_script.py

```py
import pytest
import trio
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

@pytest.mark.trio
async def test_mutation(driver):
    async with driver.bidi_connection() as session:
        async with Log(driver, session).mutation_events() as event:
            await trio.to_thread.run_sync(lambda: driver.get('https://www.selenium.dev/selenium/web/dynamic.html'))
            await trio.to_thread.run_sync(lambda: WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "reveal"))))
            await trio.to_thread.run_sync(lambda: driver.find_element(By.ID, "reveal").click())

    assert event["element"] == driver.find_element(By.ID, "revealed")
```

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs#L39-L46)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs

```cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class ScriptTest : BaseChromeTest
    {
        [TestMethod]
        public async Task PinScript()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/xhtmlTest.html";
            var element = driver.FindElement(By.Id("id1"));

            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);

            var expected = new List<object>
            {
                1L,
                true,
                element
            };
            CollectionAssert.AreEqual(expected, (ICollection)arguments);
        }

        [TestMethod]
        public async Task MutatedElements()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            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();

            driver.FindElement(By.Id("reveal")).Click();
            
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !mutations.IsNullOrEmpty());
            await monitor.DisableDomMutationMonitoring();
            monitor.StopEventMonitoring();

            var revealed = driver.FindElement(By.Id("revealed")); 
            Assert.AreEqual(revealed, mutations[0]);
        }
    }
}
```

```rb
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/script_spec.rb#L22)

##### /examples/ruby/spec/bidi/cdp/script\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Script' do
  let(:driver) { start_session }

  it 'pins script' do
    driver.get('https://www.selenium.dev/selenium/web/xhtmlTest.html')
    element = driver.find_element(id: 'id1')

    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)

    expect(arguments).to eq([1, true, element])
  end

  it 'gets mutated elements' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'

    mutations = []
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }

    driver.find_element(id: 'reveal').click
    Selenium::WebDriver::Wait.new(timeout: 30).until { mutations.any? }

    expect(mutations).to include(driver.find_element(id: 'revealed'))
  end
end
```

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/bidi/w3c/browsing_context/
----

# Browsing Context

```java
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L44-L47)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L33-L35)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

    @Test
    void testNavigateToAUrl() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L58-L61)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L48-L50)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L37-L41)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L25-L28)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L50-L55)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L40-L43)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        Assertions.assertNotNull(browsingContext.getId());
        Assertions.assertNotNull(info.getNavigationId());
        Assertions.assertTrue(info.getUrl().contains("/bidi/logEntryAdded.html"));
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L64-L69)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L55-L58)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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"));
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L72-L80)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L67)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L83-L92)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L79-L82)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        Assertions.assertTrue(info.getChildren().get(0).getUrl().contains("formPage.html"));
    }

    @Test
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L95-L108)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L103-L109)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    }

    @Test
    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());
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L111-L123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L103-L109)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window2.close();

        Assertions.assertThrows(BiDiException.class, window2::getTree);
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L126-L133)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.20.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.20.0.0)

```js
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L426-L431)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext tab2 = new BrowsingContext(driver, WindowType.TAB);

        tab2.close();

        Assertions.assertThrows(BiDiException.class, tab2::getTree);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L136-L153)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L115-L118)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L157-L161)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L192-L194)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```js
    await window1.activate()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L204)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L169-L173)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.reload(undefined, 'complete')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L351)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    @Test
    void testDismissUserPromptWithText() {
        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";
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L220-L228)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.handleUserPrompt(true, userText)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L301)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        driver.get("https://www.selenium.dev/selenium/web/coordinates_tests/simple_page.html");

        WebElement element = driver.findElement(By.id("box"));
        Rectangle elementRectangle = element.getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L248-L252)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const response = await browsingContext.captureScreenshot()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L362)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    }

    @Test
    void textCaptureElementScreenshot() {
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L259-L268)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L165-L169)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L275-L280)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const response = await browsingContext.captureElementScreenshot(elementId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L184)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L304-L307)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.setViewport(250, 300)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L335)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L317-L322)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    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'],
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L145-L157)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        wait.until(visibilityOfElementLocated(By.id("imageButton"))).submit();
        wait.until(titleIs("We Arrive Here"));

        browsingContext.back();
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L330-L336)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.back()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L396)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L342-L352)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.forward()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L420)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L359-L365)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.traverseHistory(-1)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L378)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L34-L41)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L23-L28)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L54-L63)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L53-L62)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L81-88)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L70-L78)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L97-104)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L113-123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L86-L97)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L113-123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L150-163)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L170-L181)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0.0)

```js
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L105-L113)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/discouraged/link_spidering/
----

# Navegação por links

Usar o WebDriver para navegar por links não é uma prática recomendada. Não porque não pode ser feito, mas porque WebDriver definitivamente não é a ferramenta ideal para isso. O WebDriver precisa de tempo para inicializar, e pode levar vários segundos, até um minuto dependendo de como seu teste é escrito, apenas para chegar à página e atravessar o DOM.

Em vez de usar o WebDriver para isso, você poderia economizar muito tempo executando um comando [curl](https://curl.se/), ou usando uma biblioteca como BeautifulSoup uma vez que esses métodos não dependem em criar um navegador e navegar para uma página. Você está economizando muito tempo por não usar o WebDriver para essa tarefa.

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/discouraged/gmail_email_and_facebook_logins/
----

# Gmail, email 和 Facebook 登录

由于多种原因, 不建议使用WebDriver登录Gmail和Facebook等网站. 除了违反这些网站的使用条款之外 (您可能会面临帐户被关闭的风险) , 还有其运行速度缓慢且不可靠的因素.

理想的做法是使用电子邮件供应商提供的API, 或者对于Facebook, 使用开发者工具的服务, 该服务是被用于创建测试帐户、朋友等内容的API. 尽管使用API可能看起来有些额外的工作量, 但是您将获得基于速度、可靠性和稳定性的回报. API不会频繁更改, 但是网页和HTML定位符经常变化, 并且需要您更新测试框架的代码.

在任何时候测试使用WebDriver登录第三方站点, 都会增加测试失败的风险, 因为这会使您的测试时间更长. 通常的经验是, 执行时间较长的测试会更加脆弱和不可靠.

符合[W3C conformant](//w3c.github.io/webdriver/webdriver-spec.html) 的WebDriver实现, 也会使用 `WebDriver` 的属性对 `navigator` 对象进行注释, 用于缓解拒绝服务的攻击.

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/browsers/safari/
----

# Funcionalidade específica do Safari

Estas capacidades e características são específicas ao navegador Apple Safari.

Ao invés dos drivers para Chromium e Firefox, o safaridriver faz parte to sistema Operativo. Para activar a automação no Safari, execute o seguinte comando no terminal:

```shell
safaridriver --enable
```

```java
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#24-L25)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

```py
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L9-L10)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

```cs
            var options = new SafariOptions();
            driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/SafariTest.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/Browsers/SafariTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Safari;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("OSX")]
    public class SafariTest
    {
        private SafariDriver driver;

        [TestCleanup]
        public void QuitDriver()
        {
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new SafariOptions();
            driver = new SafariDriver(options);
        }
    }
}
```

```rb
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L8-L9)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

```js
    let driver = new Builder()
      .forBrowser(Browser.SAFARI)
      .setSafariOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/safariSpecificCap.spec.js#L8-L11)

##### /examples/javascript/test/browser/safariSpecificCap.spec.js

```js
const safari = require('selenium-webdriver/safari');
const {Browser, Builder} = require("selenium-webdriver");
const options = new safari.Options();
const process  =  require('node:process');

describe('Should be able to Test Command line arguments', function () {
  (process.platform === 'darwin' ? it : it.skip)('safari caps', async function () {
    let driver = new Builder()
      .forBrowser(Browser.SAFARI)
      .setSafariOptions(options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
val options = SafariOptions()
val driver = SafariDriver(options)
```

```java
                .withLogging(true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `SafariDriverService.SAFARI_DRIVER_LOGGING`\
Property value: `"true"` or `"false"`

[Selenium v4.26](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.26.0)

```py
    service = webdriver.SafariService(enable_logging=True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L17)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L20)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

```java
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#L39-L40)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

```py
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L25-L30)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L38-L39)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

----
url: https://www.selenium.dev/documentation/legacy/selenium_2/team/
----

# Selenium 2.0 Team

----
url: https://www.selenium.dev/zh-cn/documentation/
----

# Selenium 浏览器自动化项目

Selenium 是支持 web 浏览器自动化的一系列工具和库的综合项目。

它提供了扩展来模拟用户与浏览器的交互，用于扩展浏览器分配的分发服务器， 以及用于实现 [W3C WebDriver 规范](//www.w3.org/TR/webdriver/) 的基础结构， 该 规范 允许您为所有主要 Web 浏览器编写可互换的代码。

这个项目是由志愿者贡献者实现的，他们投入了自己数千小时的时间， 并使源代码[免费提供](https://www.selenium.dev/zh-cn/documentation/about/copyright/#许可)给任何人使用、享受和改进。

Selenium 汇集了浏览器供应商，工程师和爱好者，以进一步围绕 Web 平台自动化进行公开讨论。 该项目组织了[一次年度会议](/zh-cn/)，以教学和培养社区。

Selenium 的核心是 [WebDriver](https://www.selenium.dev/zh-cn/documentation/webdriver/)，这是一个编写指令集的接口，可以在许多浏览器中互换运行。 这里有一个最简单的说明：

*
*
*
*
*
*

```java
package dev.selenium.hello;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class HelloSelenium {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://selenium.dev");

        driver.quit();
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/hello/HelloSelenium.java)

```py
from selenium import webdriver


driver = webdriver.Chrome()

driver.get("http://selenium.dev")

driver.quit()
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/hello/hello_selenium.py)

```cs
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Hello;

public static class HelloSelenium
{
    public static void Main()
    {
        var driver = new ChromeDriver();
            
        driver.Navigate().GoToUrl("https://selenium.dev");
            
        driver.Quit();
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/HelloSelenium.cs)

```rb
# frozen_string_literal: true

require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get 'https://selenium.dev'

driver.quit
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/hello/hello_selenium.rb)

```js
const {Builder, Browser} = require('selenium-webdriver');

(async function helloSelenium() {
  let driver = await new Builder().forBrowser(Browser.CHROME).build();

  await driver.get('https://selenium.dev');

  await driver.quit();
})();
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/hello/helloSelenium.js)

```kt
package dev.selenium.hello

import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()

    driver.get("https://selenium.dev")

    driver.quit()
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/hello/HelloSelenium.kt)

请参阅 [概述](https://www.selenium.dev/zh-cn/documentation/overview/) 以检查不同的项目组件, 并确定Selenium是否适合您.

您应该继续阅读 [开始](https://www.selenium.dev/zh-cn/documentation/webdriver/getting_started/), 以了解如何安装Selenium, 将其成功用作测试自动化工具, 并将这样的简单测试扩展为 在大型分布式环境, 以及不同操作系统上的环境上 运行多个浏览器的测试.

***

##### [概述](/zh-cn/documentation/overview/)

Selenium适合你吗? 请参见不同项目组件的概述.

##### [WebDriver](/zh-cn/documentation/webdriver/)

WebDriver以原生的方式驱动浏览器; 在此了解更多内容.

##### [Selenium Manager (测试版)](/zh-cn/documentation/selenium_manager/)

Selenium Manager 是一个用 Rust 语言实现的命令行工具, 为 Selenium 提供了自动化的驱动程序和浏览器管理功能. Selenium 默认绑定使用此工具, 因此您无需下载它, 也不需要在代码中添加任何内容或执行其他操作即可使用它.

##### [Grid](/zh-cn/documentation/grid/)

要在多台计算机上并行运行测试吗? 那么, Grid正是为你准备的.

##### [IE驱动服务器](/zh-cn/documentation/ie_driver_server/)

Internet Explorer驱动是一种实现WebDriver规范的单机服务器.

##### [Selenium IDE](/zh-cn/documentation/ide/)

Selenium IDE是一个记录和回放用户操作的浏览器扩展.

##### [鼓励的行为](/zh-cn/documentation/test_practices/)

Selenium项目的一些测试指南和建议.

##### [Legacy](/zh-cn/documentation/legacy/)

在此部分，您可以找到与Selenium的旧组件有关的所有文档. 这样做纯粹是出于历史原因，而不是鼓励使用已废弃的组件.

##### [关于这个文档](/zh-cn/documentation/about/)

最后修改 April 6, 2025: [\[rb\] do not run hello selenium in examples (efaae63f2b6)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/efaae63f2b66029b5022e5b0348414a1a29c631f)

----
url: https://www.selenium.dev/documentation/test_practices/encouraged/mock_external_services/
----

# Mock external services

Eliminating the dependencies on external services will greatly improve the speed and stability of your tests.

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/getting_started/install_library/
----

# 安装Selenium类库

```xml
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/pom.xml#L35-L38)

##### /examples/java/pom.xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>dev.selenium</groupId>
    <artifactId>selenium-examples</artifactId>
    <version>1.0.0</version>

    <properties>
        <surefire.parallel>1</surefire.parallel>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <selenium.version>4.41.0</selenium.version>
    </properties>

    <repositories>
        <repository>
            <name>Central Portal Snapshots</name>
            <id>central-portal-snapshots</id>
            <url>https://central.sonatype.com/repository/maven-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-grid</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>6.0.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.titusfortner</groupId>
            <artifactId>selenium-logger</artifactId>
            <version>2.4.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.5.5</version>
                <configuration>
                    <properties>
                        <configurationParameters>
                            junit.jupiter.execution.parallel.enabled = true
                            junit.jupiter.execution.parallel.mode.default = concurrent
                            junit.jupiter.execution.parallel.config.strategy = fixed
                            junit.jupiter.execution.parallel.config.fixed.parallelism = ${surefire.parallel}
                            junit.jupiter.execution.parallel.config.fixed.max-pool-size = ${surefire.parallel}
                        </configurationParameters>
                    </properties>
                    <rerunFailingTestsCount>3</rerunFailingTestsCount>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
```

### Gradle

具体的依赖位于项目中的 `build.gradle` 文件中的 `testImplementation`:

```gradle

dependencies {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/build.gradle#L13-L14)

##### /examples/java/build.gradle

```gradle
plugins {
    id 'java'
}

group 'dev.selenium'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

ext['seleniumVersion'] = System.getProperty('selenium.version', '4.41.0')

dependencies {
    testImplementation "org.seleniumhq.selenium:selenium-java:${seleniumVersion}"
    testImplementation "org.seleniumhq.selenium:selenium-grid:${seleniumVersion}"
    testImplementation platform("org.junit:junit-bom:6.0.2")
    testImplementation 'org.junit.jupiter:junit-jupiter-engine'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    testImplementation 'com.titusfortner:selenium-logger:2.4.0'
}

test {
    useJUnitPlatform()
}
```

该库所支持的Python版本最低版本可以在 `支持的Python版本` 章节中找到 [PyPi](https://pypi.org/project/selenium/)

这里提供了几种不同的方式来安装 Selenium .

### Pip

```shell
pip install selenium
```



### 下载

此外你可以从这里下载 [PyPI Built Distribution](https://pypi.org/project/selenium/#files) (selenium-x.x.x.-py3-none-any.whl) 并通过: *pip* 文件安装:

```shell
pip install selenium-x.x.x.-py3-none-any.whl
```



### 在项目中使用

为了在项目中使用它,需要将它添加到 `requirements.txt` 文件中:

```txt
selenium==4.41.0
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/requirements.txt#L1)

##### /examples/python/requirements.txt

```txt
selenium==4.41.0
pytest==9.0.3
trio==0.31.0
pytest-trio==0.8.0
pytest-rerunfailures==16.1
flake8==7.3.0
requests==2.33.0
tox==4.32.0
pytest-xdist==3.8.0
```

Selenium 所支持的所有平台的列表一览 见诸于 [Nuget](https://www.nuget.org/packages/Selenium.WebDriver)

该处阐述了一些安装Selenium的选项.

### 包管理器

```shell
Install-Package Selenium.WebDriver
```



### .NET CLI

```shell
dotnet add package Selenium.WebDriver
```



### CSProj

在 `csproj` 文件里, 具体的依赖 `PackageReference`(包参数) 位于 `ItemGroup` (项目组)中:

```csproj
      <PackageReference Include="Selenium.WebDriver" Version="4.41.0" />
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/SeleniumDocs.csproj#L14)

##### /examples/dotnet/SeleniumDocs/SeleniumDocs.csproj

```csproj
<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <GenerateProgramFile>false</GenerateProgramFile>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
      <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="7.7.1" />
      <PackageReference Include="MSTest.TestAdapter" Version="3.6.0" />
      <PackageReference Include="MSTest.TestFramework" Version="3.6.0" />
      <PackageReference Include="Selenium.Support" Version="4.41.0" />
      <PackageReference Include="Selenium.WebDriver" Version="4.41.0" />
    </ItemGroup>

    <ItemGroup>
      <Folder Include="LocalPackages" />
    </ItemGroup>

</Project>
```

### 其他附加思虑事项

更多的注意事项,适用于使用 Visual Studio Code (vscode) 和 C#

安装兼容的 .NET SDK 作为章节的先决条件 同时安装 vscode 的扩展 (Ctrl-Shift-X)以适配 C# 和 NuGet 可以遵照此处进行 [操作指南](https://docs.microsoft.com/en-us/dotnet/core/tutorials/with-visual-studio-code?pivots=dotnet-5-0) 创建 C# 控制台项目并运行 “Hello World”. 你也可以用命令行 `dotnet new NUnit` 创建NUnit初阶项目. 确保文件 `%appdata%\NuGet\nuget.config` 已经配置完成,就像某位开发者报告的问题一样,它可能因为某种因素被自动清空. 如果 `nuget.config` 是空的,或者未配置的,那么 .NET 创建的Selenium项目可能失败. 加入如下章节到文件 `nuget.config` 如果出现清空的情况:

```
<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />   
  </packageSources>
...
```

更多关于 `nuget.config` 的信息 [点击](https://docs.microsoft.com/en-us/nuget/reference/nuget-config-file). 你可能需要按照自己的需求配置 `nuget.config` .

现在,返回 vscode ,按下 Ctrl-Shift-P, 然后键入 “NuGet Add Package”, 并选择自己需要的 Selenium 包,例如 `Selenium.WebDriver`. 按下回车并选择版本. 现在你可以使用说明文档中关于 C# vscode下的案例了.

你可以查看 Selenium 对 Ruby 版本支持和最低支持. 具体位于 [rubygems.org](https://rubygems.org/gems/selenium-webdriver/)

Selenium 可以使用两种不同方法安装.

### 手动安装

```shell
gem install selenium-webdriver
```



### 加入项目的 gemfile

```gemfile
gem 'selenium-devtools', '= 0.147.0'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/Gemfile#L10)

##### /examples/ruby/Gemfile

```gemfile
# frozen_string_literal: true

source 'https://rubygems.org'

gem 'ffi', '~> 1.15', '>= 1.15.5' if Gem.win_platform? # Windows only
gem 'rake', '~> 13.0'
gem 'rspec', '~> 3.0'
gem 'rubocop', '~> 1.35'
gem 'rubocop-rspec', '~> 3.0'
gem 'selenium-devtools', '= 0.147.0'
gem 'selenium-webdriver', '= 4.43.0'
```

You can find the minimum required version of Node for any given version of Selenium in the 你可以在此查看 Selenium 对 Node 的版本支持情况 位于 `Node Support Policy` 中的相关章节 [npmjs](https://www.npmjs.com/package/selenium-webdriver)

Selenium is typically installed using npm.

### 本地安装

```shell
npm install selenium-webdriver
```



### 加入项目

在你的项目 `package.json`, 必须加入到 `dependencies`:

```json
        "mocha": "11.7.5"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/package.json#L14)

##### /examples/javascript/package.json

```json
{
    "name": "javascript-examples",
    "version": "1.0.0",
    "scripts": {
        "test": "npx mocha test/**/*.spec.js --timeout 120000 --parallel --retries 2"
    },
    "author": "The Selenium project",
    "license": "Apache-2.0",
    "dependencies": {
        "assert": "2.1.0",
        "selenium-webdriver": "4.41.0"
    },
    "devDependencies": {
        "mocha": "11.7.5"
    }
}
```

Use the Java bindings for Kotlin.

## 下一步

[创建你的第一个Selenium脚本](https://www.selenium.dev/zh-cn/documentation/webdriver/getting_started/first_script/)

最后修改 September 2, 2025: [fixed line number to show case selenium maven dependency (#2450) (845ea50bbac)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/845ea50bbac1131c18ea2735554c1611e5369777)

----
url: https://www.selenium.dev/ja/documentation/webdriver/elements/
----

# Web要素

DOM内の要素オブジェクトの識別と操作

ほとんどの人のSeleniumコードの大部分は、Web要素の操作に関連しています。

***

##### [要素を探す](/ja/documentation/webdriver/elements/locators/)

DOM内の1つ以上の特定の要素を識別する方法

##### [Interacting with web elements](/ja/documentation/webdriver/elements/interactions/)

A high-level instruction set for manipulating form controls.

##### [Web要素の検索](/ja/documentation/webdriver/elements/finders/)

提供されたロケーターの値に基づいて要素を検索します。

##### [Web要素に関する情報](/ja/documentation/webdriver/elements/information/)

要素について学ぶことができること。

##### [File Upload](/ja/documentation/webdriver/elements/file_upload/)

最終更新 December 22, 2021: [Japanese Translation of Elements (#899)\[deploy site\] (4b8c3575676)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/4b8c3575676aef8f49a4cdda5f6f4df2298b61a8)

----
url: https://www.selenium.dev/ja/documentation/webdriver/actions_api/
----

# アクション API

仮想化されたデバイス入力アクションを Web ブラウザーに提供するための低レベルのインターフェイス。

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/ActionsTest.java#L21-L28)

##### /examples/java/src/test/java/dev/selenium/actions\_api/ActionsTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;

public class ActionsTest extends BaseChromeTest {
    @Test
    public void pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        long start = System.currentTimeMillis();

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();

        long duration = System.currentTimeMillis() - start;
        Assertions.assertTrue(duration > 2000);
        Assertions.assertTrue(duration < 3000);
    }

    @Test
    public void releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        Actions actions = new Actions(driver);
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        ((RemoteWebDriver) driver).resetInputState();

        actions.sendKeys("a").perform();
        Assertions.assertEquals("A", String.valueOf(clickable.getAttribute("value").charAt(0)));
        Assertions.assertEquals("a", String.valueOf(clickable.getAttribute("value").charAt(1)));
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_actions.py#L13-L20)

##### /examples/python/tests/actions\_api/test\_actions.py

```py
from time import time

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.by import By


def test_pauses(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    start = time()

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()

    duration = time() - start
    assert duration > 2
    assert duration < 3


def test_releases_all(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .click_and_hold(clickable)\
        .key_down(Keys.SHIFT)\
        .key_down("a")\
        .perform()

    ActionBuilder(driver).clear_actions()

    ActionChains(driver).key_down('a').perform()

    assert clickable.get_attribute('value')[0] == "A"
    assert clickable.get_attribute('value')[1] == "a"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs#L18-L25)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class ActionsTest : BaseChromeTest
    {
        [TestMethod]
        public void Pause()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            DateTime start = DateTime.Now;

            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();

            TimeSpan duration = DateTime.Now - start;
            Assert.IsTrue(duration > TimeSpan.FromSeconds(2));
            Assert.IsTrue(duration < TimeSpan.FromSeconds(3));
        }

        [TestMethod]
        public void ReleaseAll()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            var actions = new Actions(driver);
            actions.ClickAndHold(clickable)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            ((WebDriver)driver).ResetInputState();

            actions.SendKeys("a").Perform();
            var value = clickable.GetAttribute("value");
            Assert.AreEqual("A", value[..1]);
            Assert.AreEqual("a", value.Substring(1, 1));
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/actions_spec.rb#L12-L19)

##### /examples/ruby/spec/actions\_api/actions\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Actions' do
  let(:driver) { start_session }

  it 'pauses' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
    start = Time.now

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform

    duration = Time.now - start
    expect(duration).to be > 2
    expect(duration).to be < 3
  end

  it 'releases all' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    action = driver.action
                   .click_and_hold(clickable)
                   .key_down(:shift)
                   .key_down('a')
    action.perform

    driver.action.release_actions

    action.key_down('a').perform
    expect(clickable.attribute('value')[0]).to eq 'A'
    expect(clickable.attribute('value')[-1]).to eq 'a'
  end
end
```

```js
    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/actionsTest.spec.js#L18-L25)

##### /examples/javascript/test/actionsApi/actionsTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Pause and Release All Actions', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('Pause', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const start = Date.now()

    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()

    const end = Date.now() - start
    assert.ok(end > 2000)
    assert.ok(end < 4000)
  })

  it('Clear', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const clickable = driver.findElement(By.id('clickable'))
    await driver.actions()
      .click(clickable)
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    await driver.actions().clear()
    await driver.actions().sendKeys('a').perform()

    const value = await clickable.getAttribute('value')
    assert.deepStrictEqual('A', value.substring(0, 1))
    assert.deepStrictEqual('a', value.substring(1, 2))
  })
})
```

```kt
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/ActionsTest.kt#L22-L29)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/ActionsTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration

class ActionsTest : BaseTest() {

    @Test
    fun pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val start = System.currentTimeMillis()

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 

        val duration = System.currentTimeMillis() - start
        Assertions.assertTrue(duration > 2000)
        Assertions.assertTrue(duration < 4000)
    }

    @Test
    fun releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        val actions = Actions(driver)
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        (driver as RemoteWebDriver).resetInputState()

        actions.sendKeys("a").perform()
        Assertions.assertEquals("A", clickable.getAttribute("value")!!.get(0).toString())
        Assertions.assertEquals("a", clickable.getAttribute("value")!!.get(1).toString())
    }
}
```

```java
        ((RemoteWebDriver) driver).resetInputState();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/ActionsTest.java#L46)

##### /examples/java/src/test/java/dev/selenium/actions\_api/ActionsTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;

public class ActionsTest extends BaseChromeTest {
    @Test
    public void pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        long start = System.currentTimeMillis();

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();

        long duration = System.currentTimeMillis() - start;
        Assertions.assertTrue(duration > 2000);
        Assertions.assertTrue(duration < 3000);
    }

    @Test
    public void releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        Actions actions = new Actions(driver);
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        ((RemoteWebDriver) driver).resetInputState();

        actions.sendKeys("a").perform();
        Assertions.assertEquals("A", String.valueOf(clickable.getAttribute("value").charAt(0)));
        Assertions.assertEquals("a", String.valueOf(clickable.getAttribute("value").charAt(1)));
    }
}
```

```py
    ActionBuilder(driver).clear_actions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_actions.py#L37)

##### /examples/python/tests/actions\_api/test\_actions.py

```py
from time import time

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.by import By


def test_pauses(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    start = time()

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()

    duration = time() - start
    assert duration > 2
    assert duration < 3


def test_releases_all(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .click_and_hold(clickable)\
        .key_down(Keys.SHIFT)\
        .key_down("a")\
        .perform()

    ActionBuilder(driver).clear_actions()

    ActionChains(driver).key_down('a').perform()

    assert clickable.get_attribute('value')[0] == "A"
    assert clickable.get_attribute('value')[1] == "a"
```

```cs
            ((WebDriver)driver).ResetInputState();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs#L44)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class ActionsTest : BaseChromeTest
    {
        [TestMethod]
        public void Pause()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            DateTime start = DateTime.Now;

            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();

            TimeSpan duration = DateTime.Now - start;
            Assert.IsTrue(duration > TimeSpan.FromSeconds(2));
            Assert.IsTrue(duration < TimeSpan.FromSeconds(3));
        }

        [TestMethod]
        public void ReleaseAll()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            var actions = new Actions(driver);
            actions.ClickAndHold(clickable)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            ((WebDriver)driver).ResetInputState();

            actions.SendKeys("a").Perform();
            var value = clickable.GetAttribute("value");
            Assert.AreEqual("A", value[..1]);
            Assert.AreEqual("a", value.Substring(1, 1));
        }
    }
}
```

```rb
    driver.action.release_actions
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/actions_spec.rb#L36)

##### /examples/ruby/spec/actions\_api/actions\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Actions' do
  let(:driver) { start_session }

  it 'pauses' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
    start = Time.now

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform

    duration = Time.now - start
    expect(duration).to be > 2
    expect(duration).to be < 3
  end

  it 'releases all' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    action = driver.action
                   .click_and_hold(clickable)
                   .key_down(:shift)
                   .key_down('a')
    action.perform

    driver.action.release_actions

    action.key_down('a').perform
    expect(clickable.attribute('value')[0]).to eq 'A'
    expect(clickable.attribute('value')[-1]).to eq 'a'
  end
end
```

```js
    await driver.actions().clear()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/actionsTest.spec.js#L42)

##### /examples/javascript/test/actionsApi/actionsTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Pause and Release All Actions', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('Pause', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const start = Date.now()

    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()

    const end = Date.now() - start
    assert.ok(end > 2000)
    assert.ok(end < 4000)
  })

  it('Clear', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const clickable = driver.findElement(By.id('clickable'))
    await driver.actions()
      .click(clickable)
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    await driver.actions().clear()
    await driver.actions().sendKeys('a').perform()

    const value = await clickable.getAttribute('value')
    assert.deepStrictEqual('A', value.substring(0, 1))
    assert.deepStrictEqual('a', value.substring(1, 2))
  })
})
```

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/ActionsTest.kt#L47)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/ActionsTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration

class ActionsTest : BaseTest() {

    @Test
    fun pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val start = System.currentTimeMillis()

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 

        val duration = System.currentTimeMillis() - start
        Assertions.assertTrue(duration > 2000)
        Assertions.assertTrue(duration < 4000)
    }

    @Test
    fun releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        val actions = Actions(driver)
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        (driver as RemoteWebDriver).resetInputState()

        actions.sendKeys("a").perform()
        Assertions.assertEquals("A", clickable.getAttribute("value")!!.get(0).toString())
        Assertions.assertEquals("a", clickable.getAttribute("value")!!.get(1).toString())
    }
}
```

***

##### [Keyboard actions](/ja/documentation/webdriver/actions_api/keyboard/)

A representation of any key input device for interacting with a web page.

##### [Mouse actions](/ja/documentation/webdriver/actions_api/mouse/)

A representation of any pointer device for interacting with a web page.

##### [Pen actions](/ja/documentation/webdriver/actions_api/pen/)

A representation of a pen stylus kind of pointer input for interacting with a web page.

##### [Scroll wheel actions](/ja/documentation/webdriver/actions_api/wheel/)

A representation of a scroll wheel input device for interacting with a web page.

----
url: https://www.selenium.dev/ja/documentation/webdriver/bidi/w3c/
----

# BiDirectional API (W3C compliant)

**Page being translated from English to Japanese. Do you speak Japanese? Help us to translate it by sending us pull requests!

The following list of APIs will be growing as the [WebDriver BiDirectional Protocol](https://w3c.github.io/webdriver-bidi/) 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](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=\&template=feature.md).

***

##### [Browsing Context](/ja/documentation/webdriver/bidi/w3c/browsing_context/)

##### [Browsing Context](/ja/documentation/webdriver/bidi/w3c/input/)

##### [Network](/ja/documentation/webdriver/bidi/w3c/network/)

##### [Script](/ja/documentation/webdriver/bidi/w3c/script/)

##### [BiDirectional API (W3C compliant)](/ja/documentation/webdriver/bidi/w3c/log/)

----
url: https://www.selenium.dev/documentation/test_practices/encouraged/generating_application_state/
----

# Generating application state

Selenium should not be used to prepare a test case. All repetitive actions and preparations for a test case, should be done through other methods. For example, most web UIs have authentication (e.g. a login form). Eliminating logging in via web browser before every test will improve both the speed and stability of the test. A method should be created to gain access to the AUT\* (e.g. using an API to login and set a cookie). Also, creating methods to pre-load data for testing should not be done using Selenium. As mentioned previously, existing APIs should be leveraged to create data for the AUT\*.

\***AUT**: Application under test

----
url: https://www.selenium.dev/documentation/webdriver/actions_api/keyboard/
----

# Keyboard actions

```java
        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L17-L20)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L10-L13)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L13-L16)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L17-L20)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L19-L22)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L30-L35)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L21-L26)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L30-L35)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L25-L30)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L32-L37)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L32-L37)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .sendKeys("abc")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L45-L47)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L34-L36)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs

            new Actions(driver)
                .SendKeys("abc")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L45-L47)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .send_keys('abc')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L39-L41)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .sendKeys('abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L48-L50)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .sendKeys("abc")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L47-L49)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L59-L62)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L45-L48)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L58-L61)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L51-L54)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L59-L63)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L60-L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L70-L84)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L56-L67)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L72-L82)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L64-L74)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L73-L85)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L74-L86)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/support_features/thread_guard/
----

# ThreadGuard

Esta classe está disponível apenas no Java Binding

ThreadGuard verifica se um driver é chamado apenas da mesma thread que o criou. Problemas de threading, especialmente durante a execução de testes em paralelo, podem ter erros misteriosos e difíceis de diagnosticar. Usar este wrapper evita esta categoria de erros e gerará uma exceção quando isso acontecer.

O exemplo a seguir simula um conflito de threads:

```java
public class DriverClash {
  //thread main (id 1) criou este driver
  private WebDriver protectedDriver = ThreadGuard.protect(new ChromeDriver()); 

  static {
    System.setProperty("webdriver.chrome.driver", "<Set path to your Chromedriver>");
  }
  
  //Thread-1 (id 24) está chamando o mesmo driver causando o conflito
  Runnable r1 = () -> {protectedDriver.get("https://selenium.dev");};
  Thread thr1 = new Thread(r1);
   
  void runThreads(){
    thr1.start();
  }

  public static void main(String[] args) {
    new DriverClash().runThreads();
  }
}
```

O resultado mostrado abaixo:

```text
Exception in thread "Thread-1" org.openqa.selenium.WebDriverException:
Thread safety error; this instance of WebDriver was constructed
on thread main (id 1)and is being accessed by thread Thread-1 (id 24)
This is not permitted and *will* cause undefined behaviour
```

Última modificação September 23, 2022: [rename additional features section back to support features to re-emphasize the distinct purpose of support classes (c70272e7f8b)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/c70272e7f8be03fada236fd1f6dc75e81ec79638)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/actions_api/
----

# Actions接口

用于向 Web 浏览器提供虚拟化设备输入操作的低级接口.

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/ActionsTest.java#L21-L28)

##### /examples/java/src/test/java/dev/selenium/actions\_api/ActionsTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;

public class ActionsTest extends BaseChromeTest {
    @Test
    public void pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        long start = System.currentTimeMillis();

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();

        long duration = System.currentTimeMillis() - start;
        Assertions.assertTrue(duration > 2000);
        Assertions.assertTrue(duration < 3000);
    }

    @Test
    public void releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        Actions actions = new Actions(driver);
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        ((RemoteWebDriver) driver).resetInputState();

        actions.sendKeys("a").perform();
        Assertions.assertEquals("A", String.valueOf(clickable.getAttribute("value").charAt(0)));
        Assertions.assertEquals("a", String.valueOf(clickable.getAttribute("value").charAt(1)));
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_actions.py#L13-L20)

##### /examples/python/tests/actions\_api/test\_actions.py

```py
from time import time

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.by import By


def test_pauses(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    start = time()

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()

    duration = time() - start
    assert duration > 2
    assert duration < 3


def test_releases_all(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .click_and_hold(clickable)\
        .key_down(Keys.SHIFT)\
        .key_down("a")\
        .perform()

    ActionBuilder(driver).clear_actions()

    ActionChains(driver).key_down('a').perform()

    assert clickable.get_attribute('value')[0] == "A"
    assert clickable.get_attribute('value')[1] == "a"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs#L18-L25)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class ActionsTest : BaseChromeTest
    {
        [TestMethod]
        public void Pause()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            DateTime start = DateTime.Now;

            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();

            TimeSpan duration = DateTime.Now - start;
            Assert.IsTrue(duration > TimeSpan.FromSeconds(2));
            Assert.IsTrue(duration < TimeSpan.FromSeconds(3));
        }

        [TestMethod]
        public void ReleaseAll()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            var actions = new Actions(driver);
            actions.ClickAndHold(clickable)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            ((WebDriver)driver).ResetInputState();

            actions.SendKeys("a").Perform();
            var value = clickable.GetAttribute("value");
            Assert.AreEqual("A", value[..1]);
            Assert.AreEqual("a", value.Substring(1, 1));
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/actions_spec.rb#L12-L19)

##### /examples/ruby/spec/actions\_api/actions\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Actions' do
  let(:driver) { start_session }

  it 'pauses' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
    start = Time.now

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform

    duration = Time.now - start
    expect(duration).to be > 2
    expect(duration).to be < 3
  end

  it 'releases all' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    action = driver.action
                   .click_and_hold(clickable)
                   .key_down(:shift)
                   .key_down('a')
    action.perform

    driver.action.release_actions

    action.key_down('a').perform
    expect(clickable.attribute('value')[0]).to eq 'A'
    expect(clickable.attribute('value')[-1]).to eq 'a'
  end
end
```

```js
    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/actionsTest.spec.js#L18-L25)

##### /examples/javascript/test/actionsApi/actionsTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Pause and Release All Actions', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('Pause', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const start = Date.now()

    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()

    const end = Date.now() - start
    assert.ok(end > 2000)
    assert.ok(end < 4000)
  })

  it('Clear', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const clickable = driver.findElement(By.id('clickable'))
    await driver.actions()
      .click(clickable)
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    await driver.actions().clear()
    await driver.actions().sendKeys('a').perform()

    const value = await clickable.getAttribute('value')
    assert.deepStrictEqual('A', value.substring(0, 1))
    assert.deepStrictEqual('a', value.substring(1, 2))
  })
})
```

```kt
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/ActionsTest.kt#L22-L29)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/ActionsTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration

class ActionsTest : BaseTest() {

    @Test
    fun pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val start = System.currentTimeMillis()

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 

        val duration = System.currentTimeMillis() - start
        Assertions.assertTrue(duration > 2000)
        Assertions.assertTrue(duration < 4000)
    }

    @Test
    fun releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        val actions = Actions(driver)
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        (driver as RemoteWebDriver).resetInputState()

        actions.sendKeys("a").perform()
        Assertions.assertEquals("A", clickable.getAttribute("value")!!.get(0).toString())
        Assertions.assertEquals("a", clickable.getAttribute("value")!!.get(1).toString())
    }
}
```

```java
        ((RemoteWebDriver) driver).resetInputState();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/ActionsTest.java#L46)

##### /examples/java/src/test/java/dev/selenium/actions\_api/ActionsTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;

public class ActionsTest extends BaseChromeTest {
    @Test
    public void pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        long start = System.currentTimeMillis();

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();

        long duration = System.currentTimeMillis() - start;
        Assertions.assertTrue(duration > 2000);
        Assertions.assertTrue(duration < 3000);
    }

    @Test
    public void releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        Actions actions = new Actions(driver);
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        ((RemoteWebDriver) driver).resetInputState();

        actions.sendKeys("a").perform();
        Assertions.assertEquals("A", String.valueOf(clickable.getAttribute("value").charAt(0)));
        Assertions.assertEquals("a", String.valueOf(clickable.getAttribute("value").charAt(1)));
    }
}
```

```py
    ActionBuilder(driver).clear_actions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_actions.py#L37)

##### /examples/python/tests/actions\_api/test\_actions.py

```py
from time import time

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.by import By


def test_pauses(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    start = time()

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()

    duration = time() - start
    assert duration > 2
    assert duration < 3


def test_releases_all(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .click_and_hold(clickable)\
        .key_down(Keys.SHIFT)\
        .key_down("a")\
        .perform()

    ActionBuilder(driver).clear_actions()

    ActionChains(driver).key_down('a').perform()

    assert clickable.get_attribute('value')[0] == "A"
    assert clickable.get_attribute('value')[1] == "a"
```

```cs
            ((WebDriver)driver).ResetInputState();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs#L44)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class ActionsTest : BaseChromeTest
    {
        [TestMethod]
        public void Pause()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            DateTime start = DateTime.Now;

            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();

            TimeSpan duration = DateTime.Now - start;
            Assert.IsTrue(duration > TimeSpan.FromSeconds(2));
            Assert.IsTrue(duration < TimeSpan.FromSeconds(3));
        }

        [TestMethod]
        public void ReleaseAll()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            var actions = new Actions(driver);
            actions.ClickAndHold(clickable)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            ((WebDriver)driver).ResetInputState();

            actions.SendKeys("a").Perform();
            var value = clickable.GetAttribute("value");
            Assert.AreEqual("A", value[..1]);
            Assert.AreEqual("a", value.Substring(1, 1));
        }
    }
}
```

```rb
    driver.action.release_actions
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/actions_spec.rb#L36)

##### /examples/ruby/spec/actions\_api/actions\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Actions' do
  let(:driver) { start_session }

  it 'pauses' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
    start = Time.now

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform

    duration = Time.now - start
    expect(duration).to be > 2
    expect(duration).to be < 3
  end

  it 'releases all' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    action = driver.action
                   .click_and_hold(clickable)
                   .key_down(:shift)
                   .key_down('a')
    action.perform

    driver.action.release_actions

    action.key_down('a').perform
    expect(clickable.attribute('value')[0]).to eq 'A'
    expect(clickable.attribute('value')[-1]).to eq 'a'
  end
end
```

```js
    await driver.actions().clear()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/actionsTest.spec.js#L42)

##### /examples/javascript/test/actionsApi/actionsTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Pause and Release All Actions', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('Pause', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const start = Date.now()

    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()

    const end = Date.now() - start
    assert.ok(end > 2000)
    assert.ok(end < 4000)
  })

  it('Clear', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const clickable = driver.findElement(By.id('clickable'))
    await driver.actions()
      .click(clickable)
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    await driver.actions().clear()
    await driver.actions().sendKeys('a').perform()

    const value = await clickable.getAttribute('value')
    assert.deepStrictEqual('A', value.substring(0, 1))
    assert.deepStrictEqual('a', value.substring(1, 2))
  })
})
```

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/ActionsTest.kt#L47)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/ActionsTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration

class ActionsTest : BaseTest() {

    @Test
    fun pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val start = System.currentTimeMillis()

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 

        val duration = System.currentTimeMillis() - start
        Assertions.assertTrue(duration > 2000)
        Assertions.assertTrue(duration < 4000)
    }

    @Test
    fun releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        val actions = Actions(driver)
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        (driver as RemoteWebDriver).resetInputState()

        actions.sendKeys("a").perform()
        Assertions.assertEquals("A", clickable.getAttribute("value")!!.get(0).toString())
        Assertions.assertEquals("a", clickable.getAttribute("value")!!.get(1).toString())
    }
}
```

***

##### [键盘操作](/zh-cn/documentation/webdriver/actions_api/keyboard/)

一种适用于任何与网页交互的按键输入设备的表现形式.

##### [鼠标操作](/zh-cn/documentation/webdriver/actions_api/mouse/)

任何用于与网页进行交互的指针设备的表示形式.

##### [触控笔操作](/zh-cn/documentation/webdriver/actions_api/pen/)

一种用于与网页交互的类似笔尖的指针输入设备的表示.

##### [Scroll wheel actions](/zh-cn/documentation/webdriver/actions_api/wheel/)

A representation of a scroll wheel input device for interacting with a web page.

----
url: https://www.selenium.dev/pt-br/_print/documentation/webdriver/troubleshooting/errors/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/webdriver/troubleshooting/errors/).

# Understanding Common Errors

How to solve various problems in your Selenium code.

* 1: [Unable to Locate Driver Error](#pg-1a041d40202643eaad1eb71b29cd7b9b)

* Make sure you are using a proper [Waiting Strategy](https://www.selenium.dev/pt-br/documentation/webdriver/waits/)

[Explicit Waits](https://www.selenium.dev/pt-br/documentation/webdriver/waits/) will likely be your best friend in these instances. A great way is to use `ExpectedCondition.ToBeClickable()` with `WebDriverWait` to wait until the right moment.

As of Selenium 4.6, Selenium downloads the correct driver for you. You shouldn’t need to do anything. If you are using the latest version of Selenium and you are getting an error, please [turn on logging](https://www.selenium.dev/pt-br/documentation/webdriver/troubleshooting/logging/) and [file a bug report](//github.com/seleniumhq/selenium/issues) with that information.

If you want to read more information about how Selenium manages driver downloads for you, you can read about the [Selenium Manager](https://www.selenium.dev/pt-br/documentation/selenium_manager/).

### Use the `PATH` environment variable

This option first requires manually [downloading the driver](/pt-br/documentation/webdriver/troubleshooting/errors/driver_location/#download-the-driver).

This is a flexible option to change location of drivers without having to update your code, and will work on multiple machines without requiring that each machine put the drivers in the same place.

You can either place the drivers in a directory that is already listed in `PATH`, or you can place them in a directory and add it to `PATH`.

*
*
*

To see what directories are already on `PATH`, open a Terminal and execute:

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.bash_profile
source ~/.bash_profile
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Terminal and execute:

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.zshenv
source ~/.zshenv
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Command Prompt and execute:

```shell
echo %PATH%
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
setx PATH "%PATH%;C:\WebDriver\bin"
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver.exe --version
```

| Navegador         | OS Suportado                   | Mantido por      | Download                                                                     | Rastreador de Problemas                                             |
| ----------------- | ------------------------------ | ---------------- | ---------------------------------------------------------------------------- | ------------------------------------------------------------------- |
| Chromium/Chrome   | Windows/macOS/Linux            | Google           | [Downloads](//chromedriver.chromium.org/downloads)                           | [Problemas](//bugs.chromium.org/p/chromedriver/issues/list)         |
| Firefox           | Windows/macOS/Linux            | Mozilla          | [Downloads](//github.com/mozilla/geckodriver/releases)                       | [Problemas](//github.com/mozilla/geckodriver/issues)                |
| Edge              | Windows/macOS/Linux            | Microsoft        | [Downloads](//developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/) | [Problemas](https://github.com/MicrosoftDocs/edge-developer/issues) |
| Internet Explorer | Windows                        | Projeto Selenium | [Downloads](/downloads)                                                      | [Problemas](//github.com/SeleniumHQ/selenium/labels/D-IE)           |
| Safari            | macOS High Sierra e superiores | Apple            | Integrado no Sistema                                                         | [Problemas](//bugreport.apple.com/logon)                            |

Nota: O Opera driver já não inclui as funcionalidades mais recentes do Selenium e oficialmente deixou de ser suportado.

----
url: https://www.selenium.dev/_print/documentation/legacy/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/legacy/).

# Legacy

Documentation related to the legacy components of Selenium. Meant to be kept purely for historical reasons and not as a incentive to use deprecated components.

* 1: [Selenium RC (Selenium 1)](#pg-a76e46944e3b68009240890dd22b057c)
* 2: [Selenium 2](#pg-637f0c199ff3e7476428169ec8fa3382)
* * 2.1: [Migrating from RC to WebDriver](#pg-6d6ce38fefd72ba339f1f94ce93b4b11)
  * 2.2: [Backing Selenium with WebDriver](#pg-b70fabac091738e86524dd8793bcc0bf)
  * 2.3: [Legacy Firefox Driver](#pg-6984c4d03154181ae791e3cd56fd311f)
  * 2.4: [Selenium grid 2](#pg-8ed1a0dc90a43d86e2d25e92a3e7cbd8)
  * 2.5: [History of Grid Platforms](#pg-54595ecbfa5e5d9fb842086d5fc39a0d)
  * 2.6: [Remote WebDriver standalone server](#pg-1b088b432d4645b4106c50b880e5e299)
  * 2.7: [Limitations of scaling up tests in Selenium 2](#pg-993524c9537baa2d57c6eaba7881014f)
  * 2.8: [Stealing focus from Firefox in Linux](#pg-3e28db920e0f683929711b45122a4d4d)
  * 2.9: [Untrusted SSL Certificates](#pg-f0fd86d94624603be663eacc23f25aba)
  * 2.10: [WebDriver For Mobile Browsers](#pg-e1d327a5eb6a8ebaeaca9cdfa4dbbd7d)
  * 2.11: [Frequently Asked Questions for Selenium 2](#pg-36437cf691a726827ecca3a5756760ad)
  * 2.12: [Selenium 2.0 Team](#pg-b18f30320b6067c6959caae4547f4b0c)
  3: [Selenium 3](#pg-8531796b843807e9cc78785f9b7f5cc9)
* * 3.1: [Grid 3](#pg-6b86dc079f63c200ff9d293cde398616)
  * 3.2: [Setting up your own Grid 3](#pg-51d2482692e825414d0ffd833835614e)
  * 3.3: [Components of Grid 3](#pg-88001777a96888486f97550f11bcb985)
  4: [Legacy Selenium IDE](#pg-e13f1313413c04a6f7f0d9678a28facd)
* * 4.1: [HTML runner](#pg-113130e01fcfca255f15dc478eda5567)
  * 4.2: [Legacy Selenium IDE Release Notes](#pg-b425a5d462ec0ada7528ac53a83879b2)
  5: [JSON Wire Protocol Specification](#pg-310e4c9bc9b210dc192617998269d47b)
* 6: [Legacy Selenium Desired Capabilities](#pg-316e9aff150eaba65ac7ba072cd4acfa)
* 7: [Legacy developer documentation](#pg-910e3169e66f4aa306c13e90f27590df)
  * 7.1: [Crazy Fun Build Tool](#pg-2b6c9c51f27a64725c8c0a31b8b03410)
  * 7.2: [Buck Build Tool](#pg-81809b631ab02f068a62c6d946181953)
  * 7.3: [Adding new drivers to Selenium 2 code](#pg-b298e82c015f8bca9f928bf1f7086bfc)
  * 7.4: [Selenium's Continuous Integration Implementation](#pg-7fbb4509f1f8120b35e7ede7afd2208a)
  * 7.5: [Google Summer of Code 2011](#pg-9de634ad30601b09ab6d4dc220dc4fad)
  * 7.6: [Developer Tips](#pg-954466729b10336f6f769f2013a2c081)
  * 7.7: [Snapshot of Roadmaps for Selenium Releases](#pg-39a7dde85bdbfff147088b41161f32a5)

# 1 - Selenium RC (Selenium 1)

```shell
    java -jar selenium-server-standalone-<version-number>.jar
```

This can be simplified by creating a batch or shell executable file (.bat on Windows and .sh on Linux) containing the command above. Then make a shortcut to that executable on your desktop and simply double-click the icon to start the server.

For the server to run you’ll need Java installed and the PATH environment variable correctly configured to run it from the console. You can check that you have Java correctly installed by running the following on a console.

```shell
       java -version
```

|                   |                            |             |
| ----------------- | -------------------------- | ----------- |
| open              | /                          |             |
| type              | q                          | selenium rc |
| clickAndWait      | btnG                       |             |
| assertTextPresent | Results \* for selenium rc |             |

Note: This example would work with the Google search page <http://www.google.com>

### Selenese as Programming Code

Here is the test script exported (via Selenium-IDE) to each of the supported programming languages. If you have at least basic knowledge of an object- oriented programming language, you will understand how Selenium runs Selenese commands by reading one of these examples. To see an example in a specific language, select one of these buttons.

#### CSharp

```csharp

        using System;
        using System.Text;
        using System.Text.RegularExpressions;
        using System.Threading;
        using NUnit.Framework;
        using Selenium;

        namespace SeleniumTests
        {
            [TestFixture]
            public class NewTest
            {
                private ISelenium selenium;
                private StringBuilder verificationErrors;
                
                [SetUp]
                public void SetupTest()
                {
                    selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
                    selenium.Start();
                    verificationErrors = new StringBuilder();
                }
                
                [TearDown]
                public void TeardownTest()
                {
                    try
                    {
                        selenium.Stop();
                    }
                    catch (Exception)
                    {
                        // Ignore errors if unable to close the browser
                    }
                    Assert.AreEqual("", verificationErrors.ToString());
                }
                
                [Test]
                public void TheNewTest()
                {
                    selenium.Open("/");
                    selenium.Type("q", "selenium rc");
                    selenium.Click("btnG");
                    selenium.WaitForPageToLoad("30000");
                    Assert.AreEqual("selenium rc - Google Search", selenium.GetTitle());
                }
            }
        }
```

#### Java

```java
      
	  /** Add JUnit framework to your classpath if not already there 
	   *  for this example to work
	  */
      package com.example.tests;

      import com.thoughtworks.selenium.*;
      import java.util.regex.Pattern;

      public class NewTest extends SeleneseTestCase {
          public void setUp() throws Exception {
              setUp("http://www.google.com/", "*firefox");
          }
            public void testNew() throws Exception {
                selenium.open("/");
                selenium.type("q", "selenium rc");
                selenium.click("btnG");
                selenium.waitForPageToLoad("30000");
                assertTrue(selenium.isTextPresent("Results * for selenium rc"));
          }
      }
```

#### Php

```php
      <?php

      require_once 'PHPUnit/Extensions/SeleniumTestCase.php';

      class Example extends PHPUnit_Extensions_SeleniumTestCase
      {
        function setUp()
        {
          $this->setBrowser("*firefox");
          $this->setBrowserUrl("http://www.google.com/");
        }

        function testMyTestCase()
        {
          $this->open("/");
          $this->type("q", "selenium rc");
          $this->click("btnG");
          $this->waitForPageToLoad("30000");
          $this->assertTrue($this->isTextPresent("Results * for selenium rc"));
        }
      }
      ?>
```

#### Python

```python

     from selenium import selenium
      import unittest, time, re

      class NewTest(unittest.TestCase):
          def setUp(self):
              self.verificationErrors = []
              self.selenium = selenium("localhost", 4444, "*firefox",
                      "http://www.google.com/")
              self.selenium.start()
         
          def test_new(self):
              sel = self.selenium
              sel.open("/")
              sel.type("q", "selenium rc")
              sel.click("btnG")
              sel.wait_for_page_to_load("30000")
              self.failUnless(sel.is_text_present("Results * for selenium rc"))
         
          def tearDown(self):
              self.selenium.stop()
              self.assertEqual([], self.verificationErrors)
```

#### Ruby

```ruby

      require "selenium/client"
      require "test/unit"

      class NewTest < Test::Unit::TestCase
        def setup
          @verification_errors = []
          if $selenium
            @selenium = $selenium
          else
            @selenium =  Selenium::Client::Driver.new("localhost", 4444, "*firefox", "http://www.google.com/", 60);
            @selenium.start
          end
          @selenium.set_context("test_new")
        end

        def teardown
          @selenium.stop unless $selenium
          assert_equal [], @verification_errors
        end

        def test_new
          @selenium.open "/"
          @selenium.type "q", "selenium rc"
          @selenium.click "btnG"
          @selenium.wait_for_page_to_load "30000"
          assert @selenium.is_text_present("Results * for selenium rc")
        end
      end
```

```java
    selenium = new DefaultSelenium("localhost", 4444, "*iehta", "http://www.google.com/");
```

The Selenium-IDE generated code will look like this. This example has comments added manually for additional clarity.

```java
   package com.example.tests;
   // We specify the package of our tests

   import com.thoughtworks.selenium.*;
   // This is the driver's import. You'll use this for instantiating a
   // browser and making it do what you need.

   import java.util.regex.Pattern;
   // Selenium-IDE add the Pattern module because it's sometimes used for 
   // regex validations. You can remove the module if it's not used in your 
   // script.

   public class NewTest extends SeleneseTestCase {
   // We create our Selenium test case

         public void setUp() throws Exception {
           setUp("http://www.google.com/", "*firefox");
                // We instantiate and start the browser
         }

         public void testNew() throws Exception {
              selenium.open("/");
              selenium.type("q", "selenium rc");
              selenium.click("btnG");
              selenium.waitForPageToLoad("30000");
              assertTrue(selenium.isTextPresent("Results * for selenium rc"));
              // These are the real test steps
        }
   }
```

### `C#`

The .NET Client Driver works with Microsoft.NET. It can be used with any .NET testing framework like NUnit or the Visual Studio 2005 Team System.

Selenium-IDE assumes you will use NUnit as your testing framework. You can see this in the generated code below. It includes the *using* statement for NUnit along with corresponding NUnit attributes identifying the role for each member function of the test class.

You will probably have to rename the test class from “NewTest” to something of your own choosing. Also, you will need to change the browser-open parameters in the statement:

```csharp
    selenium = new DefaultSelenium("localhost", 4444, "*iehta", "http://www.google.com/");
```

The generated code will look similar to this.

```csharp

    using System;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading;
    using NUnit.Framework;
    using Selenium;
    
    namespace SeleniumTests

    {
        [TestFixture]

        public class NewTest

        {
        private ISelenium selenium;

        private StringBuilder verificationErrors;

        [SetUp]

        public void SetupTest()

        {
            selenium = new DefaultSelenium("localhost", 4444, "*iehta",
            "http://www.google.com/");

            selenium.Start();

            verificationErrors = new StringBuilder();
        }

        [TearDown]

        public void TeardownTest()
        {
            try
            {
            selenium.Stop();
            }

            catch (Exception)
            {
            // Ignore errors if unable to close the browser
            }

            Assert.AreEqual("", verificationErrors.ToString());
        }
        [Test]

        public void TheNewTest()
        {
            // Open Google search engine.        
            selenium.Open("http://www.google.com/"); 
            
            // Assert Title of page.
            Assert.AreEqual("Google", selenium.GetTitle());
            
            // Provide search term as "Selenium OpenQA"
            selenium.Type("q", "Selenium OpenQA");
            
            // Read the keyed search term and assert it.
            Assert.AreEqual("Selenium OpenQA", selenium.GetValue("q"));
            
            // Click on Search button.
            selenium.Click("btnG");
            
            // Wait for page to load.
            selenium.WaitForPageToLoad("5000");
            
            // Assert that "www.openqa.org" is available in search results.
            Assert.IsTrue(selenium.IsTextPresent("www.openqa.org"));
            
            // Assert that page title is - "Selenium OpenQA - Google Search"
            Assert.AreEqual("Selenium OpenQA - Google Search", 
                         selenium.GetTitle());
        }
        }
    }
```

You can allow NUnit to manage the execution of your tests. Or alternatively, you can write a simple `main()` program that instantiates the test object and runs each of the three methods, `SetupTest()`, `TheNewTest()`, and `TeardownTest()` in turn.

### Python

Pyunit is the test framework to use for Python.

The basic test structure is:

```python

   from selenium import selenium
   # This is the driver's import.  You'll use this class for instantiating a
   # browser and making it do what you need.

   import unittest, time, re
   # This are the basic imports added by Selenium-IDE by default.
   # You can remove the modules if they are not used in your script.

   class NewTest(unittest.TestCase):
   # We create our unittest test case

       def setUp(self):
           self.verificationErrors = []
           # This is an empty array where we will store any verification errors
           # we find in our tests

           self.selenium = selenium("localhost", 4444, "*firefox",
                   "http://www.google.com/")
           self.selenium.start()
           # We instantiate and start the browser

       def test_new(self):
           # This is the test code.  Here you should put the actions you need
           # the browser to do during your test.
            
           sel = self.selenium
           # We assign the browser to the variable "sel" (just to save us from 
           # typing "self.selenium" each time we want to call the browser).
            
           sel.open("/")
           sel.type("q", "selenium rc")
           sel.click("btnG")
           sel.wait_for_page_to_load("30000")
           self.failUnless(sel.is_text_present("Results * for selenium rc"))
           # These are the real test steps

       def tearDown(self):
           self.selenium.stop()
           # we close the browser (I'd recommend you to comment this line while
           # you are creating and debugging your tests)

           self.assertEqual([], self.verificationErrors)
           # And make the test fail if we found that any verification errors
           # were found
```

### Ruby

Old (pre 2.0) versions of Selenium-IDE generate Ruby code that requires the old Selenium gem. Therefore, it is advisable to update any Ruby scripts generated by the IDE as follows:

1. On line 1, change `require "selenium"` to `require "selenium/client"`

2. On line 11, change `Selenium::SeleniumDriver.new` to `Selenium::Client::Driver.new`

You probably also want to change the class name to something more informative than “Untitled,” and change the test method’s name to something other than “test\_untitled.”

Here is a simple example created by modifying the Ruby code generated by Selenium IDE, as described above.

```ruby

   # load the Selenium-Client gem
   require "selenium/client"

   # Load Test::Unit, Ruby's default test framework.
   # If you prefer RSpec, see the examples in the Selenium-Client
   # documentation.
   require "test/unit"

   class Untitled < Test::Unit::TestCase

     # The setup method is called before each test.
     def setup

       # This array is used to capture errors and display them at the
       # end of the test run.
       @verification_errors = []

       # Create a new instance of the Selenium-Client driver.
       @selenium = Selenium::Client::Driver.new \
         :host => "localhost",
         :port => 4444,
         :browser => "*chrome",
         :url => "http://www.google.com/",
         :timeout_in_second => 60

       # Start the browser session
       @selenium.start

       # Print a message in the browser-side log and status bar
       # (optional).
       @selenium.set_context("test_untitled")

     end

     # The teardown method is called after each test.
     def teardown

       # Stop the browser session.
       @selenium.stop

       # Print the array of error messages, if any.
       assert_equal [], @verification_errors
     end

     # This is the main body of your test.
     def test_untitled
     
       # Open the root of the site we specified when we created the
       # new driver instance, above.
       @selenium.open "/"

       # Type 'selenium rc' into the field named 'q'
       @selenium.type "q", "selenium rc"

       # Click the button named "btnG"
       @selenium.click "btnG"

       # Wait for the search results page to load.
       # Note that we don't need to set a timeout here, because that
       # was specified when we created the new driver instance, above.
       @selenium.wait_for_page_to_load

       begin

          # Test whether the search results contain the expected text.
	  # Notice that the star (*) is a wildcard that matches any
	  # number of characters.
	  assert @selenium.is_text_present("Results * for selenium rc")
	  
       rescue Test::Unit::AssertionFailedError
       
          # If the assertion fails, push it onto the array of errors.
	  @verification_errors << $!

       end
     end
   end
```

```csharp
      selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
      selenium.Start();
```

#### Java

```java

      setUp("http://www.google.com/", "*firefox");
```

#### Perl

```perl
      my $sel = Test::WWW::Selenium->new( host => "localhost", 
                                          port => 4444, 
                                          browser => "*firefox", 
                                          browser_url => "http://www.google.com/" );
```

#### Php

```php
      $this->setBrowser("*firefox");
      $this->setBrowserUrl("http://www.google.com/");
```

#### Python

```python
      self.selenium = selenium("localhost", 4444, "*firefox",
                               "http://www.google.com/")
      self.selenium.start()
```

#### Ruby

```ruby
      @selenium = Selenium::ClientDriver.new("localhost", 4444, "*firefox", "http://www.google.com/", 10000);
      @selenium.start
```

```
    selenium.type("field-id","string to type")
```

|                   |                              |               |
| ----------------- | ---------------------------- | ------------- |
| open              | /                            |               |
| type              | q                            | selenium rc   |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium rc   |               |
| type              | q                            | selenium ide  |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium ide  |               |
| type              | q                            | selenium grid |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium grid |               |

The code has been repeated to run the same steps 3 times. But multiple copies of the same code is not good program practice because it’s more work to maintain. By using a programming language, we can iterate over the search results for a more flexible and maintainable solution.

#### In `C#`

```csharp
   // Collection of String values.
   String[] arr = {"ide", "rc", "grid"};    
        
   // Execute loop for each String in array 'arr'.
   foreach (String s in arr) {
       sel.open("/");
       sel.type("q", "selenium " +s);
       sel.click("btnG");
       sel.waitForPageToLoad("30000");
       assertTrue("Expected text: " +s+ " is missing on page."
       , sel.isTextPresent("Results * for selenium " + s));
    }
```

### Condition Statements

To illustrate using conditions in tests we’ll start with an example. A common problem encountered while running Selenium tests occurs when an expected element is not available on page. For example, when running the following line:

```
   selenium.type("q", "selenium " +s);
```

If element ‘q’ is not on the page then an exception is thrown:

```java
   com.thoughtworks.selenium.SeleniumException: ERROR: Element q not found
```

This can cause your test to abort. For some tests that’s what you want. But often that is not desirable as your test script has many other subsequent tests to perform.

A better approach is to first validate whether the element is really present and then take alternatives when it it is not. Let’s look at this using Java.

```java
   // If element is available on page then perform type operation.
   if(selenium.isElementPresent("q")) {
       selenium.type("q", "Selenium rc");
   } else {
       System.out.printf("Element: " +q+ " is not available on page.")
   }
```

The advantage of this approach is to continue with test execution even if some UI elements are not available on page.

### Executing JavaScript from Your Test

JavaScript comes very handy in exercising an application which is not directly supported by Selenium. The **getEval** method of Selenium API can be used to execute JavaScript from Selenium RC.

Consider an application having check boxes with no static identifiers. In this case one could evaluate JavaScript from Selenium RC to get ids of all check boxes and then exercise them.

```java
   public static String[] getAllCheckboxIds () { 
		String script = "var inputId  = new Array();";// Create array in java script.
		script += "var cnt = 0;"; // Counter for check box ids.  
		script += "var inputFields  = new Array();"; // Create array in java script.
		script += "inputFields = window.document.getElementsByTagName('input');"; // Collect input elements.
		script += "for(var i=0; i<inputFields.length; i++) {"; // Loop through the collected elements.
		script += "if(inputFields[i].id !=null " +
		"&& inputFields[i].id !='undefined' " +
		"&& inputFields[i].getAttribute('type') == 'checkbox') {"; // If input field is of type check box and input id is not null.
		script += "inputId[cnt]=inputFields[i].id ;" + // Save check box id to inputId array.
		"cnt++;" + // increment the counter.
		"}" + // end of if.
		"}"; // end of for.
		script += "inputId.toString();" ;// Convert array in to string.			
		String[] checkboxIds = selenium.getEval(script).split(","); // Split the string.
		return checkboxIds;
    }
```

To count number of images on a page:

```java
   selenium.getEval("window.document.images.length;");
```

Remember to use window object in case of DOM expressions as by default selenium window is referred to, not the test window.

## Server Options

When the server is launched, command line options can be used to change the default server behaviour.

Recall, the server is started by running the following.

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar
```

To see the list of options, run the server with the `-h` option.

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar -h
```

You’ll see a list of all the options you can use with the server and a brief description of each. The provided descriptions will not always be enough, so we’ve provided explanations for some of the more important options.

### Proxy Configuration

If your AUT is behind an HTTP proxy which requires authentication then you should configure http.proxyHost, http.proxyPort, http.proxyUser and http.proxyPassword using the following command.

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar -Dhttp.proxyHost=proxy.com -Dhttp.proxyPort=8080 -Dhttp.proxyUser=username -Dhttp.proxyPassword=password
```

### Multi-Window Mode

If you are using Selenium 1.0 you can probably skip this section, since multiwindow mode is the default behavior. However, prior to version 1.0, Selenium by default ran the application under test in a sub frame as shown here.

Some applications didn’t run correctly in a sub frame, and needed to be loaded into the top frame of the window. The multi-window mode option allowed the AUT to run in a separate window rather than in the default frame where it could then have the top frame it required.

For older versions of Selenium you must specify multiwindow mode explicitly with the following option:

```bash
   -multiwindow 
```

As of Selenium RC 1.0, if you want to run your test within a single frame (i.e. using the standard for earlier Selenium versions) you can state this to the Selenium Server using the option

```bash
   -singlewindow 
```

### Specifying the Firefox Profile

Firefox will not run two instances simultaneously unless you specify a separate profile for each instance. Selenium RC 1.0 and later runs in a separate profile automatically, so if you are using Selenium 1.0, you can probably skip this section. However, if you’re using an older version of Selenium or if you need to use a specific profile for your tests (such as adding an https certificate or having some addons installed), you will need to explicitly specify the profile.

First, to create a separate Firefox profile, follow this procedure. Open the Windows Start menu, select “Run”, then type and enter one of the following:

```bash
   firefox.exe -profilemanager 
```

```bash
   firefox.exe -P 
```

Create the new profile using the dialog. Then when you run Selenium Server, tell it to use this new Firefox profile with the server command-line option *-firefoxProfileTemplate* and specify the path to the profile using its filename and directory path.

```bash
   -firefoxProfileTemplate "path to the profile" 
```

**Warning**: Be sure to put your profile in a new folder separate from the default!!! The Firefox profile manager tool will delete all files in a folder if you delete a profile, regardless of whether they are profile files or not.

More information about Firefox profiles can be found in [Mozilla’s Knowledge Base](http://support.mozilla.com/en/kb/Managing+profiles)

### Run Selenese Directly Within the Server Using -htmlSuite

You can run Selenese html files directly within the Selenium Server by passing the html file to the server’s command line. For instance:

```bash
   java -jar selenium-server-standalone-<version-number>.jar -htmlSuite "*firefox" 
   "http://www.google.com" "c:\absolute\path\to\my\HTMLSuite.html" 
   "c:\absolute\path\to\my\results.html"
```

This will automatically launch your HTML suite, run all the tests and save a nice HTML report with the results.

*Note:* When using this option, the server will start the tests and wait for a specified number of seconds for the test to complete; if the test doesn’t complete within that amount of time, the command will exit with a non-zero exit code and no results file will be generated.

This command line is very long so be careful when you type it. Note this requires you to pass in an HTML Selenese suite, not a single test. Also be aware the -htmlSuite option is incompatible with `-interactive` You cannot run both at the same time.

### Selenium Server Logging

#### Server-Side Logs

When launching Selenium server the **-log** option can be used to record valuable debugging information reported by the Selenium Server to a text file.

```bash
   java -jar selenium-server-standalone-<version-number>.jar -log selenium.log
```

This log file is more verbose than the standard console logs (it includes DEBUG level logging messages). The log file also includes the logger name, and the ID number of the thread that logged the message. For example:

```bash
   20:44:25 DEBUG [12] org.openqa.selenium.server.SeleniumDriverResourceHandler - 
   Browser 465828/:top frame1 posted START NEW
```

The message format is

```bash
   TIMESTAMP(HH:mm:ss) LEVEL [THREAD] LOGGER - MESSAGE
```

This message may be multiline.

#### Browser-Side Logs

JavaScript on the browser side (Selenium Core) also logs important messages; in many cases, these can be more useful to the end-user than the regular Selenium Server logs. To access browser-side logs, pass the **-browserSideLog** argument to the Selenium Server.

```bash
   java -jar selenium-server-standalone-<version-number>.jar -browserSideLog
```

**-browserSideLog** must be combined with the **-log** argument, to log browserSideLogs (as well as all other DEBUG level logging messages) to a file.

## Specifying the Path to a Specific Browser

You can specify to Selenium RC a path to a specific browser. This is useful if you have different versions of the same browser and you wish to use a specific one. Also, this is used to allow your tests to run against a browser not directly supported by Selenium RC. When specifying the run mode, use the \*custom specifier followed by the full path to the browser’s executable:

```bash
   *custom <path to browser> 
```

```bash
   cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\MyBrowser.exe&2=http://www.google.com
```

### Running Tests with Different Browser Configurations

Normally Selenium RC automatically configures the browser, but if you launch the browser using the “\*custom” run mode, you can force Selenium RC to launch the browser as-is, without using an automatic configuration.

For example, you can launch Firefox with a custom configuration like this:

```bash
   cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\firefox.exe&2=http://www.google.com
```

Note that when launching the browser this way, you must manually configure the browser to use the Selenium Server as a proxy. Normally this just means opening your browser preferences and specifying “localhost:4444” as an HTTP proxy, but instructions for this can differ radically from browser to browser. Consult your browser’s documentation for details.

Be aware that Mozilla browsers can vary in how they start and stop. One may need to set the MOZ\_NO\_REMOTE environment variable to make Mozilla browsers behave a little more predictably. Unix users should avoid launching the browser using a shell script; it’s generally better to use the binary executable (e.g. firefox-bin) directly.

## Troubleshooting Common Problems

When getting started with Selenium RC there’s a few potential problems that are commonly encountered. We present them along with their solutions here.

### Unable to Connect to Server

When your test program cannot connect to the Selenium Server, Selenium throws an exception in your test program. It should display this message or a similar one:

```bash
    "Unable to connect to remote server (Inner Exception Message: 
	No connection could be made because the target machine actively 
	refused it )"
    
	(using .NET and XP Service Pack 2) 
```

If you see a message like this, be sure you started the Selenium Server. If so, then there is a problem with the connectivity between the Selenium Client Library and the Selenium Server.

When starting with Selenium RC, most people begin by running their test program (with a Selenium Client Library) and the Selenium Server on the same machine. To do this use “localhost” as your connection parameter. We recommend beginning this way since it reduces the influence of potential networking problems which you’re getting started. Assuming your operating system has typical networking and TCP/IP settings you should have little difficulty. In truth, many people choose to run the tests this way.

If, however, you do want to run Selenium Server on a remote machine, the connectivity should be fine assuming you have valid TCP/IP connectivity between the two machines.

If you have difficulty connecting, you can use common networking tools like *ping*, *telnet*, *ifconfig(Unix)/ipconfig* (Windows), etc to ensure you have a valid network connection. If unfamilar with these, your system administrator can assist you.

### Unable to Load the Browser

Ok, not a friendly error message, sorry, but if the Selenium Server cannot load the browser you will likely see this error.

```bash
    (500) Internal Server Error
```

```bash
    Error:  java.lang.RuntimeException: Firefox refused shutdown while 
    preparing a profile 
```

Here’s the complete error message from the server:

```bash
    16:20:03.919 INFO - Preparing Firefox profile... 
    16:20:27.822 WARN - GET /selenium-server/driver/?cmd=getNewBrowserSession&1=*fir 
    efox&2=http%3a%2f%2fsage-webapp1.qa.idc.com HTTP/1.1 
    java.lang.RuntimeException: Firefox refused shutdown while preparing a profile 
            at org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLaunc 
    her.waitForFullProfileToBeCreated(FirefoxCustomProfileLauncher.java:277) 
    ... 
    Caused by: org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLaunc 
    her$FileLockRemainedException: Lock file still present! C:\DOCUME~1\jsvec\LOCALS 
    ~1\Temp\customProfileDir203138\parent.lock 
```

To resolve this, see the section on Specifying a Separate Firefox Profile

### Versioning Problems

Make sure your version of Selenium supports the version of your browser. For example, Selenium RC 0.92 does not support Firefox 3. At times you may be lucky (I was). But don’t forget to check which browser versions are supported by the version of Selenium you are using. When in doubt, use the latest release version of Selenium with the most widely used version of your browser.

### Error message: “(Unsupported major.minor version 49.0)” while starting server

This error says you’re not using a correct version of Java. The Selenium Server requires Java 1.5 or higher.

To check double-check your java version, run this from the command line.

```bash
   java -version
```

You should see a message showing the Java version.

```bash
   java version "1.5.0_07"
   Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03)
   Java HotSpot(TM) Client VM (build 1.5.0_07-b03, mixed mode)
```

```bash
   cmd=getNewBrowserSession&1=*firefox /usr/local/firefox/firefox-bin&2=http://www.google.com
```

```bash
   /usr/lib/firefox-x.x.x/ 
```

Where the x.x.x is the version number you currently have. So, to add that path to the user’s path. you will have to add the following to your .bashrc file:

```bash
   export PATH="$PATH:/usr/lib/firefox-x.x.x/"
```

If necessary, you can specify the path to firefox-bin directly in your test, like this:

```bash
   "*firefox /usr/lib/firefox-x.x.x/firefox-bin"
```

### IE and Style Attributes

If you are running your tests on Internet Explorer and you cannot locate elements using their `style` attribute. For example:

```bash
    //td[@style="background-color:yellow"]
```

This would work perfectly in Firefox, Opera or Safari but not with IE. IE interprets the keys in `@style` as uppercase. So, even if the source code is in lowercase, you should use:

```bash
    //td[@style="BACKGROUND-COLOR:yellow"]
```

This is a problem if your test is intended to work on multiple browsers, but you can easily code your test to detect the situation and try the alternative locator that only works in IE.

### Error encountered - “Cannot convert object to primitive value” with shut down of \*googlechrome browser

To avoid this error you have to start browser with an option that disables same origin policy checks:

```bash
   selenium.start("commandLineFlags=--disable-web-security");
```

### Error encountered in IE - “Couldn’t open app window; is the pop-up blocker enabled?”

To avoid this error you have to configure the browser: disable the popup blocker AND uncheck ‘Enable Protected Mode’ option in Tools » Options » Security.

***

1. The proxy is a third person in the middle that passes the ball between the two parts. It acts as a “web server” that delivers the AUT to the browser. Being a proxy gives Selenium Server the capability of “lying” about the AUT’s real URL. [↩︎](#fnref:1)

2. The browser is launched with a configuration profile that has set localhost:4444 as the HTTP proxy, this is why any HTTP request that the browser does will pass through Selenium server and the response will pass through it and not from the real server. [↩︎](#fnref:2)

# 2 - Selenium 2

Selenium 2 was a rewrite of Selenium 1 that was implemented with WebDriver code.

# 2.1 - Migrating from RC to WebDriver

```java
Selenium selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.yoursite.com");
selenium.start();
```

This should be replaced like so:

```java
WebDriver driver = new FirefoxDriver();
Selenium selenium = new WebDriverBackedSelenium(driver, "http://www.yoursite.com");
```

## Next Steps

Once your tests execute without errors, the next stage is to migrate the actual test code to use the WebDriver APIs. Depending on how well abstracted your code is, this might be a short process or a long one. In either case, the approach is the same and can be summed up simply: modify code to use the new API when you come to edit it.

If you need to extract the underlying WebDriver implementation from the Selenium instance, you can simply cast it to WrapsDriver:

```java
WebDriver driver = ((WrapsDriver) selenium).getWrappedDriver();
```

This allows you to continue passing the Selenium instance around as normal, but to unwrap the WebDriver instance as required.

At some point, you’re codebase will mostly be using the newer APIs. At this point, you can flip the relationship, using WebDriver throughout and instantiating a Selenium instance on demand:

```java
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);
```

## Common Problems

Fortunately, you’re not the first person to go through this migration, so here are some common problems that others have seen, and how to solve them.

### Clicking and Typing is More Complete

A common pattern in a Selenium RC test is to see something like:

```java
selenium.type("name", "exciting tex");
selenium.keyDown("name", "t");
selenium.keyPress("name", "t");
selenium.keyUp("name", "t");
```

```java
Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(30));
WebElement element= wait.until(visibilityOfElementLocated(By.id("some_id")));
```

Where “visibilityOfElementLocated” is implemented as:

```java
public ExpectedCondition<WebElement> visibilityOfElementLocated(final By locator) {
  return new ExpectedCondition<WebElement>() {
    public WebElement apply(WebDriver driver) {
      WebElement toReturn = driver.findElement(locator);
      if (toReturn.isDisplayed()) {
        return toReturn;
      }
      return null;
    }
  };
}
```

This may look complex, but it’s almost all boiler-plate code. The only interesting bit is that the “ExpectedCondition” will be evaluated repeatedly until the “apply” method returns something that is neither “null” nor Boolean.FALSE.

Of course, adding all these “wait” calls may clutter up your code. If that’s the case, and your needs are simple, consider using the implicit waits:

```java
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
```

```java
String name = selenium.getEval(
    "selenium.browserbot.findElement('id=foo', browserbot.getCurrentWindow()).tagName");
```

becomes:

```java
WebElement element = driver.findElement(By.id("foo"));
String name = (String) ((JavascriptExecutor) driver).executeScript(
    "return arguments[0].tagName", element);
```

Notice how the passed in “element” variable appears as the first item in the JS standard “arguments” array.

### Executing Javascript Doesn’t Return Anything

WebDriver’s JavascriptExecutor will wrap all JS and evaluate it as an anonymous expression. This means that you need to use the “return” keyword:

```java
String title = selenium.getEval("browserbot.getCurrentWindow().document.title");
```

becomes:

```java
((JavascriptExecutor) driver).executeScript("return document.title;");
```

# 2.2 - Backing Selenium with WebDriver

The Java and .NET versions of Selenium 2 provided implementations of the original Selenium API

(Previously located: <https://github.com/SeleniumHQ/selenium/wiki/Selenium-Emulation>)

## Backing Selenium with WebDriver

The Java and .NET versions of WebDriver provide implementations of the existing Selenium API. In Java, it is used like so:

```
// You may use any WebDriver implementation. Firefox is used here as an example
WebDriver driver = new FirefoxDriver();

// A "base url", used by selenium to resolve relative URLs
String baseUrl = "http://www.google.com";

// Create the Selenium implementation
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);

// Perform actions with selenium
selenium.open("http://www.google.com");
selenium.type("name=q", "cheese");
selenium.click("name=btnG");

// And get the underlying WebDriver implementation back. This will refer to the
// same WebDriver instance as the "driver" variable above.
WebDriver driverInstance = ((WebDriverBackedSelenium) selenium).getUnderlyingWebDriver();
```

```
driver = RemoteWebDriver(desired_capabilities = DesiredCapabilities.FIREFOX)
selenium = DefaultSelenium('localhost', '4444', '*webdriver', 'http://www.google.com')
selenium.start(driver = driver)
```

Provided you keep a reference to the original WebDriver and Selenium objects you created, you can use even the two APIs interchangeably. The magic is the “`*webdriver`” browser name passed to the Selenium instance, and that you pass the WebDriver instance when calling `start()`.

In languages where DefaultSelenium doesn’t have `start(driver)`, you can connect the WebDriver and Selenium objects together yourself, by supplying the WebDriver session ID to the Selenium object.

For example, in C#:

```

RemoteWebDriver driver = new RemoteWebDriver(DesiredCapabilities.Firefox());
string sessionId = (string) driver.Capabilities.GetCapability("webdriver.remote.sessionid");
DefaultSelenium selenium = new DefaultSelenium("localhost", 4444, "*webdriver", "http://www.google.com");
selenium.Start("webdriver.remote.sessionid=" + sessionId);
```

## Backing WebDriver with Selenium

WebDriver doesn’t support as many browsers as Selenium does, so in order to provide that support while still using the webdriver API, you can make use of the `SeleneseCommandExecutor` It is done like this:

```
Capabilities capabilities = new DesiredCapabilities()
capabilities.setBrowserName("safari");
CommandExecutor executor = new SeleneseCommandExecutor("http:localhost:4444/", "http://www.google.com/", capabilities);
WebDriver driver = new RemoteWebDriver(executor, capabilities);
```

There are currently some major limitations with this approach, notably that `findElements` doesn’t work as expected. Also, because we’re using Selenium Core for the heavy lifting of driving the browser, you are limited by the Javascript sandbox.

# 2.3 - Legacy Firefox Driver

| **Property**                  | **What it means**                                                                                                                                                                 |
| ----------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| webdriver.firefox.bin         | The location of the binary used to control firefox.                                                                                                                               |
| webdriver.firefox.marionette  | Boolean value, if set on standalone-server will ignore any “marionette” desired capability requested and force firefox to use GeckoDriver (true) or Legacy Firefox Driver (false) |
| webdriver.firefox.profile     | The name of the profile to use when starting firefox. This defaults to webdriver creating an anonymous profile                                                                    |
| webdriver.firefox.useExisting | **Never use in production** Use a running instance of firefox if one is present                                                                                                   |
| webdriver.firefox.logfile     | Log file to dump firefox stdout/stderr to                                                                                                                                         |

Normally the Firefox binary is assumed to be in the default location for your particular operating system:

| **OS**  | **Expected Location of Firefox**                     |
| ------- | ---------------------------------------------------- |
| Linux   | firefox (found using “which”)                        |
| Mac     | /Applications/Firefox.app/Contents/MacOS/firefox-bin |
| Windows | %PROGRAMFILES%\Mozilla Firefox\firefox.exe           |

By default, the Firefox driver creates an anonymous profile

### Running with firebug

Download the firebug xpi file from mozilla and start the profile as follows:

```
   File file = new File("firebug-1.8.1.xpi");
   FirefoxProfile firefoxProfile = new FirefoxProfile();
   firefoxProfile.addExtension(file);
   firefoxProfile.setPreference("extensions.firebug.currentVersion", "1.8.1"); // Avoid startup screen

   WebDriver driver = new FirefoxDriver(firefoxProfile);
```

# 2.4 - Selenium grid 2

> This example will show you how to start the Selenium 2 Hub, and register both a WebDriver node and a Selenium 1 RC legacy node. We’ll also show you how to call the grid from Java. The hub and nodes are shown here running on the same machine, but of course you can copy the selenium-server-standalone to multiple machines. Note: The selenium-server-standalone package includes the Hub, WebDriver, and legacy RC needed to run the grid. Ant is not required anymore. You can download the selenium-server-standalone-`*`.jar from <http://selenium-release.storage.googleapis.com/index.html> This walk-through assumes you already have Java installed.

**Step 1: Start the hub**

The Hub is the central point that will receive all the test request and distribute them the the right nodes.

Open a command prompt and navigate to the directory where you copied the selenium-server-standalone file. Type the following command:

```
java -jar selenium-server-standalone-<version>.jar -role hub
```

The hub will automatically start-up using port 4444 by default. To change the default port, you can add the optional parameter -port when you run the command. You can view the status of the hub by opening a browser window and navigating to: http\://localhost:4444/grid/console

**Step 2: Start the nodes**

Regardless on whether you want to run a grid with new WebDriver functionality, or a grid with Selenium 1 RC functionality, or both at the same time, you use the same selenium-server-standalone jar file to start the nodes.

```
java -jar selenium-server-standalone-<version>.jar -role node  -hub http://localhost:4444/grid/register
```

Note: The port defaults to 5555 if not specified whenever the “-role” option is provided and is not hub.

For backwards compatibility “wd” and “rc” roles are still a valid subset of the “node” role. But those roles limit the types of remote connections to their corresponding API, while “node” allows both RC and WebDriver remote connections.

### Using grid to run tests

( using java as an example ) Now that the grid is in-place, we need to access the grid from our test cases. For the Selenium 1 RC nodes, you can continue to use the DefaultSelenium object and pass in the hub information:

```
Selenium selenium = new DefaultSelenium(“localhost”, 4444, “*firefox”, “http://www.google.com”);
```

For WebDriver nodes, you will need to use the **RemoteWebDriver** and the **DesiredCapabilities** object to define which browser, version and platform you wish to use. Create the target browser capabilities you want to run the tests against:

```
DesiredCapabilities capability = DesiredCapabilities.firefox();
```

Pass that into the RemoteWebDriver object:

```
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
```

The hub will then assign the test to a matching node.

A node matches if all the requested capabilities are met. To request specific capabilities on the grid, specify them before passing it into the WebDriver object.

```
capability.setBrowserName();
capability.setPlatform();
capability.setVersion()
capability.setCapability(,);
```

Example: A node registered with the setting:

```
 -browser  browserName=firefox,version=3.6,platform=LINUX
```

> will be a match for:

```
capability.setBrowserName(“firefox” ); 
capability.setPlatform(“LINUX”);  
capability.setVersion(“3.6”);
```

and would also be a match for

```
capability.setBrowserName(“firefox” ); 
capability.setVersion(“3.6”);
```

The capabilities that are not specified will be ignored. If you specify capabilities that do not exist on your grid (for example, your test specifies Firefox version 4.0, but have no Firefox 4 instance) then there will be no match and the test will fail to run.

## Configuring the nodes

The node can be configured in 2 different ways; one is by specifying command-line parameters, the other is by specifying a JSON file.

### Configuring the nodes by command line

By default, starting the node allows for concurrent use of 11 browsers…: 5 Firefox, 5 Chrome, 1 Internet Explorer. The maximum number of concurrent tests is set to 5 by default. To change this and other browser settings, you can pass in parameters to each -browser switch (each switch represents a node based on your parameters). If you use the -browser parameter, the default browsers will be ignored and only what you specify command line will be used.

```
-browser browserName=firefox,version=3.6,maxInstances=5,platform=LINUX
```

This setting starts 5 Firefox 3.6 nodes on a Linux machine.

If your remote machine has multiple versions of Firefox you’d like to use, you can map the location of each binary to a particular version on the same machine:

```
-browser browserName=firefox,version=3.6,firefox_binary=/home/myhomedir/firefox36/firefox,maxInstances=3,platform=LINUX -browser browserName=firefox,version=4,firefox_binary=/home/myhomedir/firefox4/firefox,maxInstances=4,platform=LINUX
```

Tip: If you need to provide a space somewhere in your browser parameters, then surround the parameters with quotation marks:

```
-browser “browserName=firefox,version=3.6,firefox_binary=c:\Program Files\firefox ,maxInstances=3, platform=WINDOWS”
```

### Optional parameters

* `-port 4444` (4444 is default)
* `-host <IP | hostname>` specify the hostname or IP. usually not needed and determined automatically. For exotic network configuration, network with VPN, specifying the host might be necessary.
* `-timeout 30` (300 is default) The timeout in seconds before the hub automatically releases a node that hasn’t received any requests for more than the specified number of seconds. After this time, the node will be released for another test in the queue. This helps to clear client crashes without manual intervention. To remove the timeout completely, specify -timeout 0 and the hub will never release the node.

> Note: This is NOT the WebDriver timeout for all ”wait for WebElement” type of commands.

> java -jar selenium-server-standalone.jar -role node -nodeConfig nodeconfig.json

A sample nodeconfig file for server version 3.x.x (>= beta4) can be seen at <https://github.com/SeleniumHQ/selenium/blob/selenium-3.141.59/java/server/src/org/openqa/grid/common/defaults/DefaultNodeWebDriver.json>

A sample nodeconfig file for server version 2.x.x can be seen at <https://github.com/SeleniumHQ/selenium/blob/selenium-2.53.0/java/server/src/org/openqa/grid/common/defaults/DefaultNode.json>

Note: the `configuration { ... }` object in version 2.x.x has been flattened in version 3.x.x (>= beta4)

### Configuring the hub by JSON

> java -jar selenium-server-standalone.jar -role hub -hubConfig hubconfig.json

A sample hubconfig.json file can be seen at <https://github.com/SeleniumHQ/selenium/blob/selenium-3.141.59/java/server/src/org/openqa/grid/common/defaults/DefaultHub.json>

## Hub diagnostic messages

Upon detecting anomalous usage patterns, the hub can give the following message:

```
Client requested session XYZ that was terminated due to REASON
```

| **Reason**                   | **Cause/fix**                                                                                                                                                                   |
| ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| TIMEOUT                      | The session timed out because the client did not access it within the timeout. If the client has been somehow suspended, this may happen when it wakes up                       |
| BROWSER\_TIMEOUT             | The node timed out the browser because it was hanging for too long (parameter browserTimeout)                                                                                   |
| ORPHAN                       | A client waiting in queue has given up once it was offered a new session                                                                                                        |
| CLIENT\_STOPPED\_SESSION     | The session was stopped using an ordinary call to stop/quit on the client. Why are you using it again??                                                                         |
| CLIENT\_GONE                 | The client process (*your* code) appears to have died or otherwise not responded to our requests, intermittent network issues may also cause                                    |
| FORWARDING\_TO\_NODE\_FAILED | The hub was unable to forward to the node. Out of memory errors/node stability issues or network problems                                                                       |
| CREATIONFAILED               | The node failed to create the browser. This can typically happen when there are environmental/configuration problems on the node. Try using the node directly to track problem. |
| PROXY\_REREGISTRATION        | The session has been discarded because the node has re-registered on the grid (in mid-test)                                                                                     |

```
	[[DesiredCapabilities]] capability = DesiredCapabilities.internetExplorer();
	capability.setVersion("8");
	capability.setPlatform(Platform.XP);
	WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
```

The request for a new session with specified DesiredCapability is sent to the Grid Hub, which will look through all of the registered nodes to see if any of them match the specification given by the test. If no node matches the specification, a CapabilityNotPresentOnTheGridException will be returned.

It is a common misconception that the PLATFORM determines the ability to choose the Operating System on which the new session will be created. In this situation, platform and operating system are not the same, thus specifying the platform to “Windows 2003 Server” will not allow you to choose between a Windows XP, Vista, and 2003 server. This misconception can be born from platforms such as Mac OSX and Linux, where the name of the platform matches the name of the Operating System.

In case of Selenium Grid, platform refers to the underlying interactions between the Driver Atoms and the web browser. Mac OSX and Linux based Operating Systems (Centos, Ubuntu, Debian, etc..) have a relatively stable communication with the web browsers such as Firefox and Chrome. Thus the platform names are simple to understand, as seen in the example bellow:

```
   capability.setPlatform(Platform.MAC);   //Set platform to OSX
   capability.setPlatform(Platform.LINUX); // Set platform to Linux based systems
```

The prior to release of Vista, Windows based Operating Systems only had one platform, shown here:

```
	capability.setPlatform(Platform.WINDOWS); //Set platform to Windows
```

However, with the introduction of UAC in Windows Vista, there were major changes done to the underlying interactions between WebDriver and Internet Explorer. To work around the UAC constrains a new platform was added to nodes with Windows based Operating systems:

```
	capability.setPlatform(Platform.VISTA); //Set platform to VISTA
```

With the release of Windows 8, another major overhaul happened in how the WebDriver communicates with Internet Explorer, thus a new platform was added for Windows 8 based nodes:

```
	capability.setPlatform(Platform.WIN8); //Set platform to Windows 8
```

Similar story happened with introduction of Windows 8.1, in this example the platform is set to Windows 8.1:

```
	capability.setPlatform(Platform.WIN8_1); //Set platform to Windows 8.1
```

```
  	capability.setPlatform(Platform.VISTA); //Will return a node with Windows Vista or 2008 Server or Windows 7 Operating System.
  	capability.setPlatform(Platform.XP);   //Will return a node with Windows XP or 2003 Server or Windows 2000 Professional Operating System.   
  	capability.setPlatform(Platform.WINDOWS); //Will return a node with ANY Windows Operating System
```

### More Information

For more information on the latest platforms, please view this file:

org.openqa.selenium.Platform.java

# 2.5 - History of Grid Platforms

```
	[[DesiredCapabilities]] capability = DesiredCapabilities.internetExplorer();
	capability.setVersion("8");
	capability.setPlatform(Platform.XP);
	WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
```

The request for a new session with specified DesiredCapability is sent to the Grid Hub, which will look through all of the registered nodes to see if any of them match the specification given by the test. If no node matches the specification, a CapabilityNotPresentOnTheGridException will be returned.

It is a common misconception that the PLATFORM determines the ability to choose the Operating System on which the new session will be created. In this situation, platform and operating system are not the same, thus specifying the platform to “Windows 2003 Server” will not allow you to choose between a Windows XP, Vista, and 2003 server. This misconception can be born from platforms such as Mac OSX and Linux, where the name of the platform matches the name of the Operating System.

In case of Selenium Grid, platform refers to the underlying interactions between the Driver Atoms and the web browser. Mac OSX and Linux based Operating Systems (Centos, Ubuntu, Debian, etc..) have a relatively stable communication with the web browsers such as Firefox and Chrome. Thus the platform names are simple to understand, as seen in the example bellow:

```
   capability.setPlatform(Platform.MAC);   //Set platform to OSX
   capability.setPlatform(Platform.LINUX); // Set platform to Linux based systems
```

The prior to release of Vista, Windows based Operating Systems only had one platform, shown here:

```
	capability.setPlatform(Platform.WINDOWS); //Set platform to Windows
```

However, with the introduction of UAC in Windows Vista, there were major changes done to the underlying interactions between WebDriver and Internet Explorer. To work around the UAC constrains a new platform was added to nodes with Windows based Operating systems:

```
	capability.setPlatform(Platform.VISTA); //Set platform to VISTA
```

With the release of Windows 8, another major overhaul happened in how the WebDriver communicates with Internet Explorer, thus a new platform was added for Windows 8 based nodes:

```
	capability.setPlatform(Platform.WIN8); //Set platform to Windows 8
```

Similar story happened with introduction of Windows 8.1, in this example the platform is set to Windows 8.1:

```
	capability.setPlatform(Platform.WIN8_1); //Set platform to Windows 8.1
```

```
  	capability.setPlatform(Platform.VISTA); //Will return a node with Windows Vista or 2008 Server or Windows 7 Operating System.
  	capability.setPlatform(Platform.XP);   //Will return a node with Windows XP or 2003 Server or Windows 2000 Professional Operating System.   
  	capability.setPlatform(Platform.WINDOWS); //Will return a node with ANY Windows Operating System
```

### More Information

For more information on the latest platforms, please view this file:

org.openqa.selenium.Platform.java

# 2.6 - Remote WebDriver standalone server

Working with the Standalone Server.

This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/RemoteWebDriverServer)

The server will always run on the machine with the browser you want to test. The server can be used either from the command line or through code configuration.

## Starting the server from the command line

Once you have downloaded `selenium-server-standalone-{VERSION}.jar`, place it on the computer with the browser you want to test. Then, from the directory with the jar, run the following:

```shell
java -jar selenium-server-standalone-{VERSION}.jar
```

## Considerations for running the server

The caller is expected to terminate each session properly, calling either `Selenium#stop()` or `WebDriver#quit`.

The selenium-server keeps in-memory logs for each ongoing session, which are cleared when `Selenium#stop()` or `WebDriver#quit` is called. If you forget to terminate these sessions, your server may leak memory. If you keep extremely long-running sessions, you will probably need to stop/quit every now and then (or increase memory with -Xmx jvm option).

## Timeouts (from version 2.21)

The server has two different timeouts, which can be set as follows:

```shell
java -jar selenium-server-standalone-{VERSION}.jar -timeout=20 -browserTimeout=60
```

```java
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.security.SslSocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;

import javax.servlet.Servlet;
import java.io.File;

import org.openqa.selenium.remote.server.DriverServlet;

public class AppServer {
  private Server server = new Server();

  public AppServer() throws Exception {
    WebAppContext context = new WebAppContext();
    context.setContextPath("");
    context.setWar(new File("."));
    server.addHandler(context);

    context.addServlet(DriverServlet.class, "/wd/*");

    SelectChannelConnector connector = new SelectChannelConnector();
    connector.setPort(3001);
    server.addConnector(connector);

    server.start();
  }
}
```

# 2.7 - Limitations of scaling up tests in Selenium 2

# 2.8 - Stealing focus from Firefox in Linux

# 2.9 - Untrusted SSL Certificates

```
WdCertOverrideService.prototype.hasMatchingOverride = function(
    aHostName, aPort, aCert, aOverrideBits, aIsTemporary)
```

The aOverrideBits and aIsTemporary are output arguments. This is where things get a bit tricky: There are three possible override bits:

```
  ERROR_UNTRUSTED: 1,
  ERROR_MISMATCH: 2,
  ERROR_TIME: 4
```

It’s impossible to just set them all, since Firefox expects a perfect match between the offences generated by the certificate and the function’s return value: (security/manager/ssl/src/SSLServerCertVerification.cpp:302):

```
  if (overrideService)
  {
    PRBool haveOverride;
    PRBool isTemporaryOverride; // we don't care
  
    nsrv = overrideService->HasMatchingOverride(hostString, port,
                                                ix509, 
                                                &overrideBits,
                                                &isTemporaryOverride, 
                                                &haveOverride);
    if (NS_SUCCEEDED(nsrv) && haveOverride) 
    {
      // remove the errors that are already overriden
      remaining_display_errors -= overrideBits;
    }
  }

  if (!remaining_display_errors) {
    // all errors are covered by override rules, so let's accept the cert
    return SECSuccess;
  }
```

The exact mapping of violation to error code can be easily seen at security/manager/pki/resources/content/exceptionDialog.js (in Firefox source):

```
  var flags = 0;
  if(gSSLStatus.isUntrusted)
    flags |= overrideService.ERROR_UNTRUSTED;
  if(gSSLStatus.isDomainMismatch)
    flags |= overrideService.ERROR_MISMATCH;
  if(gSSLStatus.isNotValidAtThisTime)
    flags |= overrideService.ERROR_TIME;
```

# 2.10 - WebDriver For Mobile Browsers

# 2.11 - Frequently Asked Questions for Selenium 2

```
WebDriver driver; // Assigned elsewhere
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("return document.title");
```

Other language bindings will follow a similar approach. Take a look at the UsingJavascript page for more information.

### Q: Why is my Javascript execution always returning null?

A: You need to return from your javascript snippet to return a value, so:

```
js.executeScript("document.title");
```

will return null, but:

```
js.executeScript("return document.title");
```

will return the title of the document.

### Q: My XPath finds elements in one browser, but not in others. Why is this?

A: The short answer is that each supported browser handles XPath slightly differently, and you’re probably running into one of these differences. The long answer is on the XpathInWebDriver page.

### Q: The InternetExplorerDriver does not work well on Vista. How do I get it to work as expected?

A: The InternetExplorerDriver requires that all security domains are set to the same value (either trusted or untrusted) If you’re not in a position to modify the security domains, then you can override the check like this:

```
DesiredCapabilities capabilities = DesiredCapabilities.internetExplorer();
capabilities.setCapability(InternetExplorerDriver.INTRODUCE_FLAKINESS_BY_IGNORING_SECURITY_DOMAINS, true);
WebDriver driver = new InternetExplorerDriver(capabilities);
```

```
// Get a handle to the open alert, prompt or confirmation
Alert alert = driver.switchTo().alert();
// Get the text of the alert or prompt
alert.getText();  
// And acknowledge the alert (equivalent to clicking "OK")
alert.accept();
```

### Q: Does WebDriver support file uploads?

A: Yes.

You can’t interact with the native OS file browser dialog directly, but we do some magic so that if you call WebElement#sendKeys("/path/to/file") on a file upload element, it does the right thing. Make sure you don’t WebElement#click() the file upload element, or the browser will probably hang.

Handy hint: You can’t interact with hidden elements without making them un-hidden. If your element is hidden, it can probably be un-hidden with some code like:

```
((JavascriptExecutor)driver).executeScript("arguments[0].style.visibility = 'visible'; arguments[0].style.height = '1px'; arguments[0].style.width = '1px'; arguments[0].style.opacity = 1", fileUploadElement);
```

### Q: The “onchange” event doesn’t fire after a call “sendKeys”

A: WebDriver leaves the focus in the element you called “sendKeys” on. The “onchange” event will only fire when focus leaves that element. As such, you need to move the focus, perhaps using a “click” on another element.

### Q: Can I run multiple instances of the WebDriver sub-classes?

A: Each instance of an HtmlUnitDriver, ChromeDriver and FirefoxDriver is completely independent of every other instance (in the case of firefox and chrome, each instance has its own anonymous profile it uses). Because of the way that Windows works, there should only ever be a single InternetExplorerDriver instance at one time. If you need to run more than one instance of the InternetExplorerDriver at a time, consider using the Remote!WebDriver and virtual machines.

### Q: I need to use a proxy. How do I configure that?

A: Proxy configuration is done via the `org.openqa.selenium.Proxy` class like so:

```
Proxy proxy = new Proxy();
proxy.setProxyAutoconfigUrl("http://youdomain/config");

// We use firefox as an example here.
DesiredCapabilities capabilities = DesiredCapabilities.firefox();
capabilities.setCapability(CapabilityType.PROXY, proxy);

// You could use any webdriver implementation here
WebDriver driver = new FirefoxDriver(capabilities);
```

### Q: How do I handle authentication with the HtmlUnitDriver?

A: When creating your instance of the HtmlUnitDriver, override the “modifyWebClient” method, for example:

```
WebDriver driver = new HtmlUnitDriver() {
  protected WebClient modifyWebClient(WebClient client) {
    // This class ships with HtmlUnit itself
    DefaultCredentialsProvider creds = new DefaultCredentialsProvider();

    // Set some example credentials
    creds.addCredentials("username", "password");

    // And now add the provider to the webClient instance
    client.setCredentialsProvider(creds);

    return client;
  }
};
```

### Q: Is WebDriver thread-safe?

A: WebDriver is not thread-safe. Having said that, if you can serialise access to the underlying driver instance, you can share a reference in more than one thread. This is not advisable. You /can/ on the other hand instantiate one WebDriver instance for each thread.

### Q: How do I type into a contentEditable iframe?

A: Assuming that the iframe is named “foo”:

```
driver.switchTo().frame("foo");
WebElement editable = driver.switchTo().activeElement();
editable.sendKeys("Your text here");
```

Sometimes this doesn’t work, and this is because the iframe doesn’t have any content. On Firefox you can execute the following before “sendKeys”:

```
((JavascriptExecutor) driver).executeScript("document.body.innerHTML = '<br>'");
```

This is needed because the iframe has no content by default: there’s nothing to send keyboard input to. This method call inserts an empty tag, which sets everything up nicely.

Remember to switch out of the frame once you’re done (as all further interactions will be with this specific frame):

```
driver.switchTo().defaultContent();
```

### Q: WebDriver fails to start Firefox on Linux due to java.net.SocketException

A: If, when running WebDriver on Linux, Firefox fails to start and the error looks like:

```
Caused by: java.net.SocketException: Invalid argument
        at java.net.PlainSocketImpl.socketBind(Native Method)
        at java.net.PlainSocketImpl.bind(PlainSocketImpl.java:365)
        at java.net.Socket.bind(Socket.java:571)
        at org.openqa.selenium.firefox.internal.SocketLock.isLockFree(SocketLock.java:99)
        at org.openqa.selenium.firefox.internal.SocketLock.lock(SocketLock.java:63)
```

It may be caused due to IPv6 settings on the machine. Execute:

```
sudo sysctl net.ipv6.bindv6only=0
```

```
WebElement element = ...;
((JavascriptExecutor) driver).executeScript("return arguments[0].getText();", element);
```

### Q: How do I start Firefox with an extension installed?

A:

```
FirefoxProfile profile = new FirefoxProfile()
profile.addExtension(....);

WebDriver driver = new FirefoxDriver(profile);
```

```
driver.findElement(By.tagName("body")).getText()
```

# 2.12 - Selenium 2.0 Team


# 3 - Selenium 3

Selenium 3 was the implementation of WebDriver without the Selenium RC Code. It has since been replaced with Selenium 4, which implements the W3C WebDriver specification.

# 3.1 - Grid 3

Selenium Grid 3 supported WebDriver without Selenium RC code. Grid 3 was completely rewritten for the new Grid 4.

You can read our documentation for more information about [Grid 4](https://www.selenium.dev/documentation/grid/)

*Selenium Grid* is a smart proxy server that allows Selenium tests to route commands to remote web browser instances. Its aim is to provide an easy way to run tests in parallel on multiple machines.

With Selenium Grid, one server acts as the hub that routes JSON formatted test commands to one or more registered Grid nodes. Tests contact the hub to obtain access to remote browser instances. The hub has a list of registered servers that it provides access to, and allows control of these instances.

Selenium Grid allows us to run tests in parallel on multiple machines, and to manage different browser versions and browser configurations centrally (instead of in each individual test).

Selenium Grid is not a silver bullet. It solves a subset of common delegation and distribution problems, but will for example not manage your infrastructure, and might not suit your specific needs.

# 3.2 - Setting up your own Grid 3

```shell
java -jar selenium-server-standalone.jar -role hub
```

The Hub will listen to port 4444 by default. You can view the status of the hub by opening a browser window and navigating to <http://localhost:4444/grid/console>.

To change the default port, you can add the optional `-port` flag with an integer representing the port to listen to when you run the command. Also, all of the other options you see in the JSON config file (seen below) are possible command-line flags.

You certainly can get by with only the simple command shown above, but if you need more advanced configuration, you can also specify a JSON format config file, for convenience, to configure the hub when you start it. You can do it like so:

```shell
java -jar selenium-server-standalone.jar -role hub -hubConfig hubConfig.json -debug
```

Below you will see an example of a `hubConfig.json` file. We will go into more detail on how to provide node configuration files in step 2.

```json
{
  "_comment" : "Configuration for Hub - hubConfig.json",
  "host": ip,
  "maxSession": 5,
  "port": 4444,
  "cleanupCycle": 5000,
  "timeout": 300000,
  "newSessionWaitTimeout": -1,
  "servlets": [],
  "prioritizer": null,
  "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
  "throwOnCapabilityNotPresent": true,
  "nodePolling": 180000,
  "platform": "WINDOWS"}
```

### Step 2: Start the Nodes

Regardless of whether you want to run a grid with new WebDriver functionality, or a grid with Selenium 1 RC functionality, or both at the same time, you use the same `selenium-server-standalone.jar` file to start the nodes:

```shell
java -jar selenium-server-standalone.jar -role node -hub http://localhost:4444
```

```shell
java -Dwebdriver.chrome.driver=chromedriver.exe -jar selenium-server-standalone.jar -role node -nodeConfig node1Config.json
```

And here is an example of a `nodeConfig.json` file:

```json
{
  "capabilities": [
    {
      "browserName": "firefox",
      "acceptSslCerts": true,
      "javascriptEnabled": true,
      "takesScreenshot": false,
      "firefox_profile": "",
      "browser-version": "27",
      "platform": "WINDOWS",
      "maxInstances": 5,
      "firefox_binary": "",
      "cleanSession": true
    },
    {
      "browserName": "chrome",
      "maxInstances": 5,
      "platform": "WINDOWS",
      "webdriver.chrome.driver": "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"
    },
    {
      "browserName": "internet explorer",
      "maxInstances": 1,
      "platform": "WINDOWS",
      "webdriver.ie.driver": "C:/Program Files (x86)/Internet Explorer/iexplore.exe"
    }
  ],
  "configuration": {
    "_comment" : "Configuration for Node",
    "cleanUpCycle": 2000,
    "timeout": 30000,
    "proxy": "org.openqa.grid.selenium.proxy.WebDriverRemoteProxy",
    "port": 5555,
    "host": ip,
    "register": true,
    "hubPort": 4444,
    "maxSession": 5
  }
}
```

```shell
java -jar selenium-server-standalone.jar -role hub -log log.txt
```

Use your favorite text editor to open log file (log.txt in the example above) to find “ERROR” logs if you get issues.

### Using `-debug` argument

Also you can use `-debug` argument to print debug logs to console. Start Selenium Grid Hub or Node with `-debug` argument. Please see the below example:

```shell
java -jar selenium-server-standalone.jar -role hub -debug
```

# 3.3 - Components of Grid 3


# 4 - Legacy Selenium IDE

```html
<tr>
    <td>Command</td>
    <td>target (locator)</td>
    <td>Value</td>
</tr>
```

|            |              |       |
| ---------- | ------------ | ----- |
| verifyText | //div//a\[2] | Login |

The parameters are not always required; it depends on the command. In some cases both are required, in others one parameter is required, and in still others the command may take no parameters at all. Here are a couple more examples:

|                   |             |                         |
| ----------------- | ----------- | ----------------------- |
| goBackAndWait     |             |                         |
| verifyTextPresent |             | Welcome to My Home Page |
| type              | id=phone    | (555) 666-7066          |
| type              | id=address1 | ${myVariableAddress}    |

```html
<table>
    <tr><td>open</td><td>/download/</td><td></td></tr>
    <tr><td>assertTitle</td><td></td><td>Downloads</td></tr>
    <tr><td>verifyText</td><td>//h2</td><td>Downloads</td></tr>
</table>
```

Rendered as a table in a browser this would look like the following:

|             |            |           |
| ----------- | ---------- | --------- |
| open        | /download/ |           |
| assertTitle |            | Downloads |
| verifyText  | //h2       | Downloads |

The Selenese HTML syntax can be used to write and run tests without requiring knowledge of a programming language. With a basic knowledge of selenese and Selenium-IDE you can quickly produce and run testcases.

## Test Suites

A test suite is a collection of tests. Often one will run all the tests in a test suite as one continuous batch-job.

When using Selenium-IDE, test suites also can be defined using a simple HTML file. The syntax again is simple. An HTML table defines a list of tests where each row defines the filesystem path to each test. An example tells it all.

```html
<html>
<head>
<title>Test Suite Function Tests - Priority 1</title>
</head>
<body>
<table>
  <tr><td><b>Suite Of Tests</b></td></tr>
  <tr><td><a href="./Login.html">Login</a></td></tr>
  <tr><td><a href="./SearchValues.html">Test Searching for Values</a></td></tr>
  <tr><td><a href="./SaveValues.html">Test Save</a></td></tr>
</table>
</body>
</html>
```

| Command     | Target     | Value        |
| ----------- | ---------- | ------------ |
| open        | /download/ |              |
| assertTitle |            | Downloads    |
| verifyText  | //h2       | Downloads    |
| assertTable | 1.2.1      | Selenium IDE |
| verifyTable | 1.2.2      | June 3, 2008 |
| verifyTable | 1.2.3      | 1.0 beta 2   |

The above example first opens a page and then “asserts” that the correct page is loaded by comparing the title with the expected value. Only if this passes will the following command run and “verify” that the text is present in the expected location. The test case then “asserts” the first column in the second row of the first table contains the expected value, and only if this passed will the remaining cells in that row be “verified”.

### **verifyTextPresent**

The command `verifyTextPresent` is used to verify specific text exists somewhere on the page. It takes a single argument–the text pattern to be verified. For example:

| Command           | Target             | Value |
| ----------------- | ------------------ | ----- |
| verifyTextPresent | Marketing Analysis |       |

This would cause Selenium to search for, and verify, that the text string “Marketing Analysis” appears somewhere on the page currently being tested. Use verifyTextPresent when you are interested in only the text itself being present on the page. Do not use this when you also need to test where the text occurs on the page.

### **verifyElementPresent**

Use this command when you must test for the presence of a specific UI element, rather than its content. This verification does not check the text, only the HTML tag. One common use is to check for the presence of an image.

| Command              | Target      | Value |
| -------------------- | ----------- | ----- |
| verifyElementPresent | //div/p/img |       |

This command verifies that an image, specified by the existence of an HTML tag, is present on the page, and that it follows a

tag and a

tag. The first (and only) parameter is a locator for telling the Selenese command how to find the element. Locators are explained in the next section.

`verifyElementPresent` can be used to check the existence of any HTML tag within the page. You can check the existence of links, paragraphs, divisions

, etc. Here are a few more examples.

| Command              | Target                        | Value |
| -------------------- | ----------------------------- | ----- |
| verifyElementPresent | //div/p                       |       |
| verifyElementPresent | //div/a                       |       |
| verifyElementPresent | id=Login                      |       |
| verifyElementPresent | link=Go to Marketing Research |       |
| verifyElementPresent | //a\[2]                       |       |
| verifyElementPresent | //head/title                  |       |

These examples illustrate the variety of ways a UI element may be tested. Again, locators are explained in the next section.

### **verifyText**

Use `verifyText` when both the text and its UI element must be tested. verifyText must use a locator. If you choose an *XPath* or *DOM* locator, you can verify that specific text appears at a specific location on the page relative to other UI components on the page.

| Command    | Target              | Value                                                               |
| ---------- | ------------------- | ------------------------------------------------------------------- |
| verifyText | //table/tr/td/div/p | This is my text and it occurs right after the div inside the table. |

## Locating Elements

For many Selenium commands, a target is required. This target identifies an element in the content of the web application, and consists of the location strategy followed by the location in the format `locatorType=location`. The locator type can be omitted in many cases. The various locator types are explained below with examples for each.

### Locating by Identifier

This is probably the most common method of locating elements and is the catch-all default when no recognized locator type is used. With this strategy, the first element with the id attribute value matching the location will be used. If no element has a matching id attribute, then the first element with a name attribute matching the location will be used.

For instance, your page source could have id and name attributes as follows:

```html
  <html>
   <body>
    <form id="loginForm">
     <input name="username" type="text" />
     <input name="password" type="password" />
     <input name="continue" type="submit" value="Login" />
    </form>
   </body>
  <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
    </body>
   <html>
```

* `id=loginForm` (3)

### Locating by Name

The name locator type will locate the first element with a matching name attribute. If multiple elements have the same value for a name attribute, then you can use filters to further refine your location strategy. The default filter type is value (matching the value attribute).

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
  <html>
   <body>
    <p>Are you sure you want to do this?</p>
    <a href="continue.html">Continue</a> 
    <a href="cancel.html">Cancel</a>
  </body>
  <html>
```

* `link=Continue` (4)
* `link=Cancel` (5)

### Locating by DOM

The Document Object Model represents an HTML document and can be accessed using JavaScript. This location strategy takes JavaScript that evaluates to an element on the page, which can be simply the element’s location using the hierarchical dotted notation.

Since only `dom` locators start with “document”, it is not necessary to include the `dom=` label when specifying a DOM locator.

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input class="required" name="username" type="text" />
      <input class="required passfield" name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | glob:\*Film\*Television\*             |       |

The actual title of the page reached by clicking on the link was “De Anza Film And Television Department - Menu”. By using a pattern rather than the exact text, the `verifyTitle` will pass as long as the two words “Film” and “Television” appear (in that order) anywhere in the page’s title. For example, if the page’s owner should shorten the title to just “Film & Television Department,” the test would still pass. Using a pattern for both a link and a simple test that the link worked (such as the `verifyTitle` above does) can greatly reduce the maintenance for such test cases.

#### Regular Expression Patterns

*Regular expression* patterns are the most powerful of the three types of patterns that Selenese supports. Regular expressions are also supported by most high-level programming languages, many text editors, and a host of tools, including the Linux/Unix command-line utilities **grep**, **sed**, and **awk**. In Selenese, regular expression patterns allow a user to perform many tasks that would be very difficult otherwise. For example, suppose your test needed to ensure that a particular table cell contained nothing but a number. `regexp: [0-9]+` is a simple pattern that will match a decimal number of any length.

Whereas Selenese globbing patterns support only the **\*** and **\[ ]** (character class) features, Selenese regular expression patterns offer the same wide array of special characters that exist in JavaScript. Below are a subset of those special characters:

| PATTERN | MATCH                                                                            |
| ------- | -------------------------------------------------------------------------------- |
| .       | any single character                                                             |
| \[ ]    | character class: any single character that appears inside the brackets           |
| \*      | quantifier: 0 or more of the preceding character (or group)                      |
| +       | quantifier: 1 or more of the preceding character (or group)                      |
| ?       | quantifier: 0 or 1 of the preceding character (or group)                         |
| {1,5}   | quantifier: 1 through 5 of the preceding character (or group)                    |
| \|      | alternation: the character/group on the left or the character/group on the right |
| ( )     | grouping: often used with alternation and/or quantifier                          |

Regular expression patterns in Selenese need to be prefixed with either `regexp:` or `regexpi:`. The former is case-sensitive; the latter is case-insensitive.

A few examples will help clarify how regular expression patterns can be used with Selenese commands. The first one uses what is probably the most commonly used regular expression pattern–**.\*** (“dot star”). This two-character sequence can be translated as “0 or more occurrences of any character” or more simply, “anything or nothing.” It is the equivalent of the one-character globbing pattern **\*** (a single asterisk).

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | regexp:.\*Film.\*Television.\*        |       |

The example above is functionally equivalent to the earlier example that used globbing patterns for this same test. The only differences are the prefix (**regexp:** instead of **glob:**) and the “anything or nothing” pattern (**.\*** instead of just **\***).

The more complex example below tests that the Yahoo! Weather page for Anchorage, Alaska contains info on the sunrise time:

| Command           | Target                                            | Value |
| ----------------- | ------------------------------------------------- | ----- |
| open              | <http://weather.yahoo.com/forecast/USAK0012.html> |       |
| verifyTextPresent | regexp:Sunrise: \*\[0-9]{1,2}:\[0-9]{2} \[ap]m    |       |

Let’s examine the regular expression above one part at a time:

|              |                                                      |
| ------------ | ---------------------------------------------------- |
| `Sunrise: *` | The string **Sunrise:** followed by 0 or more spaces |
| `[0-9]{1,2}` | 1 or 2 digits (for the hour of the day)              |
| `:`          | The character **:** (no special characters involved) |
| `[0-9]{2}`   | 2 digits (for the minutes) followed by a space       |
| `[ap]m`      | “a” or “p” followed by “m” (am or pm)                |

#### Exact Patterns

The **exact** type of Selenium pattern is of marginal usefulness. It uses no special characters at all. So, if you needed to look for an actual asterisk character (which is special for both globbing and regular expression patterns), the **exact** pattern would be one way to do that. For example, if you wanted to select an item labeled “Real \*” from a dropdown, the following code might work or it might not. The asterisk in the `glob:Real *` pattern will match anything or nothing. So, if there was an earlier select option labeled “Real Numbers,” it would be the option selected rather than the “Real \*” option.

| Command | Target   | Value        |
| ------- | -------- | ------------ |
| select  | //select | glob:Real \* |

In order to ensure that the “Real \*” item would be selected, the `exact:` prefix could be used to create an **exact** pattern as shown below:

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| select  | //select | exact:Real \* |

But the same effect could be achieved via escaping the asterisk in a regular expression pattern:

| Command | Target   | Value            |
| ------- | -------- | ---------------- |
| select  | //select | regexp:Real \\\* |

| Command | Target            | Value |
| ------- | ----------------- | ----- |
| store   | <paul@mysite.org> |       |

Later in your script, you’ll want to use the stored value of your variable. To access the value of a variable, enclose the variable in curly brackets ({}) and precede it with a dollar sign like this.

| Command    | Target  | Value         |
| ---------- | ------- | ------------- |
| verifyText | //div/p | \\${userName} |

A common use of variables is for storing input for an input field.

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| type    | id=login | \\${userName} |

| Command         | Target                                         | Value       |
| --------------- | ---------------------------------------------- | ----------- |
| store           | 10                                             | hits        |
| storeXpathCount | //blockquote                                   | blockquotes |
| storeEval       | storedVars\[‘hits’].storedVars\[‘blockquotes’] | paragraphs  |

This next example illustrates how a JavaScript snippet can include calls to methods, in this case the JavaScript String object’s `toUpperCase` method and `toLowerCase` method.

| Command   | Target                            | Value |
| --------- | --------------------------------- | ----- |
| store     | Edith Wharton                     | name  |
| storeEval | storedVars\[’name’].toUpperCase() | uc    |
| storeEval | storedVars\[’name’].toUpperCase() | lc    |

#### JavaScript Usage with Non-Script Parameters

JavaScript can also be used to help generate values for parameters, even when the parameter is not specified to be of type **script**.\
However, in this case, special syntax is required–the *entire* parameter value must be prefixed by `javascript{` with a trailing `}`, which encloses the JavaScript snippet, as in `javascript{*yourCodeHere*}`. Below is an example in which the `type` command’s second parameter `value` is generated via JavaScript code using this special syntax:

| Command | Target            | Value                                                 |
| ------- | ----------------- | ----------------------------------------------------- |
| store   | league of nations | searchString                                          |
| type    | q                 | javascript{storedVars\[‘searchString’].toUpperCase()} |

## *echo* - The Selenese Print Command

Selenese has a simple command that allows you to print text to your test’s output. This is useful for providing informational progress notes in your test which display on the console as your test is running. These notes also can be used to provide context within your test result reports, which can be useful for finding where a defect exists on a page in the event your test finds a problem. Finally, echo statements can be used to print the contents of Selenium variables.

| Command | Target                    | Value |
| ------- | ------------------------- | ----- |
| echo    | Testing page footer now.  |       |
| echo    | Username is \\${userName} |       |

## Alerts, Popups, and Multiple Windows

Suppose that you are testing a page that looks like this.

```html
  <!DOCTYPE HTML>
  <html>
  <head>
    <script type="text/javascript">
      function output(resultText){
        document.getElementById('output').childNodes[0].nodeValue=resultText;
      }

      function show_confirm(){
        var confirmation=confirm("Chose an option.");
        if (confirmation==true){
          output("Confirmed.");
        }
        else{
          output("Rejected!");
        }
      }
      
      function show_alert(){
        alert("I'm blocking!");
        output("Alert is gone.");
      }
      function show_prompt(){
        var response = prompt("What's the best web QA tool?","Selenium");
        output(response);
      }
      function open_window(windowName){
        window.open("newWindow.html",windowName);
      }
      </script>
  </head>
  <body>

    <input type="button" id="btnConfirm" onclick="show_confirm()" value="Show confirm box" />
    <input type="button" id="btnAlert" onclick="show_alert()" value="Show alert" />
    <input type="button" id="btnPrompt" onclick="show_prompt()" value="Show prompt" />
    <a href="newWindow.html" id="lnkNewWindow" target="_blank">New Window Link</a>
    <input type="button" id="btnNewNamelessWindow" onclick="open_window()" value="Open Nameless Window" />
    <input type="button" id="btnNewNamedWindow" onclick="open_window('Mike')" value="Open Named Window" />

    <br />
    <span id="output">
    </span>
  </body>
  </html>
```

The user must respond to alert/confirm boxes, as well as moving focus to newly opened popup windows. Fortunately, Selenium can cover JavaScript pop-ups.

But before we begin covering alerts/confirms/prompts in individual detail, it is helpful to understand the commonality between them. Alerts, confirmation boxes and prompts all have variations of the following

| Command                   | Description                                                           |
| ------------------------- | --------------------------------------------------------------------- |
| assertFoo(pattern)        | throws error if pattern doesn’t match the text of the pop-up          |
| assertFooPresent          | throws error if pop-up is not available                               |
| assertFooNotPresent       | throws error if any pop-up is present                                 |
| storeFoo(variable)        | stores the text of the pop-up in a variable                           |
| storeFooPresent(variable) | stores the text of the pop-up in a variable and returns true or false |

When running under Selenium, JavaScript pop-ups will not appear. This is because the function calls are actually being overridden at runtime by Selenium’s own JavaScript. However, just because you cannot see the pop-up doesn’t mean you don’t have to deal with it. To handle a pop-up, you must call its `assertFoo(pattern)` function. If you fail to assert the presence of a pop-up your next command will be blocked and you will get an error similar to the following `[error] Error: There was an unexpected Confirmation! [Chose an option.]`

### Alerts

Let’s start with alerts because they are the simplest pop-up to handle. To begin, open the HTML sample above in a browser and click on the “Show alert” button. You’ll notice that after you close the alert the text “Alert is gone.” is displayed on the page. Now run through the same steps with Selenium IDE recording, and verify the text is added after you close the alert. Your test will look something like this:

| Command           | Target         | Value |
| ----------------- | -------------- | ----- |
| open              | /              |       |
| click             | btnAlert       |       |
| assertAlert       | I’m blocking!  |       |
| verifyTextPresent | Alert is gone. |       |

You may be thinking “That’s odd, I never tried to assert that alert.” But this is Selenium-IDE handling and closing the alert for you. If you remove that step and replay the test you will get the following error `[error] Error: There was an unexpected Alert! [I'm blocking!]`. You must include an assertion of the alert to acknowledge its presence.

If you just want to assert that an alert is present but either don’t know or don’t care what text it contains, you can use `assertAlertPresent`. This will return true or false, with false halting the test.

### Confirmations

Confirmations behave in much the same way as alerts, with `assertConfirmation` and `assertConfirmationPresent` offering the same characteristics as their alert counterparts. However, by default Selenium will select OK when a confirmation pops up. Try recording clicking on the “Show confirm box” button in the sample page, but click on the “Cancel” button in the popup, then assert the output text. Your test may look something like this:

| Command                        | Target            | Value |
| ------------------------------ | ----------------- | ----- |
| open                           | /                 |       |
| click                          | btnConfirm        |       |
| chooseCancelOnNextConfirmation |                   |       |
| assertConfirmation             | Choose an option. |       |
| verifyTextPresent              | Rejected          |       |

The `chooseCancelOnNextConfirmation` function tells Selenium that all following confirmation should return false. It can be reset by calling chooseOkOnNextConfirmation.

You may notice that you cannot replay this test, because Selenium complains that there is an unhandled confirmation. This is because the order of events Selenium-IDE records causes the click and chooseCancelOnNextConfirmation to be put in the wrong order (it makes sense if you think about it, Selenium can’t know that you’re cancelling before you open a confirmation) Simply switch these two commands and your test will run fine.

### Prompts

Prompts behave in much the same way as alerts, with `assertPrompt` and `assertPromptPresent` offering the same characteristics as their alert counterparts. By default, Selenium will wait for you to input data when the prompt pops up. Try recording clicking on the “Show prompt” button in the sample page and enter “Selenium” into the prompt. Your test may look something like this:

| Command            | Target                       | Value |
| ------------------ | ---------------------------- | ----- |
| open               | /                            |       |
| answerOnNextPrompt | Selenium!                    |       |
| click              | id=btnPrompt                 |       |
| assertPrompt       | What’s the best web QA tool? |       |
| verifyTextPresent  | Selenium!                    |       |

```html
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Sample Selenium Test Suite</title>
    </head>
    <body>
        <table cellpadding="1" cellspacing="1" border="1">
            <thead>
                <tr><td>Test Cases for De Anza A-Z Directory Links</td></tr>
            </thead>
        <tbody>
            <tr><td><a href="./a.html">A Links</a></td></tr>
            <tr><td><a href="./b.html">B Links</a></td></tr>
            <tr><td><a href="./c.html">C Links</a></td></tr>
            <tr><td><a href="./d.html">D Links</a></td></tr>
        </tbody>
        </table>
    </body>
</html>
```

***

*error loading test case: no command found*

You’ve used **File=>Open** to try to open a test suite file. Use **File=>Open Test Suite** instead.

An enhancement request has been raised to improve this error message. See [issue 1010](http://code.google.com/p/selenium/issues/detail?id=1010).

***

This type of **error** may indicate a timing problem, i.e., the element specified by a locator in your command wasn’t fully loaded when the command was executed. Try putting a **pause 5000** before the command to determine whether the problem is indeed related to timing. If so, investigate using an appropriate **waitFor\*** or **\*AndWait** command before the failing command.

***

Whenever your attempt to use variable substitution fails as is the case for the **open** command above, it indicates that you haven’t actually created the variable whose value you’re trying to access. This is sometimes due to putting the variable in the **Value** field when it should be in the **Target** field or vice versa. In the example above, the two parameters for the **store** command have been erroneously placed in the reverse order of what is required. For any Selenese command, the first required parameter must go in the **Target** field, and the second required parameter (if one exists) must go in the **Value** field.

***

*error loading test case: \[Exception… “Component returned failure code: 0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND) \[nsIFileInputStream.init]” nresult: “0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND)” location: “JS frame :: chrome://selenium-ide/content/file-utils.js :: anonymous :: line 48” data: no]*

One of the test cases in your test suite cannot be found. Make sure that the test case is indeed located where the test suite indicates it is located. Also, make sure that your actual test case files have the .html extension both in their filenames, and in the test suite file where they are referenced.

An enhancement request has been raised to improve this error message. See [issue 1011](http://code.google.com/p/selenium/issues/detail?id=1011).

***

Your extension file’s contents have not been read by Selenium-IDE. Be sure you have specified the proper pathname to the extensions file via **Options=>Options=>General** in the **Selenium Core extensions** field. Also, Selenium-IDE must be restarted after any change to either an extensions file *or* to the contents of the **Selenium Core extensions** field.

# 4.1 - HTML runner

```shell
[user@localhost ~]$ cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

[user@localhost ~]$ rpm -qa | egrep -i "xvfb|java-1.8|firefox"
xorg-x11-server-Xvfb-1.19.3-11.el7.x86_64
firefox-52.4.0-1.el7.centos.x86_64
java-1.8.0-openjdk-1.8.0.151-1.b12.el7_4.x86_64
java-1.8.0-openjdk-headless-1.8.0.151-1.b12.el7_4.x86_64
```

Test Suite example:

```html
[user@localhost ~]$ cat testsuite.html
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
  <title>Test Suite</title>
</head>
<body>
<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium"><tbody>
<tr><td><b>Test Suite</b></td></tr>
<tr><td><a href="YOUR-TEST-SCENARIO.html">YOUR-TEST-SCENARIO</a></td></tr>
</tbody></table>
</body>
</html>
```

## How to run selenium-html-runner headless

Now, the most important part, an example of how to run the selenium-html-runner! Your experience might vary depending on software combinations - geckodriver/FF/html-runner releases.

```shell
xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
```

```shell
[user@localhost ~]$ xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "*firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
Multi-window mode is longer used as an option and will be ignored.
1510061109691   geckodriver     INFO    geckodriver 0.18.0
1510061109708   geckodriver     INFO    Listening on 127.0.0.1:2885
1510061110162   geckodriver::marionette INFO    Starting browser /usr/bin/firefox with args ["-marionette"]
1510061111084   Marionette      INFO    Listening on port 43229
1510061111187   Marionette      WARN    TLS certificate errors will be ignored for this session
Nov 07, 2017 1:25:12 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
2017-11-07 13:25:12.714:INFO::main: Logging initialized @3915ms to org.seleniumhq.jetty9.util.log.StdErrLog
2017-11-07 13:25:12.804:INFO:osjs.Server:main: jetty-9.4.z-SNAPSHOT
2017-11-07 13:25:12.822:INFO:osjsh.ContextHandler:main: Started o.s.j.s.h.ContextHandler@87a85e1{/tests,null,AVAILABLE}
2017-11-07 13:25:12.843:INFO:osjs.AbstractConnector:main: Started ServerConnector@52102734{HTTP/1.1,[http/1.1]}{0.0.0.0:31892}
2017-11-07 13:25:12.843:INFO:osjs.Server:main: Started @4045ms
Nov 07, 2017 1:25:13 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |open | /auth_mellon.php |  |
Nov 07, 2017 1:25:14 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |waitForPageToLoad | 3000 |  |
.
.
.etc

<td>result:</td>
<td>PASS</td>
```

# 4.2 - Legacy Selenium IDE Release Notes

| 73% (22) | Samit Badle             |
| -------- | ----------------------- |
| 16%( 5)  | Adam Goucher            |
| 6% (2)   | Dave Hunt               |
| 3% (1)   | Santiago Suarez Ordoñez |
| 3% (1)   | Simon Stewart           |

# 5 - JSON Wire Protocol Specification

| **Key** | **Type** | **Description**                                                                                                                    |
| ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| ELEMENT | string   | The opaque ID assigned to the element by the server. This ID should be used in all subsequent commands issued against the element. |

### Capabilities JSON Object

Not all server implementations will support every WebDriver feature. Therefore, the client and server should use JSON objects with the properties listed below when describing which features a session supports.

| **Key**                  | **Type**     | **Description**                                                                                                                                                                                                                                          |
| ------------------------ | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| browserName              | string       | The name of the browser being used; should be one of `{android, chrome, firefox, htmlunit, internet explorer, iPhone, iPad, opera, safari}`.                                                                                                             |
| version                  | string       | The browser version, or the empty string if unknown.                                                                                                                                                                                                     |
| platform                 | string       | A key specifying which platform the browser is running on. This value should be one of `{WINDOWS\|XP\|VISTA\|MAC\|LINUX\|UNIX}`. When requesting a new session, the client may specify `ANY` to indicate any available platform may be used.             |
| javascriptEnabled        | boolean      | Whether the session supports executing user supplied JavaScript in the context of the current page.                                                                                                                                                      |
| takesScreenshot          | boolean      | Whether the session supports taking screenshots of the current page.                                                                                                                                                                                     |
| handlesAlerts            | boolean      | Whether the session can interact with modal popups, such as `window.alert` and `window.confirm`.                                                                                                                                                         |
| databaseEnabled          | boolean      | Whether the session can interact database storage.                                                                                                                                                                                                       |
| locationContextEnabled   | boolean      | Whether the session can set and query the browser's location context.                                                                                                                                                                                    |
| applicationCacheEnabled  | boolean      | Whether the session can interact with the application cache.                                                                                                                                                                                             |
| browserConnectionEnabled | boolean      | Whether the session can query for the browser's connectivity and disable it if desired.                                                                                                                                                                  |
| cssSelectorsEnabled      | boolean      | Whether the session supports CSS selectors when searching for elements.                                                                                                                                                                                  |
| webStorageEnabled        | boolean      | Whether the session supports interactions with [storage objects](http://www.w3.org/TR/2009/WD-webstorage-20091029/).                                                                                                                                     |
| rotatable                | boolean      | Whether the session can rotate the current page's current layout between portrait and landscape orientations (only applies to mobile platforms).                                                                                                         |
| acceptSslCerts           | boolean      | Whether the session should accept all SSL certs by default.                                                                                                                                                                                              |
| nativeEvents             | boolean      | Whether the session is capable of generating native events when simulating user input.                                                                                                                                                                   |
| proxy                    | proxy object | Details of any proxy to use. If no proxy is specified, whatever the system's current or default state is used. The format is specified under Proxy JSON Object.                                                                                          |
| unexpectedAlertBehaviour | string       | What the browser should do with an unhandled alert before throwing out the UnhandledAlertException. Possible values are "accept", "dismiss" and "ignore"                                                                                                 |
| elementScrollBehavior    | integer      | Allows the user to specify whether elements are scrolled into the viewport for interaction to align with the top (0) or bottom (1) of the viewport. The default value is to align with the top of the viewport. Supported in IE and Firefox (since 2.36) |

### Desired Capabilities

A Capabilities JSON Object sent by the client describing the capabilities a new session created by the server should possess. Any omitted keys implicitly indicate the corresponding capability is irrelevant. More at [DesiredCapabilities](DesiredCapabilities.md).

### Actual Capabilities

A Capabilities JSON Object returned by the server describing what features a session actually supports. Any omitted keys implicitly indicate the corresponding capability is not supported.

### Cookie JSON Object

A JSON object describing a Cookie.

| **Key**  | **Type** | **Description**                                                                                |
| -------- | -------- | ---------------------------------------------------------------------------------------------- |
| name     | string   | The name of the cookie.                                                                        |
| value    | string   | The cookie value.                                                                              |
| path     | string   | (Optional) The cookie path.1                                                                   |
| domain   | string   | (Optional) The domain the cookie is visible to.1                                               |
| secure   | boolean  | (Optional) Whether the cookie is a secure cookie.1                                             |
| httpOnly | boolean  | (Optional) Whether the cookie is an httpOnly cookie.1                                          |
| expiry   | number   | (Optional) When the cookie expires, specified in seconds since midnight, January 1, 1970 UTC.1 |

1 When returning Cookie objects, the server should only omit an optional field if it is incapable of providing the information.

### Log Entry JSON Object

A JSON object describing a log entry.

| **Key**   | **Type** | **Description**                                                                     |
| --------- | -------- | ----------------------------------------------------------------------------------- |
| timestamp | number   | The timestamp of the entry.                                                         |
| level     | string   | The log level of the entry, for example, "INFO" (see [log levels](#Log_Levels.md)). |
| message   | string   | The log message.                                                                    |

### Log Levels

Log levels in order, with finest level on top and coarsest level at the bottom.

| **Level** | **Description**                                                           |
| --------- | ------------------------------------------------------------------------- |
| ALL       | All log messages. Used for fetching of logs and configuration of logging. |
| DEBUG     | Messages for debugging.                                                   |
| INFO      | Messages with user information.                                           |
| WARNING   | Messages corresponding to non-critical problems.                          |
| SEVERE    | Messages corresponding to critical errors.                                |
| OFF       | No log messages. Used for configuration of logging.                       |

### Log Type

The table below lists common log types. Other log types, for instance, for performance logging may also be available.

| **Log Type** | **Description**          |
| ------------ | ------------------------ |
| client       | Logs from the client.    |
| driver       | Logs from the webdriver. |
| browser      | Logs from the browser.   |
| server       | Logs from the server.    |

### Proxy JSON Object

A JSON object describing a Proxy configuration.

| **Key**                                   | **Type** | **Description**                                                                                                                                                                                                                                                                                                                                                |
| ----------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| proxyType                                 | string   | (Required) The type of proxy being used. Possible values are: **direct** - A direct connection - no proxy in use, **manual** - Manual proxy settings configured, e.g. setting a proxy for HTTP, a proxy for FTP, etc, **pac** - Proxy autoconfiguration from a URL, **autodetect** - Proxy autodetection, probably with WPAD, **system** - Use system settings |
| proxyAutoconfigUrl                        | string   | (Required if proxyType == **pac**, Ignored otherwise) Specifies the URL to be used for proxy autoconfiguration. Expected format example: <http://hostname.com:1234/pacfile>                                                                                                                                                                                    |
| ftpProxy, httpProxy, sslProxy, socksProxy | string   | (Optional, Ignored if proxyType != **manual**) Specifies the proxies to be used for FTP, HTTP, HTTPS and SOCKS requests respectively. Behaviour is undefined if a request is made, where the proxy for the particular protocol is undefined, if proxyType is **manual**. Expected format example: hostname.com:1234                                            |
| socksUsername                             | string   | (Optional, Ignored if proxyType != **manual** and socksProxy is not set) Specifies SOCKS proxy username.                                                                                                                                                                                                                                                       |
| socksPassword                             | string   | (Optional, Ignored if proxyType != **manual** and socksProxy is not set) Specifies SOCKS proxy password.                                                                                                                                                                                                                                                       |
| noProxy                                   | string   | (Optional, Ignored if proxyType != **manual**) Specifies proxy bypass addresses. Format is driver specific.                                                                                                                                                                                                                                                    |

## Messages

### Commands

WebDriver command messages should conform to the [HTTP/1.1 request specification](http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5). Although the server may be extended to respond to other content-types, the wire protocol dictates that all commands accept a content-type of `application/json;charset=UTF-8`. Likewise, the message bodies for POST and PUT request must use an `application/json;charset=UTF-8` content-type.

Each command in the WebDriver service will be mapped to an HTTP method at a specific path. Path segments prefixed with a colon (:) indicate that segment is a variable used to further identify the underlying resource. For example, consider an arbitrary resource mapped as:

```
GET /favorite/color/:name
```

Given this mapping, the server should respond to GET requests sent to “/favorite/color/Jack” and “/favorite/color/Jill”, with the variable `:name` set to “Jack” and “Jill”, respectively.

### Responses

Command responses shall be sent as [HTTP/1.1 response messages](http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6). If the remote server must return a 4xx response, the response body shall have a Content-Type of text/plain and the message body shall be a descriptive message of the bad request. For all other cases, if a response includes a message body, it must have a Content-Type of application/json;charset=UTF-8 and will be a JSON object with the following properties:

| **Key**   | **Type** | **Description**                                                                                          |
| --------- | -------- | -------------------------------------------------------------------------------------------------------- |
| sessionId | string   | null                                                                                                     |
| status    | number   | A status code summarizing the result of the command. A non-zero value indicates that the command failed. |
| value     | `*`      | The response JSON value.                                                                                 |

#### Response Status Codes

The wire protocol will inherit its status codes from those used by the InternetExplorerDriver:

| **Code** | **Summary**                  | **Detail**                                                                                                                              |
| -------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| 0        | `Success`                    | The command executed successfully.                                                                                                      |
| 6        | `NoSuchDriver`               | A session is either terminated or not started                                                                                           |
| 7        | `NoSuchElement`              | An element could not be located on the page using the given search parameters.                                                          |
| 8        | `NoSuchFrame`                | A request to switch to a frame could not be satisfied because the frame could not be found.                                             |
| 9        | `UnknownCommand`             | The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource. |
| 10       | `StaleElementReference`      | An element command failed because the referenced element is no longer attached to the DOM.                                              |
| 11       | `ElementNotVisible`          | An element command could not be completed because the element is not visible on the page.                                               |
| 12       | `InvalidElementState`        | An element command could not be completed because the element is in an invalid state (e.g. attempting to click a disabled element).     |
| 13       | `UnknownError`               | An unknown server-side error occurred while processing the command.                                                                     |
| 15       | `ElementIsNotSelectable`     | An attempt was made to select an element that cannot be selected.                                                                       |
| 17       | `JavaScriptError`            | An error occurred while executing user supplied JavaScript.                                                                             |
| 19       | `XPathLookupError`           | An error occurred while searching for an element by XPath.                                                                              |
| 21       | `Timeout`                    | An operation did not complete before its timeout expired.                                                                               |
| 23       | `NoSuchWindow`               | A request to switch to a different window could not be satisfied because the window could not be found.                                 |
| 24       | `InvalidCookieDomain`        | An illegal attempt was made to set a cookie under a different domain than the current page.                                             |
| 25       | `UnableToSetCookie`          | A request to set a cookie’s value could not be satisfied.                                                                               |
| 26       | `UnexpectedAlertOpen`        | A modal dialog was open, blocking this operation                                                                                        |
| 27       | `NoAlertOpenError`           | An attempt was made to operate on a modal dialog when one was not open.                                                                 |
| 28       | `ScriptTimeout`              | A script did not complete before its timeout expired.                                                                                   |
| 29       | `InvalidElementCoordinates`  | The coordinates provided to an interactions operation are invalid.                                                                      |
| 30       | `IMENotAvailable`            | IME was not available.                                                                                                                  |
| 31       | `IMEEngineActivationFailed`  | An IME engine could not be started.                                                                                                     |
| 32       | `InvalidSelector`            | Argument was an invalid selector (e.g. XPath/CSS).                                                                                      |
| 33       | `SessionNotCreatedException` | A new session could not be created.                                                                                                     |
| 34       | `MoveTargetOutOfBounds`      | Target provided for a move action is out of bounds.                                                                                     |

| Key        | Type   | Description                                                                                                                                                                                                        |
| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| message    | string | A descriptive message for the command failure.                                                                                                                                                                     |
| screen     | string | (Optional) If included, a screenshot of the current page as a base64 encoded string.                                                                                                                               |
| class      | string | (Optional) If included, specifies the fully qualified class name for the exception that was thrown when the command failed.                                                                                        |
| stackTrace | array  | (Optional) If included, specifies an array of JSON objects describing the stack trace for the exception that was thrown when the command failed. The zeroeth element of the array represents the top of the stack. |

Each JSON object in the stackTrace array must contain the following properties:

| **Key**    | **Type** | **Description**                                                                                                                                                                                                                      |
| ---------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| fileName   | string   | The name of the source file containing the line represented by this frame.                                                                                                                                                           |
| className  | string   | The fully qualified class name for the class active in this frame. If the class name cannot be determined, or is not applicable for the language the server is implemented in, then this property should be set to the empty string. |
| methodName | string   | The name of the method active in this frame, or the empty string if unknown/not applicable.                                                                                                                                          |
| lineNumber | number   | The line number in the original source file for the frame, or 0 if unknown.                                                                                                                                                          |

## Resource Mapping

Resources in the WebDriver REST service are mapped to individual URL patterns. Each resource may respond to one or more HTTP request methods. If a resource responds to a GET request, then it should also respond to HEAD requests. All resources should respond to OPTIONS requests with an `Allow` header field, whose value is a list of all methods that resource responds to.

If a resource is mapped to a URL containing a variable path segment name, that path segment should be used to further route the request. Variable path segments are indicated in the resource mapping by a colon-prefix. For example, consider the following:

```
/favorite/color/:person
```

| **HTTP Method** | **Path**                                                                                                                                  | **Summary**                                                                                                                                                           |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| GET             | [/status](/documentation/legacy/json_wire_protocol/#status)                                                                               | Query the server’s current status.                                                                                                                                    |
| POST            | [/session](/documentation/legacy/json_wire_protocol/#session)                                                                             | Create a new session.                                                                                                                                                 |
| GET             | [/sessions](/documentation/legacy/json_wire_protocol/#sessions)                                                                           | Returns a list of the currently active sessions.                                                                                                                      |
| GET             | [/session/:sessionId](/documentation/legacy/json_wire_protocol/#sessionsessionid)                                                         | Retrieve the capabilities of the specified session.                                                                                                                   |
| DELETE          | [/session/:sessionId](/documentation/legacy/json_wire_protocol/#sessionsessionid)                                                         | Delete the session.                                                                                                                                                   |
| POST            | [/session/:sessionId/timeouts](/documentation/legacy/json_wire_protocol/#sessionsessionidtimeouts)                                        | Configure the amount of time that a particular type of operation can execute for before they are aborted and a                                                        |
| POST            | [/session/:sessionId/timeouts/async\_script](/documentation/legacy/json_wire_protocol/#sessionsessionidtimeoutsasync_script)              | Set the amount of time, in milliseconds, that asynchronous scripts executed by `/session/:sessionId/execute_async` are permitted to run before they are aborted and a |
| POST            | [/session/:sessionId/timeouts/implicit\_wait](/documentation/legacy/json_wire_protocol/#sessionsessionidtimeoutsimplicit_wait)            | Set the amount of time the driver should wait when searching for elements.                                                                                            |
| GET             | [/session/:sessionId/window\_handle](/documentation/legacy/json_wire_protocol/#sessionsessionidwindow_handle)                             | Retrieve the current window handle.                                                                                                                                   |
| GET             | [/session/:sessionId/window\_handles](/documentation/legacy/json_wire_protocol/#sessionsessionidwindow_handles)                           | Retrieve the list of all window handles available to the session.                                                                                                     |
| GET             | [/session/:sessionId/url](/documentation/legacy/json_wire_protocol/#sessionsessionidurl)                                                  | Retrieve the URL of the current page.                                                                                                                                 |
| POST            | [/session/:sessionId/url](/documentation/legacy/json_wire_protocol/#sessionsessionidurl)                                                  | Navigate to a new URL.                                                                                                                                                |
| POST            | [/session/:sessionId/forward](/documentation/legacy/json_wire_protocol/#sessionsessionidforward)                                          | Navigate forwards in the browser history, if possible.                                                                                                                |
| POST            | [/session/:sessionId/back](/documentation/legacy/json_wire_protocol/#sessionsessionidback)                                                | Navigate backwards in the browser history, if possible.                                                                                                               |
| POST            | [/session/:sessionId/refresh](/documentation/legacy/json_wire_protocol/#sessionsessionidrefresh)                                          | Refresh the current page.                                                                                                                                             |
| POST            | [/session/:sessionId/execute](/documentation/legacy/json_wire_protocol/#sessionsessionidexecute)                                          | Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame.                                                            |
| POST            | [/session/:sessionId/execute\_async](/documentation/legacy/json_wire_protocol/#sessionsessionidexecute_async)                             | Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame.                                                            |
| GET             | [/session/:sessionId/screenshot](/documentation/legacy/json_wire_protocol/#sessionsessionidscreenshot)                                    | Take a screenshot of the current page.                                                                                                                                |
| GET             | [/session/:sessionId/ime/available\_engines](/documentation/legacy/json_wire_protocol/#sessionsessionidimeavailable_engines)              | List all available engines on the machine.                                                                                                                            |
| GET             | [/session/:sessionId/ime/active\_engine](/documentation/legacy/json_wire_protocol/#sessionsessionidimeactive_engine)                      | Get the name of the active IME engine.                                                                                                                                |
| GET             | [/session/:sessionId/ime/activated](/documentation/legacy/json_wire_protocol/#sessionsessionidimeactivated)                               | Indicates whether IME input is active at the moment (not if it’s available.                                                                                           |
| POST            | [/session/:sessionId/ime/deactivate](/documentation/legacy/json_wire_protocol/#sessionsessionidimedeactivate)                             | De-activates the currently-active IME engine.                                                                                                                         |
| POST            | [/session/:sessionId/ime/activate](/documentation/legacy/json_wire_protocol/#sessionsessionidimeactivate)                                 | Make an engines that is available (appears on the listreturned by getAvailableEngines) active.                                                                        |
| POST            | [/session/:sessionId/frame](/documentation/legacy/json_wire_protocol/#sessionsessionidframe)                                              | Change focus to another frame on the page.                                                                                                                            |
| POST            | [/session/:sessionId/frame/parent](/documentation/legacy/json_wire_protocol/#sessionsessionidframeparent)                                 | Change focus to the parent context.                                                                                                                                   |
| POST            | [/session/:sessionId/window](/documentation/legacy/json_wire_protocol/#sessionsessionidwindow)                                            | Change focus to another window.                                                                                                                                       |
| DELETE          | [/session/:sessionId/window](/documentation/legacy/json_wire_protocol/#sessionsessionidwindow)                                            | Close the current window.                                                                                                                                             |
| POST            | [/session/:sessionId/window/:windowHandle/size](/documentation/legacy/json_wire_protocol/#sessionsessionidwindowwindowhandlesize)         | Change the size of the specified window.                                                                                                                              |
| GET             | [/session/:sessionId/window/:windowHandle/size](/documentation/legacy/json_wire_protocol/#sessionsessionidwindowwindowhandlesize)         | Get the size of the specified window.                                                                                                                                 |
| POST            | [/session/:sessionId/window/:windowHandle/position](/documentation/legacy/json_wire_protocol/#sessionsessionidwindowwindowhandleposition) | Change the position of the specified window.                                                                                                                          |
| GET             | [/session/:sessionId/window/:windowHandle/position](/documentation/legacy/json_wire_protocol/#sessionsessionidwindowwindowhandleposition) | Get the position of the specified window.                                                                                                                             |
| POST            | [/session/:sessionId/window/:windowHandle/maximize](/documentation/legacy/json_wire_protocol/#sessionsessionidwindowwindowhandlemaximize) | Maximize the specified window if not already maximized.                                                                                                               |
| GET             | [/session/:sessionId/cookie](/documentation/legacy/json_wire_protocol/#sessionsessionidcookie)                                            | Retrieve all cookies visible to the current page.                                                                                                                     |
| POST            | [/session/:sessionId/cookie](/documentation/legacy/json_wire_protocol/#sessionsessionidcookie)                                            | Set a cookie.                                                                                                                                                         |
| DELETE          | [/session/:sessionId/cookie](/documentation/legacy/json_wire_protocol/#sessionsessionidcookie)                                            | Delete all cookies visible to the current page.                                                                                                                       |
| DELETE          | [/session/:sessionId/cookie/:name](/documentation/legacy/json_wire_protocol/#sessionsessionidcookiename)                                  | Delete the cookie with the given name.                                                                                                                                |
| GET             | [/session/:sessionId/source](/documentation/legacy/json_wire_protocol/#sessionsessionidsource)                                            | Get the current page source.                                                                                                                                          |
| GET             | [/session/:sessionId/title](/documentation/legacy/json_wire_protocol/#sessionsessionidtitle)                                              | Get the current page title.                                                                                                                                           |
| POST            | [/session/:sessionId/element](/documentation/legacy/json_wire_protocol/#sessionsessionidelement)                                          | Search for an element on the page, starting from the document root.                                                                                                   |
| POST            | [/session/:sessionId/elements](/documentation/legacy/json_wire_protocol/#sessionsessionidelements)                                        | Search for multiple elements on the page, starting from the document root.                                                                                            |
| POST            | [/session/:sessionId/element/active](/documentation/legacy/json_wire_protocol/#sessionsessionidelementactive)                             | Get the element on the page that currently has focus.                                                                                                                 |
| GET             | [/session/:sessionId/element/:id](/documentation/legacy/json_wire_protocol/#sessionsessionidelementid)                                    | Describe the identified element.                                                                                                                                      |
| POST            | [/session/:sessionId/element/:id/element](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidelement)                     | Search for an element on the page, starting from the identified element.                                                                                              |
| POST            | [/session/:sessionId/element/:id/elements](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidelements)                   | Search for multiple elements on the page, starting from the identified element.                                                                                       |
| POST            | [/session/:sessionId/element/:id/click](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidclick)                         | Click on an element.                                                                                                                                                  |
| POST            | [/session/:sessionId/element/:id/submit](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidsubmit)                       | Submit a `FORM` element.                                                                                                                                              |
| GET             | [/session/:sessionId/element/:id/text](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidtext)                           | Returns the visible text for the element.                                                                                                                             |
| POST            | [/session/:sessionId/element/:id/value](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidvalue)                         | Send a sequence of key strokes to an element.                                                                                                                         |
| POST            | [/session/:sessionId/keys](/documentation/legacy/json_wire_protocol/#sessionsessionidkeys)                                                | Send a sequence of key strokes to the active element.                                                                                                                 |
| GET             | [/session/:sessionId/element/:id/name](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidname)                           | Query for an element’s tag name.                                                                                                                                      |
| POST            | [/session/:sessionId/element/:id/clear](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidclear)                         | Clear a `TEXTAREA` or `text INPUT` element’s value.                                                                                                                   |
| GET             | [/session/:sessionId/element/:id/selected](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidselected)                   | Determine if an `OPTION` element, or an `INPUT` element of type `checkbox` or `radiobutton` is currently selected.                                                    |
| GET             | [/session/:sessionId/element/:id/enabled](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidenabled)                     | Determine if an element is currently enabled.                                                                                                                         |
| GET             | [/session/:sessionId/element/:id/attribute/:name](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidattribute/:name)     | Get the value of an element’s attribute.                                                                                                                              |
| GET             | [/session/:sessionId/element/:id/equals/:other](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidequals/:other)         | Test if two element IDs refer to the same DOM element.                                                                                                                |
| GET             | [/session/:sessionId/element/:id/displayed](/documentation/legacy/json_wire_protocol/#sessionsessionidelementiddisplayed)                 | Determine if an element is currently displayed.                                                                                                                       |
| GET             | [/session/:sessionId/element/:id/location](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidlocation)                   | Determine an element’s location on the page.                                                                                                                          |
| GET             | [/session/:sessionId/element/:id/location\_in\_view](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidlocation_in_view) | Determine an element’s location on the screen once it has been scrolled into view.                                                                                    |
| GET             | [/session/:sessionId/element/:id/size](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidsize)                           | Determine an element’s size in pixels.                                                                                                                                |
| GET             | [/session/:sessionId/element/:id/css/:propertyName](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidcss/:propertyName) | Query the value of an element’s computed CSS property.                                                                                                                |
| GET             | [/session/:sessionId/orientation](/documentation/legacy/json_wire_protocol/#sessionsessionidorientation)                                  | Get the current browser orientation.                                                                                                                                  |
| POST            | [/session/:sessionId/orientation](/documentation/legacy/json_wire_protocol/#sessionsessionidorientation)                                  | Set the browser orientation.                                                                                                                                          |
| GET             | [/session/:sessionId/alert\_text](/documentation/legacy/json_wire_protocol/#sessionsessionidalert_text)                                   | Gets the text of the currently displayed JavaScript `alert()`, `confirm()`, or `prompt()` dialog.                                                                     |
| POST            | [/session/:sessionId/alert\_text](/documentation/legacy/json_wire_protocol/#sessionsessionidalert_text)                                   | Sends keystrokes to a JavaScript `prompt()` dialog.                                                                                                                   |
| POST            | [/session/:sessionId/accept\_alert](/documentation/legacy/json_wire_protocol/#sessionsessionidaccept_alert)                               | Accepts the currently displayed alert dialog.                                                                                                                         |
| POST            | [/session/:sessionId/dismiss\_alert](/documentation/legacy/json_wire_protocol/#sessionsessioniddismiss_alert)                             | Dismisses the currently displayed alert dialog.                                                                                                                       |
| POST            | [/session/:sessionId/moveto](/documentation/legacy/json_wire_protocol/#sessionsessionidmoveto)                                            | Move the mouse by an offset of the specificed element.                                                                                                                |
| POST            | [/session/:sessionId/click](/documentation/legacy/json_wire_protocol/#sessionsessionidclick)                                              | Click any mouse button (at the coordinates set by the last moveto command).                                                                                           |
| POST            | [/session/:sessionId/buttondown](/documentation/legacy/json_wire_protocol/#sessionsessionidbuttondown)                                    | Click and hold the left mouse button (at the coordinates set by the last moveto command).                                                                             |
| POST            | [/session/:sessionId/buttonup](/documentation/legacy/json_wire_protocol/#sessionsessionidbuttonup)                                        | Releases the mouse button previously held (where the mouse is currently at).                                                                                          |
| POST            | [/session/:sessionId/doubleclick](/documentation/legacy/json_wire_protocol/#sessionsessioniddoubleclick)                                  | Double-clicks at the current mouse coordinates (set by moveto).                                                                                                       |
| POST            | [/session/:sessionId/touch/click](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchclick)                                   | Single tap on the touch enabled device.                                                                                                                               |
| POST            | [/session/:sessionId/touch/down](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchdown)                                     | Finger down on the screen.                                                                                                                                            |
| POST            | [/session/:sessionId/touch/up](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchup)                                         | Finger up on the screen.                                                                                                                                              |
| POST            | [session/:sessionId/touch/move](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchmove)                                      | Finger move on the screen.                                                                                                                                            |
| POST            | [session/:sessionId/touch/scroll](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchscroll)                                  | Scroll on the touch screen using finger based motion events.                                                                                                          |
| POST            | [session/:sessionId/touch/scroll](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchscroll)                                  | Scroll on the touch screen using finger based motion events.                                                                                                          |
| POST            | [session/:sessionId/touch/doubleclick](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchdoubleclick)                        | Double tap on the touch screen using finger motion events.                                                                                                            |
| POST            | [session/:sessionId/touch/longclick](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchlongclick)                            | Long press on the touch screen using finger motion events.                                                                                                            |
| POST            | [session/:sessionId/touch/flick](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchflick)                                    | Flick on the touch screen using finger motion events.                                                                                                                 |
| POST            | [session/:sessionId/touch/flick](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchflick)                                    | Flick on the touch screen using finger motion events.                                                                                                                 |
| GET             | [/session/:sessionId/location](/documentation/legacy/json_wire_protocol/#sessionsessionidlocation)                                        | Get the current geo location.                                                                                                                                         |
| POST            | [/session/:sessionId/location](/documentation/legacy/json_wire_protocol/#sessionsessionidlocation)                                        | Set the current geo location.                                                                                                                                         |
| GET             | [/session/:sessionId/local\_storage](/documentation/legacy/json_wire_protocol/#sessionsessionidlocal_storage)                             | Get all keys of the storage.                                                                                                                                          |
| POST            | [/session/:sessionId/local\_storage](/documentation/legacy/json_wire_protocol/#sessionsessionidlocal_storage)                             | Set the storage item for the given key.                                                                                                                               |
| DELETE          | [/session/:sessionId/local\_storage](/documentation/legacy/json_wire_protocol/#sessionsessionidlocal_storage)                             | Clear the storage.                                                                                                                                                    |
| GET             | [/session/:sessionId/local\_storage/key/:key](/documentation/legacy/json_wire_protocol/#sessionsessionidlocal_storagekeykey)              | Get the storage item for the given key.                                                                                                                               |
| DELETE          | [/session/:sessionId/local\_storage/key/:key](/documentation/legacy/json_wire_protocol/#sessionsessionidlocal_storagekeykey)              | Remove the storage item for the given key.                                                                                                                            |
| GET             | [/session/:sessionId/local\_storage/size](/documentation/legacy/json_wire_protocol/#sessionsessionidlocal_storagesize)                    | Get the number of items in the storage.                                                                                                                               |
| GET             | [/session/:sessionId/session\_storage](/documentation/legacy/json_wire_protocol/#sessionsessionidsession_storage)                         | Get all keys of the storage.                                                                                                                                          |
| POST            | [/session/:sessionId/session\_storage](/documentation/legacy/json_wire_protocol/#sessionsessionidsession_storage)                         | Set the storage item for the given key.                                                                                                                               |
| DELETE          | [/session/:sessionId/session\_storage](/documentation/legacy/json_wire_protocol/#sessionsessionidsession_storage)                         | Clear the storage.                                                                                                                                                    |
| GET             | [/session/:sessionId/session\_storage/key/:key](/documentation/legacy/json_wire_protocol/#sessionsessionidsession_storagekeykey)          | Get the storage item for the given key.                                                                                                                               |
| DELETE          | [/session/:sessionId/session\_storage/key/:key](/documentation/legacy/json_wire_protocol/#sessionsessionidsession_storagekeykey)          | Remove the storage item for the given key.                                                                                                                            |
| GET             | [/session/:sessionId/session\_storage/size](/documentation/legacy/json_wire_protocol/#sessionsessionidsession_storagesize)                | Get the number of items in the storage.                                                                                                                               |
| POST            | [/session/:sessionId/log](/documentation/legacy/json_wire_protocol/#sessionsessionidlog)                                                  | Get the log for a given log type.                                                                                                                                     |
| GET             | [/session/:sessionId/log/types](/documentation/legacy/json_wire_protocol/#sessionsessionidlogtypes)                                       | Get available log types.                                                                                                                                              |
| GET             | [/session/:sessionId/application\_cache/status](/documentation/legacy/json_wire_protocol/#sessionsessionidapplication_cachestatus)        | Get the status of the html5 application cache.                                                                                                                        |

### Command Detail

#### /status

* * #### GET /status

  * * * Query the server's current status. The server should respond with a general "HTTP 200 OK" response if it is alive and accepting commands. The response body should be a JSON object describing the state of the server. All server implementations should return two basic objects describing the server's current platform and when the server was built. All fields are optional; if omitted, the client should assume the value is uknown. Furthermore, server implementations may include additional fields not listed here.

        | **Key**        | **Type** | **Description**                                                                               |
        | -------------- | -------- | --------------------------------------------------------------------------------------------- |
        | build          | object   |                                                                                               |
        | build.version  | string   | A generic release label (i.e. "2.0rc3")                                                       |
        | build.revision | string   | The revision of the local source control client from which the server was built               |
        | build.time     | string   | A timestamp from when the server was built.                                                   |
        | os             | object   |                                                                                               |
        | os.arch        | string   | The current system architecture.                                                              |
        | os.name        | string   | The name of the operating system the server is currently running on: "windows", "linux", etc. |
        | os.version     | string   | The operating system version.                                                                 |

      * * **Returns:**

          `{object}` An object describing the general status of the server.

***

#### /session

* * #### POST /session

  * * * Create a new session. The server should attempt to create a session that most closely matches the desired and required capabilities. Required capabilities have higher priority than desired capabilities and must be set for the session to be created.

      * * **JSON Parameters:**

          * `desiredCapabilities` - `{object}` An object describing the session's [desired capabilities](#Desired_Capabilities.md).
          * `requiredCapabilities` - `{object}` An object describing the session's [required capabilities](#Desired_Capabilities.md) (Optional).

      * * **Returns:**

          `{object}` An object describing the session's [capabilities](#Actual_Capabilities.md).

      * * **Potential Errors:**

          `SessionNotCreatedException` - If a required capability could not be set.

***

#### /sessions

* * #### GET /sessions

  * * * Returns a list of the currently active sessions. Each session will be returned as a list of JSON objects with the following keys:

        | **Key**      | **Type** | **Description**                                                             |
        | ------------ | -------- | --------------------------------------------------------------------------- |
        | id           | string   | The session ID.                                                             |
        | capabilities | object   | An object describing the session's [capabilities](#Actual_Capabilities.md). |

      * * **Returns:**

          `{Array.<Object>}` A list of the currently active sessions.

***

#### /session/:sessionId

* * #### GET /session/:sessionId

  * * * Retrieve the capabilities of the specified session.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{object}` An object describing the session's [capabilities](#Actual_Capabilities.md).

- - #### DELETE /session/:sessionId

  - * * Delete the session.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

***

#### /session/:sessionId/timeouts

* * #### POST /session/:sessionId/timeouts

  * * * Configure the amount of time that a particular type of operation can execute for before they are aborted and a |Timeout| error is returned to the client.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `type` - `{string}` The type of operation to set the timeout for. Valid values are: "script" for script timeouts, "implicit" for modifying the implicit wait timeout and "page load" for setting a page load timeout.
          * `ms` - `{number}` The amount of time, in milliseconds, that time-limited commands are permitted to run.

***

#### /session/:sessionId/timeouts/async\_script

* * #### POST /session/:sessionId/timeouts/async\_script

  * * * Set the amount of time, in milliseconds, that asynchronous scripts executed by `/session/:sessionId/execute_async` are permitted to run before they are aborted and a |Timeout| error is returned to the client.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `ms` - `{number}` The amount of time, in milliseconds, that time-limited commands are permitted to run.

***

#### /session/:sessionId/timeouts/implicit\_wait

* * #### POST /session/:sessionId/timeouts/implicit\_wait

  * * * Set the amount of time the driver should wait when searching for elements. When\
        searching for a single element, the driver should poll the page until an element is found or\
        the timeout expires, whichever occurs first. When searching for multiple elements, the driver\
        should poll the page until at least one element is found or the timeout expires, at which point\
        it should return an empty list.\
        \
        If this command is never sent, the driver should default to an implicit wait of 0ms.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `ms` - `{number}` The amount of time to wait, in milliseconds. This value has a lower bound of 0.

***

#### /session/:sessionId/window\_handle

* * #### GET /session/:sessionId/window\_handle

  * * * Retrieve the current window handle.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{string}` The current window handle.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/window\_handles

* * #### GET /session/:sessionId/window\_handles

  * * * Retrieve the list of all window handles available to the session.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{Array.<string>}` A list of window handles.

***

#### /session/:sessionId/url

* * #### GET /session/:sessionId/url

  * * * Retrieve the URL of the current page.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{string}` The current URL.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

- - #### POST /session/:sessionId/url

  - * * Navigate to a new URL.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `url` - `{string}` The URL to navigate to.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/forward

* * #### POST /session/:sessionId/forward

  * * * Navigate forwards in the browser history, if possible.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/back

* * #### POST /session/:sessionId/back

  * * * Navigate backwards in the browser history, if possible.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/refresh

* * #### POST /session/:sessionId/refresh

  * * * Refresh the current page.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/execute

* * #### POST /session/:sessionId/execute

  * * * Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. The executed script is assumed to be synchronous and the result of evaluating the script is returned to the client.\
        \
        The `script` argument defines the script to execute in the form of a function body. The value returned by that function will be returned to the client. The function will be invoked with the provided `args` array and the values may be accessed via the `arguments` object in the order specified.\
        \
        Arguments may be any JSON-primitive, array, or JSON object. JSON objects that define a [WebElement reference](#WebElement_JSON_Object.md) will be converted to the corresponding DOM element. Likewise, any WebElements in the script result will be returned to the client as [WebElement JSON objects](#WebElement_JSON_Object.md).

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `script` - `{string}` The script to execute.
          * `args` - `{Array.<*>}` The script arguments.

      * * **Returns:**

          `{*}` The script result.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If one of the script arguments is a WebElement that is not attached to the page's DOM.
          * `JavaScriptError` - If the script throws an Error.

***

#### /session/:sessionId/execute\_async

* * #### POST /session/:sessionId/execute\_async

  * * * Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. The executed script is assumed to be asynchronous and must signal that is done by invoking the provided callback, which is always provided as the final argument to the function. The value to this callback will be returned to the client.\
        \
        Asynchronous script commands may not span page loads. If an `unload` event is fired while waiting for a script result, an error should be returned to the client.\
        \
        The `script` argument defines the script to execute in teh form of a function body. The function will be invoked with the provided `args` array and the values may be accessed via the `arguments` object in the order specified. The final argument will always be a callback function that must be invoked to signal that the script has finished.\
        \
        Arguments may be any JSON-primitive, array, or JSON object. JSON objects that define a [WebElement reference](#WebElement_JSON_Object.md) will be converted to the corresponding DOM element. Likewise, any WebElements in the script result will be returned to the client as [WebElement JSON objects](#WebElement_JSON_Object.md).

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `script` - `{string}` The script to execute.
          * `args` - `{Array.<*>}` The script arguments.

      * * **Returns:**

          `{*}` The script result.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If one of the script arguments is a WebElement that is not attached to the page's DOM.
          * `Timeout` - If the script callback is not invoked before the timeout expires. Timeouts are controlled by the `/session/:sessionId/timeout/async_script` command.
          * `JavaScriptError` - If the script throws an Error or if an `unload` event is fired while waiting for the script to finish.

***

#### /session/:sessionId/screenshot

* * #### GET /session/:sessionId/screenshot

  * * * Take a screenshot of the current page.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{string}` The screenshot as a base64 encoded PNG.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/ime/available\_engines

* * #### GET /session/:sessionId/ime/available\_engines

  * * * List all available engines on the machine. To use an engine, it has to be present in this list.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{Array.<string>}` A list of available engines

      * * **Potential Errors:**

          `ImeNotAvailableException` - If the host does not support IME

***

#### /session/:sessionId/ime/active\_engine

* * #### GET /session/:sessionId/ime/active\_engine

  * * * Get the name of the active IME engine. The name string is platform specific.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{string}` The name of the active IME engine.

      * * **Potential Errors:**

          `ImeNotAvailableException` - If the host does not support IME

***

#### /session/:sessionId/ime/activated

* * #### GET /session/:sessionId/ime/activated

  * * * Indicates whether IME input is active at the moment (not if it's available.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{boolean}` true if IME input is available and currently active, false otherwise

      * * **Potential Errors:**

          `ImeNotAvailableException` - If the host does not support IME

***

#### /session/:sessionId/ime/deactivate

* * #### POST /session/:sessionId/ime/deactivate

  * * * De-activates the currently-active IME engine.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `ImeNotAvailableException` - If the host does not support IME

***

#### /session/:sessionId/ime/activate

* * #### POST /session/:sessionId/ime/activate

  * * * Make an engines that is available (appears on the list\
        returned by getAvailableEngines) active. After this call, the engine will\
        be added to the list of engines loaded in the IME daemon and the input sent\
        using sendKeys will be converted by the active engine.\
        Note that this is a platform-independent method of activating IME\
        (the platform-specific way being using keyboard shortcuts

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `engine` - `{string}` Name of the engine to activate.

      * * **Potential Errors:**

          * `ImeActivationFailedException` - If the engine is not available or if the activation fails for other reasons.
          * `ImeNotAvailableException` - If the host does not support IME

***

#### /session/:sessionId/frame

* * #### POST /session/:sessionId/frame

  * * * Change focus to another frame on the page. If the frame `id` is `null`, the server\
        should switch to the page's default content.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `id` - `{string|number|null|WebElement JSON Object}` Identifier for the frame to change focus to.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `NoSuchFrame` - If the frame specified by `id` cannot be found.

***

#### /session/:sessionId/frame/parent

* * #### POST /session/:sessionId/frame/parent

  * * * Change focus to the parent context. If the current context is the top level browsing context, the context remains unchanged.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

***

#### /session/:sessionId/window

* * #### POST /session/:sessionId/window

  * * * Change focus to another window. The window to change focus to may be specified by its\
        server assigned window handle, or by the value of its `name` attribute.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `name` - `{string}` The window to change focus to.

      * * **Potential Errors:**

          `NoSuchWindow` - If the window specified by `name` cannot be found.

- - #### DELETE /session/:sessionId/window

  - * * Close the current window.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window is already closed

***

#### /session/:sessionId/window/:windowHandle/size

* * #### POST /session/:sessionId/window/:windowHandle/size

  * * * Change the size of the specified window. If the :windowHandle URL parameter is "current", the currently active window will be resized.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `width` - `{number}` The new window width.
          * `height` - `{number}` The new window height.

- - #### GET /session/:sessionId/window/:windowHandle/size

  - * * Get the size of the specified window. If the :windowHandle URL parameter is "current", the size of the currently active window will be returned.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{width: number, height: number}` The size of the window.

      * * **Potential Errors:**

          `NoSuchWindow` - If the specified window cannot be found.

***

#### /session/:sessionId/window/:windowHandle/position

* * #### POST /session/:sessionId/window/:windowHandle/position

  * * * Change the position of the specified window. If the :windowHandle URL parameter is "current", the currently active window will be moved.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `x` - `{number}` The X coordinate to position the window at, relative to the upper left corner of the screen.
          * `y` - `{number}` The Y coordinate to position the window at, relative to the upper left corner of the screen.

      * * **Potential Errors:**

          `NoSuchWindow` - If the specified window cannot be found.

- - #### GET /session/:sessionId/window/:windowHandle/position

  - * * Get the position of the specified window. If the :windowHandle URL parameter is "current", the position of the currently active window will be returned.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{x: number, y: number}` The X and Y coordinates for the window, relative to the upper left corner of the screen.

      * * **Potential Errors:**

          `NoSuchWindow` - If the specified window cannot be found.

***

#### /session/:sessionId/window/:windowHandle/maximize

* * #### POST /session/:sessionId/window/:windowHandle/maximize

  * * * Maximize the specified window if not already maximized. If the :windowHandle URL parameter is "current", the currently active window will be maximized.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `NoSuchWindow` - If the specified window cannot be found.

***

#### /session/:sessionId/cookie

* * #### GET /session/:sessionId/cookie

  * * * Retrieve all cookies visible to the current page.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{Array.<object>}` A list of [cookies](#Cookie_JSON_Object.md).

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

- - #### POST /session/:sessionId/cookie

  - * * Set a cookie. If the [cookie](#Cookie_JSON_Object.md) path is not specified, it should be set to `"/"`. Likewise, if the domain is omitted, it should default to the current page's domain.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `cookie` - `{object}` A [JSON object](#Cookie_JSON_Object.md) defining the cookie to add.

* * #### DELETE /session/:sessionId/cookie

  * * * Delete all cookies visible to the current page.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          * `InvalidCookieDomain` - If the cookie's `domain` is not visible from the current page.
          * `NoSuchWindow` - If the currently selected window has been closed.
          * `UnableToSetCookie` - If attempting to set a cookie on a page that does not support cookies (e.g. pages with mime-type `text/plain`).

***

#### /session/:sessionId/cookie/:name

* * #### DELETE /session/:sessionId/cookie/:name

  * * * Delete the cookie with the given name. This command should be a no-op if there is no\
        such cookie visible to the current page.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:name` - The name of the cookie to delete.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/source

* * #### GET /session/:sessionId/source

  * * * Get the current page source.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{string}` The current page source.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/title

* * #### GET /session/:sessionId/title

  * * * Get the current page title.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{string}` The current page title.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/element

* * #### POST /session/:sessionId/element

  * * * Search for an element on the page, starting from the document root. The located element will be returned as a WebElement JSON object. The table below lists the locator strategies that each server should support. Each locator must return the first matching element located in the DOM.

        | **Strategy**      | **Description**                                                                                        |
        | ----------------- | ------------------------------------------------------------------------------------------------------ |
        | class name        | Returns an element whose class name contains the search value; compound class names are not permitted. |
        | css selector      | Returns an element matching a CSS selector.                                                            |
        | id                | Returns an element whose ID attribute matches the search value.                                        |
        | name              | Returns an element whose NAME attribute matches the search value.                                      |
        | link text         | Returns an anchor element whose visible text matches the search value.                                 |
        | partial link text | Returns an anchor element whose visible text partially matches the search value.                       |
        | tag name          | Returns an element whose tag name matches the search value.                                            |
        | xpath             | Returns an element matching an XPath expression.                                                       |

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `using` - `{string}` The locator strategy to use.
          * `value` - `{string}` The The search target.

      * * **Returns:**

          `{ELEMENT:string}` A WebElement JSON object for the located element.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `NoSuchElement` - If the element cannot be found.
          * `XPathLookupError` - If using XPath and the input expression is invalid.

***

#### /session/:sessionId/elements

* * #### POST /session/:sessionId/elements

  * * * Search for multiple elements on the page, starting from the document root. The located elements will be returned as a WebElement JSON objects. The table below lists the locator strategies that each server should support. Elements should be returned in the order located in the DOM.

        | **Strategy**      | **Description**                                                                                          |
        | ----------------- | -------------------------------------------------------------------------------------------------------- |
        | class name        | Returns all elements whose class name contains the search value; compound class names are not permitted. |
        | css selector      | Returns all elements matching a CSS selector.                                                            |
        | id                | Returns all elements whose ID attribute matches the search value.                                        |
        | name              | Returns all elements whose NAME attribute matches the search value.                                      |
        | link text         | Returns all anchor elements whose visible text matches the search value.                                 |
        | partial link text | Returns all anchor elements whose visible text partially matches the search value.                       |
        | tag name          | Returns all elements whose tag name matches the search value.                                            |
        | xpath             | Returns all elements matching an XPath expression.                                                       |

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `using` - `{string}` The locator strategy to use.
          * `value` - `{string}` The The search target.

      * * **Returns:**

          `{Array.<{ELEMENT:string}>}` A list of WebElement JSON objects for the located elements.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `XPathLookupError` - If using XPath and the input expression is invalid.

***

#### /session/:sessionId/element/active

* * #### POST /session/:sessionId/element/active

  * * * Get the element on the page that currently has focus. The element will be returned as a WebElement JSON object.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{ELEMENT:string}` A WebElement JSON object for the active element.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/element/:id

* * #### GET /session/:sessionId/element/:id

  * * * Describe the identified element.\
        \
        **Note:** This command is reserved for future use; its return type is currently undefined.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/element

* * #### POST /session/:sessionId/element/:id/element

  * * * Search for an element on the page, starting from the identified element. The located element will be returned as a WebElement JSON object. The table below lists the locator strategies that each server should support. Each locator must return the first matching element located in the DOM.

        | **Strategy**      | **Description**                                                                                                                                                                                                                                                                                             |
        | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
        | class name        | Returns an element whose class name contains the search value; compound class names are not permitted.                                                                                                                                                                                                      |
        | css selector      | Returns an element matching a CSS selector.                                                                                                                                                                                                                                                                 |
        | id                | Returns an element whose ID attribute matches the search value.                                                                                                                                                                                                                                             |
        | name              | Returns an element whose NAME attribute matches the search value.                                                                                                                                                                                                                                           |
        | link text         | Returns an anchor element whose visible text matches the search value.                                                                                                                                                                                                                                      |
        | partial link text | Returns an anchor element whose visible text partially matches the search value.                                                                                                                                                                                                                            |
        | tag name          | Returns an element whose tag name matches the search value.                                                                                                                                                                                                                                                 |
        | xpath             | Returns an element matching an XPath expression. The provided XPath expression must be applied to the server "as is"; if the expression is not relative to the element root, the server should not modify it. Consequently, an XPath query may return elements not contained in the root element's subtree. |

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **JSON Parameters:**

          * `using` - `{string}` The locator strategy to use.
          * `value` - `{string}` The The search target.

      * * **Returns:**

          `{ELEMENT:string}` A WebElement JSON object for the located element.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.
          * `NoSuchElement` - If the element cannot be found.
          * `XPathLookupError` - If using XPath and the input expression is invalid.

***

#### /session/:sessionId/element/:id/elements

* * #### POST /session/:sessionId/element/:id/elements

  * * * Search for multiple elements on the page, starting from the identified element. The located elements will be returned as a WebElement JSON objects. The table below lists the locator strategies that each server should support. Elements should be returned in the order located in the DOM.

        | **Strategy**      | **Description**                                                                                                                                                                                                                                                                                               |
        | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
        | class name        | Returns all elements whose class name contains the search value; compound class names are not permitted.                                                                                                                                                                                                      |
        | css selector      | Returns all elements matching a CSS selector.                                                                                                                                                                                                                                                                 |
        | id                | Returns all elements whose ID attribute matches the search value.                                                                                                                                                                                                                                             |
        | name              | Returns all elements whose NAME attribute matches the search value.                                                                                                                                                                                                                                           |
        | link text         | Returns all anchor elements whose visible text matches the search value.                                                                                                                                                                                                                                      |
        | partial link text | Returns all anchor elements whose visible text partially matches the search value.                                                                                                                                                                                                                            |
        | tag name          | Returns all elements whose tag name matches the search value.                                                                                                                                                                                                                                                 |
        | xpath             | Returns all elements matching an XPath expression. The provided XPath expression must be applied to the server "as is"; if the expression is not relative to the element root, the server should not modify it. Consequently, an XPath query may return elements not contained in the root element's subtree. |

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **JSON Parameters:**

          * `using` - `{string}` The locator strategy to use.
          * `value` - `{string}` The The search target.

      * * **Returns:**

          `{Array.<{ELEMENT:string}>}` A list of WebElement JSON objects for the located elements.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.
          * `XPathLookupError` - If using XPath and the input expression is invalid.

***

#### /session/:sessionId/element/:id/click

* * #### POST /session/:sessionId/element/:id/click

  * * * Click on an element.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.
          * `ElementNotVisible` - If the referenced element is not visible on the page (either is hidden by CSS, has 0-width, or has 0-height)

***

#### /session/:sessionId/element/:id/submit

* * #### POST /session/:sessionId/element/:id/submit

  * * * Submit a `FORM` element. The submit command may also be applied to any element that is a descendant of a `FORM` element.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/text

* * #### GET /session/:sessionId/element/:id/text

  * * * Returns the visible text for the element.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/value

* * #### POST /session/:sessionId/element/:id/value

  * * * Send a sequence of key strokes to an element.\
        \
        Any UTF-8 character may be specified, however, if the server does not support native key events, it should simulate key strokes for a standard US keyboard layout. The Unicode [Private Use Area](http://unicode.org/faq/casemap_charprop.html#8) code points, 0xE000-0xF8FF, are used to represent pressable, non-text keys (see table below).

        |                                                                                                                                                                                                                                        |                                                                                                                                                                                                                                                             |                                                                                                                                                                                                             |                                                                                                                      |                                                                                                                                                                                                        |
        | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
        | Key	CodeNULL	U+E000&#xA;Cancel	U+E001&#xA;Help	U+E002&#xA;Back space	U+E003&#xA;Tab	U+E004&#xA;Clear	U+E005&#xA;Return1	U+E006&#xA;Enter1	U+E007&#xA;Shift	U+E008&#xA;Control	U+E009&#xA;Alt	U+E00A&#xA;Pause	U+E00B&#xA;Escape	U+E00C | Key	CodeSpace	U+E00D&#xA;Pageup	U+E00E&#xA;Pagedown	U+E00F&#xA;End	U+E010&#xA;Home	U+E011&#xA;Left arrow	U+E012&#xA;Up arrow	U+E013&#xA;Right arrow	U+E014&#xA;Down arrow	U+E015&#xA;Insert	U+E016&#xA;Delete	U+E017&#xA;Semicolon	U+E018&#xA;Equals	U+E019 | Key	CodeNumpad 0	U+E01A&#xA;Numpad 1	U+E01B&#xA;Numpad 2	U+E01C&#xA;Numpad 3	U+E01D&#xA;Numpad 4	U+E01E&#xA;Numpad 5	U+E01F&#xA;Numpad 6	U+E020&#xA;Numpad 7	U+E021&#xA;Numpad 8	U+E022&#xA;Numpad 9	U+E023 | Key	CodeMultiply	U+E024&#xA;Add	U+E025&#xA;Separator	U+E026&#xA;Subtract	U+E027&#xA;Decimal	U+E028&#xA;Divide	U+E029 | Key	CodeF1	U+E031&#xA;F2	U+E032&#xA;F3	U+E033&#xA;F4	U+E034&#xA;F5	U+E035&#xA;F6	U+E036&#xA;F7	U+E037&#xA;F8	U+E038&#xA;F9	U+E039&#xA;F10	U+E03A&#xA;F11	U+E03B&#xA;F12	U+E03C&#xA;Command/Meta	U+E03D |
        | 1 The return key is *not the same* as the [enter key](http://en.wikipedia.org/wiki/Enter_key).                                                                                                                                         |                                                                                                                                                                                                                                                             |                                                                                                                                                                                                             |                                                                                                                      |                                                                                                                                                                                                        |

        The server must process the key sequence as follows:

        * Each key that appears on the keyboard without requiring modifiers are sent as a keydown followed by a key up.
        * If the server does not support native events and must simulate key strokes with JavaScript, it must generate keydown, keypress, and keyup events, in that order. The keypress event should only be fired when the corresponding key is for a printable character.
        * If a key requires a modifier key (e.g. "!" on a standard US keyboard), the sequence is: `modifier` down, `key` down, `key` up, `modifier` up, where `key` is the ideal unmodified key value (using the previous example, a "1").
        * Modifier keys (Ctrl, Shift, Alt, and Command/Meta) are assumed to be "sticky"; each modifier should be held down (e.g. only a keydown event) until either the modifier is encountered again in the sequence, or the `NULL` (U+E000) key is encountered.
        * Each key sequence is terminated with an implicit `NULL` key. Subsequently, all depressed modifier keys must be released (with corresponding keyup events) at the end of the sequence.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **JSON Parameters:**

          `value` - `{Array.<string>}` The sequence of keys to type. An array must be provided. The server should flatten the array items to a single string to be typed.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.
          * `ElementNotVisible` - If the referenced element is not visible on the page (either is hidden by CSS, has 0-width, or has 0-height)

***

#### /session/:sessionId/keys

* * #### POST /session/:sessionId/keys

  * * * Send a sequence of key strokes to the active element. This command is similar to the [send keys](JsonWireProtocol#/session/:sessionId/element/:id/value.md) command in every aspect except the implicit termination: The modifiers are **not** released at the end of the call. Rather, the state of the modifier keys is kept between calls, so mouse interactions can be performed while modifier keys are depressed.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `value` - `{Array.<string>}` The keys sequence to be sent. The sequence is defined in the[send keys](JsonWireProtocol#/session/:sessionId/element/:id/value.md) command.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/element/:id/name

* * #### GET /session/:sessionId/element/:id/name

  * * * Query for an element's tag name.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Returns:**

          `{string}` The element's tag name, as a lowercase string.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/clear

* * #### POST /session/:sessionId/element/:id/clear

  * * * Clear a `TEXTAREA` or `text INPUT` element's value.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.
          * `ElementNotVisible` - If the referenced element is not visible on the page (either is hidden by CSS, has 0-width, or has 0-height)
          * `InvalidElementState` - If the referenced element is disabled.

***

#### /session/:sessionId/element/:id/selected

* * #### GET /session/:sessionId/element/:id/selected

  * * * Determine if an `OPTION` element, or an `INPUT` element of type `checkbox` or `radiobutton` is currently selected.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Returns:**

          `{boolean}` Whether the element is selected.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/enabled

* * #### GET /session/:sessionId/element/:id/enabled

  * * * Determine if an element is currently enabled.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Returns:**

          `{boolean}` Whether the element is enabled.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/attribute/:name

* * #### GET /session/:sessionId/element/:id/attribute/:name

  * * * Get the value of an element's attribute.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Returns:**

          `{string|null}` The value of the attribute, or null if it is not set on the element.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/equals/:other

* * #### GET /session/:sessionId/element/:id/equals/:other

  * * * Test if two element IDs refer to the same DOM element.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.
          * `:other` - ID of the element to compare against.

      * * **Returns:**

          `{boolean}` Whether the two IDs refer to the same element.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If either the element refered to by `:id` or `:other` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/displayed

* * #### GET /session/:sessionId/element/:id/displayed

  * * * Determine if an element is currently displayed.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Returns:**

          `{boolean}` Whether the element is displayed.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/location

* * #### GET /session/:sessionId/element/:id/location

  * * * Determine an element's location on the page. The point `(0, 0)` refers to the upper-left corner of the page. The element's coordinates are returned as a JSON object with `x` and `y` properties.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Returns:**

          `{x:number, y:number}` The X and Y coordinates for the element on the page.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/location\_in\_view

* * #### GET /session/:sessionId/element/:id/location\_in\_view

  * * * Determine an element's location on the screen once it has been scrolled into view.\
        \
        **Note:** This is considered an internal command and should **only** be used to determine an element's\
        location for correctly generating native events.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Returns:**

          `{x:number, y:number}` The X and Y coordinates for the element.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/size

* * #### GET /session/:sessionId/element/:id/size

  * * * Determine an element's size in pixels. The size will be returned as a JSON object with `width` and `height` properties.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Returns:**

          `{width:number, height:number}` The width and height of the element, in pixels.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/css/:propertyName

* * #### GET /session/:sessionId/element/:id/css/:propertyName

  * * * Query the value of an element's computed CSS property. The CSS property to query should be specified using the CSS property name, **not** the JavaScript property name (e.g. `background-color` instead of `backgroundColor`).

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Returns:**

          `{string}` The value of the specified CSS property.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/orientation

* * #### GET /session/:sessionId/orientation

  * * * Get the current browser orientation. The server should return a valid orientation value as defined in [ScreenOrientation](http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/ScreenOrientation.html): `{LANDSCAPE|PORTRAIT}`.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{string}` The current browser orientation corresponding to a value defined in [ScreenOrientation](http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/ScreenOrientation.html): `{LANDSCAPE|PORTRAIT}`.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

- - #### POST /session/:sessionId/orientation

  - * * Set the browser orientation. The orientation should be specified as defined in [ScreenOrientation](http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/ScreenOrientation.html): `{LANDSCAPE|PORTRAIT}`.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `orientation` - `{string}` The new browser orientation as defined in [ScreenOrientation](http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/ScreenOrientation.html): `{LANDSCAPE|PORTRAIT}`.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/alert\_text

* * #### GET /session/:sessionId/alert\_text

  * * * Gets the text of the currently displayed JavaScript `alert()`, `confirm()`, or `prompt()` dialog.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{string}` The text of the currently displayed alert.

      * * **Potential Errors:**

          `NoAlertPresent` - If there is no alert displayed.

- - #### POST /session/:sessionId/alert\_text

  - * * Sends keystrokes to a JavaScript `prompt()` dialog.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `text` - `{string}` Keystrokes to send to the `prompt()` dialog.

      * * **Potential Errors:**

          `NoAlertPresent` - If there is no alert displayed.

***

#### /session/:sessionId/accept\_alert

* * #### POST /session/:sessionId/accept\_alert

  * * * Accepts the currently displayed alert dialog. Usually, this is equivalent to clicking on the 'OK' button in the dialog.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `NoAlertPresent` - If there is no alert displayed.

***

#### /session/:sessionId/dismiss\_alert

* * #### POST /session/:sessionId/dismiss\_alert

  * * * Dismisses the currently displayed alert dialog. For `confirm()` and `prompt()` dialogs, this is equivalent to clicking the 'Cancel' button. For `alert()` dialogs, this is equivalent to clicking the 'OK' button.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `NoAlertPresent` - If there is no alert displayed.

***

#### /session/:sessionId/moveto

* * #### POST /session/:sessionId/moveto

  * * * Move the mouse by an offset of the specificed element. If no element is specified, the move is relative to the current mouse cursor. If an element is provided but no offset, the mouse will be moved to the center of the element. If the element is not visible, it will be scrolled into view.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `element` - `{string}` Opaque ID assigned to the element to move to, as described in the WebElement JSON Object. If not specified or is null, the offset is relative to current position of the mouse.
          * `xoffset` - `{number}` X offset to move to, relative to the top-left corner of the element. If not specified, the mouse will move to the middle of the element.
          * `yoffset` - `{number}` Y offset to move to, relative to the top-left corner of the element. If not specified, the mouse will move to the middle of the element.

***

#### /session/:sessionId/click

* * #### POST /session/:sessionId/click

  * * * Click any mouse button (at the coordinates set by the last moveto command). Note that calling this command after calling buttondown and before calling button up (or any out-of-order interactions sequence) will yield undefined behaviour).

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `button` - `{number}` Which button, enum: `{LEFT = 0, MIDDLE = 1 , RIGHT = 2}`. Defaults to the left mouse button if not specified.

***

#### /session/:sessionId/buttondown

* * #### POST /session/:sessionId/buttondown

  * * * Click and hold the left mouse button (at the coordinates set by the last moveto command). Note that the next mouse-related command that should follow is buttonup . Any other mouse command (such as click or another call to buttondown) will yield undefined behaviour.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `button` - `{number}` Which button, enum: `{LEFT = 0, MIDDLE = 1 , RIGHT = 2}`. Defaults to the left mouse button if not specified.

***

#### /session/:sessionId/buttonup

* * #### POST /session/:sessionId/buttonup

  * * * Releases the mouse button previously held (where the mouse is currently at). Must be called once for every buttondown command issued. See the note in click and buttondown about implications of out-of-order commands.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `button` - `{number}` Which button, enum: `{LEFT = 0, MIDDLE = 1 , RIGHT = 2}`. Defaults to the left mouse button if not specified.

***

#### /session/:sessionId/doubleclick

* * #### POST /session/:sessionId/doubleclick

  * * * Double-clicks at the current mouse coordinates (set by moveto).

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

***

#### /session/:sessionId/touch/click

* * #### POST /session/:sessionId/touch/click

  * * * Single tap on the touch enabled device.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `element` - `{string}` ID of the element to single tap on.

***

#### /session/:sessionId/touch/down

* * #### POST /session/:sessionId/touch/down

  * * * Finger down on the screen.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `x` - `{number}` X coordinate on the screen.
          * `y` - `{number}` Y coordinate on the screen.

***

#### /session/:sessionId/touch/up

* * #### POST /session/:sessionId/touch/up

  * * * Finger up on the screen.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `x` - `{number}` X coordinate on the screen.
          * `y` - `{number}` Y coordinate on the screen.

***

#### session/:sessionId/touch/move

* * #### POST session/:sessionId/touch/move

  * * * Finger move on the screen.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `x` - `{number}` X coordinate on the screen.
          * `y` - `{number}` Y coordinate on the screen.

***

#### session/:sessionId/touch/scroll

* * #### POST session/:sessionId/touch/scroll

  * * * Scroll on the touch screen using finger based motion events. Use this command to start scrolling at a particular screen location.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `element` - `{string}` ID of the element where the scroll starts.
          * `xoffset` - `{number}` The x offset in pixels to scroll by.
          * `yoffset` - `{number}` The y offset in pixels to scroll by.

***

#### session/:sessionId/touch/scroll

* * #### POST session/:sessionId/touch/scroll

  * * * Scroll on the touch screen using finger based motion events. Use this command if you don't care where the scroll starts on the screen.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `xoffset` - `{number}` The x offset in pixels to scrollby.
          * `yoffset` - `{number}` The y offset in pixels to scrollby.

***

#### session/:sessionId/touch/doubleclick

* * #### POST session/:sessionId/touch/doubleclick

  * * * Double tap on the touch screen using finger motion events.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `element` - `{string}` ID of the element to double tap on.

***

#### session/:sessionId/touch/longclick

* * #### POST session/:sessionId/touch/longclick

  * * * Long press on the touch screen using finger motion events.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `element` - `{string}` ID of the element to long press on.

***

#### session/:sessionId/touch/flick

* * #### POST session/:sessionId/touch/flick

  * * * Flick on the touch screen using finger motion events. This flickcommand starts at a particulat screen location.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `element` - `{string}` ID of the element where the flick starts.
          * `xoffset` - `{number}` The x offset in pixels to flick by.
          * `yoffset` - `{number}` The y offset in pixels to flick by.
          * `speed` - `{number}` The speed in pixels per seconds.

***

#### session/:sessionId/touch/flick

* * #### POST session/:sessionId/touch/flick

  * * * Flick on the touch screen using finger motion events. Use this flick command if you don't care where the flick starts on the screen.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `xspeed` - `{number}` The x speed in pixels per second.
          * `yspeed` - `{number}` The y speed in pixels per second.

***

#### /session/:sessionId/location

* * #### GET /session/:sessionId/location

  * * * Get the current geo location.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{latitude: number, longitude: number, altitude: number}` The current geo location.

- - #### POST /session/:sessionId/location

  - * * Set the current geo location.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `location` - `{latitude: number, longitude: number, altitude: number}` The new location.

***

#### /session/:sessionId/local\_storage

* * #### GET /session/:sessionId/local\_storage

  * * * Get all keys of the storage.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{Array.<string>}` The list of keys.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

- - #### POST /session/:sessionId/local\_storage

  - * * Set the storage item for the given key.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `key` - `{string}` The key to set.
          * `value` - `{string}` The value to set.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

* * #### DELETE /session/:sessionId/local\_storage

  * * * Clear the storage.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/local\_storage/key/:key

* * #### GET /session/:sessionId/local\_storage/key/:key

  * * * Get the storage item for the given key.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:key` - The key to get.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

- - #### DELETE /session/:sessionId/local\_storage/key/:key

  - * * Remove the storage item for the given key.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:key` - The key to remove.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/local\_storage/size

* * #### GET /session/:sessionId/local\_storage/size

  * * * Get the number of items in the storage.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{number}` The number of items in the storage.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/session\_storage

* * #### GET /session/:sessionId/session\_storage

  * * * Get all keys of the storage.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{Array.<string>}` The list of keys.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

- - #### POST /session/:sessionId/session\_storage

  - * * Set the storage item for the given key.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `key` - `{string}` The key to set.
          * `value` - `{string}` The value to set.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

* * #### DELETE /session/:sessionId/session\_storage

  * * * Clear the storage.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/session\_storage/key/:key

* * #### GET /session/:sessionId/session\_storage/key/:key

  * * * Get the storage item for the given key.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:key` - The key to get.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

- - #### DELETE /session/:sessionId/session\_storage/key/:key

  - * * Remove the storage item for the given key.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:key` - The key to remove.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/session\_storage/size

* * #### GET /session/:sessionId/session\_storage/size

  * * * Get the number of items in the storage.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{number}` The number of items in the storage.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/log

* * #### POST /session/:sessionId/log

  * * * Get the log for a given log type. Log buffer is reset after each request.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `type` - `{string}` The [log type](#Log_Type.md). This must be provided.

      * * **Returns:**

          `{Array.<object>}` The list of [log entries](#Log_Entry_JSON_Object.md).

***

#### /session/:sessionId/log/types

* * #### GET /session/:sessionId/log/types

  * * * Get available log types.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{Array.<string>}` The list of available [log types](#Log_Type.md).

***

#### /session/:sessionId/application\_cache/status

* * #### GET /session/:sessionId/application\_cache/status

  * * * Get the status of the html5 application cache.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{number}` Status code for application cache: {UNCACHED = 0, IDLE = 1, CHECKING = 2, DOWNLOADING = 3, UPDATE\_READY = 4, OBSOLETE = 5}

# 6 - Legacy Selenium Desired Capabilities

These capabilities worked with the legacy JSON Wire Protocol

This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities)\
See [JSON Wire Protocol](https://www.selenium.dev/documentation/legacy/json_wire_protocol/#capabilities-json-object) for common capabilities.

## Remote Driver Specific

| **Key**                          | **Type** | **Description**                                                                                                                    |
| -------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| webdriver.remote.sessionid       | string   | WebDriver session ID for the session. Readonly and only returned if the server implements a server-side webdriver-backed selenium. |
| webdriver.remote.quietExceptions | boolean  | Disable automatic screenshot capture on exceptions. This is False by default.                                                      |

## Grid Specific

| **Key**          | **Type** | **Description**                                              |
| ---------------- | -------- | ------------------------------------------------------------ |
| path             | string   | Path to route request to, or maybe listen on.                |
| seleniumProtocol | string   | Which protocol to use. Accepted values: WebDriver, Selenium. |
| maxInstances     | integer  | Maximum number of instances to allow to connect to grid      |
| environment      | string   | Possible duplicate of browserName? See RegistrationRequest   |

## Selenium RC Specific

| Key                      | Type              | Description                                                                                                                   |
| ------------------------ | ----------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| proxy\_pac               | boolean           | Legacy proxy mechanism. Do not use.                                                                                           |
| commandLineFlags         | string            | Flags to pass to browser command line.                                                                                        |
| executablePath           | string            | Path to browser executable.                                                                                                   |
| timeoutInSeconds         | long integer      | Timeout to wait for the browser to launch, in seconds.                                                                        |
| onlyProxySeleniumTraffic | boolean           | Whether to only proxy selenium traffic. See browserlaunchers.Proxies                                                          |
| avoidProxy               | boolean           | ??? See browserlaunchers.Proxies                                                                                              |
| proxyEverything          | boolean           | ??? See browserlaunchers.Proxies                                                                                              |
| proxyRequired            | boolean           | ??? See browserlaunchers.Proxies                                                                                              |
| browserSideLog           | boolean           | ??? See AbstractBrowserLauncher.                                                                                              |
| optionsSet               | boolean           | ??? See BrowserOptions.                                                                                                       |
| singleWindow             | boolean           | Whether to enable single window mode.                                                                                         |
| dontInjectRegex          | javascript RegExp | Regular expression that proxy injection mode can use to know when to bypss injection. Ignored if not in proxy injection mode. |
| userJSInjection          | boolean           | ??? Whether to inject user JS. Ignored if not in proxy injection mode.                                                        |
| userExtensions           | string            | Path to a JavaScript file that will be loaded into selenium.                                                                  |

## Selenese-Backed-WebDriver specific

| Key                 | Type   | Description                                           |
| ------------------- | ------ | ----------------------------------------------------- |
| selenium.server.url | string | URL of Selenium server to use, to back this WebDriver |

## Firefox specific

| Key                     | Type    | Description                            |
| ----------------------- | ------- | -------------------------------------- |
| captureNetworkTraffic   | boolean | Whether to capture network traffic.    |
| addCustomRequestHeaders | boolean | Whether to add custom request headers. |
| trustAllSSLCertificates | boolean | Whether to trust all SSL certificates. |
| changeMaxConnections    | boolean | ??? See FirefoxChromeLauncher.         |
| firefoxProfileTemplate  | string  | ??? See FirefoxChromeLauncher.         |
| profile                 | string  | ??? See FirefoxChromeLauncher          |

### FirefoxProfile settings

Preferences accepted by the FirefoxProfile with special meaning, in the WebDriver API:

| **Key**                              | **Type** | **Description**                                                                                                                                                                                       |
| ------------------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| webdriver\_accept\_untrusted\_certs  | boolean  | Whether to trust all SSL certificates. TODO: Maybe in some way different to the acceptSslCerts or trustAllSSLCertificates capabilities.                                                               |
| webdriver\_assume\_untrusted\_issuer | boolean  | Whether to trust all SSL certificate issuers. TODO: Maybe in some way different to the acceptSslCerts or trustAllSSLCertificates capabilities.                                                        |
| webdriver.log.driver                 | string   | Level at which to log FirefoxDriver logging statements to a temporary file, so that they can be retrieved by a getLogs command. Available options; DEBUG, INFO, WARNING, ERROR, OFF. Defaults to OFF. |
| webdriver.log.file                   | string   | Path to file to which to copy firefoxdriver logging output. Defaults to no file (like /dev/null).                                                                                                     |
| webdriver.load.strategy              | string   | Experimental API. Defines different strategies for how long to wait until a page is loaded. Values: unstable, conservative. Defaults to conservative.                                                 |
| webdriver\_firefox\_port             | integer  | Port to listen on for WebDriver commands. Defaults to 7055.                                                                                                                                           |

## IE specific

| Key                 | Type    | Description                                                                                                                                                  |
| ------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| killProcessesByName | boolean | Whether to try to kill processes by name, instead (or addition) to killing processes we happen to have handles to.                                           |
| honorSystemProxy    | boolean | Whether to honor the system proxy.                                                                                                                           |
| ensureCleanSession  | boolean | Whether to make sure the session has no cookies or temporary internet files on Windows. I believe this is passed to the IEDriver as well, but ignored by it. |

## Safari specific

| Key                | Type    | Description                                                                                                                              |
| ------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| honorSystemProxy   | boolean | Whether to honour the system proxy.                                                                                                      |
| ensureCleanSession | boolean | Whether to make sure the session has no cookies, cache entries. And that any registry and proxy settings are restored after the session. |

# 7 - Legacy developer documentation

Information of interest to developers of Selenium

# 7.1 - Crazy Fun Build Tool

The original Selenium Build Tool that grew from nothing to be extremely unwieldy, making it both crazy and “fun” to work with.

This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/Crazy-Fun-Build)

WebDriver is a large project: if we tried to push everything into a single monolithic build file it eventually becomes unmanageable. We know this. We’ve tried it. So we broke the single Rakefile into a series of `build.desc` files. Each of these describe a part of the build.

Let’s take a look at a build.desc file. This is part of the [main test build.desc](https://github.com/SeleniumHQ/selenium/blob/master/java/client/test/org/openqa/selenium/build.desc):

```
java_test(name = "single",
  srcs = [
    "SingleTestSuite.java",
  ],
  deps = [
    ":tests",
    "//java/server/src/org/openqa/selenium/server",
    "//java/client/test/org/openqa/selenium/v1:selenium-backed-webdriver-test",
    "//java/client/test/org/openqa/selenium/firefox:test",
  ]  ])
```

```
./go -T
```

Being a brief description of the available targets that you can use.

### Common Attributes

The following attributes are required for all build targets:

| **Attribute Name** | **Type** | **Meaning**                                                                 |
| ------------------ | -------- | --------------------------------------------------------------------------- |
| name               | string   | Used to derive the rake target and (often) the name of the generated binary |

The following attributes are commonly used:

| **Attribute Name** | **Type** | **Meaning**                                |
| ------------------ | -------- | ------------------------------------------ |
| srcs               | array    | The raw source to be build for this target |
| deps               | array    | Prerequisites of this target               |

### java\_library

* **Output:** JAR file named after the “name” attribute if the “srcs” attribute is set.
* **Implicit Targets:** run (if “main” attribute specifiec), project, project-srcs, uber, zip
* **Required Attributes:** “name” and at least one of “srcs” or “deps”.

| **Attribute Name** | **Type** | **Meaning**                                                                         |
| ------------------ | -------- | ----------------------------------------------------------------------------------- |
| deps               | array    | As above                                                                            |
| srcs               | array    | As above                                                                            |
| resources          | array    | Any resources that should be copied into the jar file.                              |
| main               | string   | The full classname of the main class of the jar (used for creating executable jars) |

### java\_test

* **Output:** JAR file named after the “name” attribute if the “srcs” attribute is set.
* **Implicit Targets:** run, project, project-srcs, uber, zip
* **Required Attributes:** “name” and at least one of “srcs” or “deps”.

| **Attribute Name** | **Type** | **Meaning**                                                      |
| ------------------ | -------- | ---------------------------------------------------------------- |
| deps               | array    | As above.                                                        |
| srcs               | array    | As above.                                                        |
| resources          | array    | Any resources that should be copied into the jar file.           |
| main               | string   | The alternative class to use for running these tests.            |
| args               | string   | The argument line to pass to the main class                      |
| sysproperties      | array    | An array of maps containing System properties that should be set |

### js\_deps

* **Output:** Marker file to indicate task is up to date.
* **Implicit Targets:** None
* **Required Attributes:** “name” and “srcs”

| **Attribute Name** | **Type** | **Meaning** |
| ------------------ | -------- | ----------- |
| name               | string   | As above    |
| srcs               | array    | As above    |
| deps               | array    | As above    |

### js\_binary

* **Output:** A monolithic JS file containing all dependencies and sources compiled using the closure compiler without optimizations.
* **Implicit Targets:** None
* **Required Attributes:** At least one of srcs or deps.

| **Attribute Name** | **Type** | **Meaning** |
| ------------------ | -------- | ----------- |
| name               | string   | As above    |
| srcs               | array    | As above    |
| deps               | array    | As above    |

### js\_fragment

* **Output:** Source of an anonymous function representing the exported function, compiled by the closure compiler with all optimizations turned on.
* **Implicit Targets:** None
* **Required Attributes:** name, module, function, deps

| **Attribute Name** | **Type** | **Meaning**                                    |
| ------------------ | -------- | ---------------------------------------------- |
| name               | string   | As above                                       |
| module             | string   | The name of the module containing the function |
| function           | string   | The full name of the function to export        |
| deps               | array    | As above                                       |

### js\_fragment\_header

* **Output:** A C header file with all js\_fragment dependencies declared as constants.
* **Implicit Targets:** None
* **Required Attributes:** name, deps

| **Attribute Name** | **Type** | **Meaning** |
| ------------------ | -------- | ----------- |
| name               | string   | As above    |
| srcs               | array    | As above    |
| deps               | array    | As above    |

### js\_test

* **Output:**
* **Implicit Targets:** `_`BROWSER:run, run
* **Required Attributes:** None.

| **Attribute Name** | **Type** | **Meaning**                                                                                                                                                                                                 |
| ------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| deps               | array    | As above.                                                                                                                                                                                                   |
| srcs               | array    | As above.                                                                                                                                                                                                   |
| path               | string   | The path at which to expect the test files to be hosted on the test server.                                                                                                                                 |
| browsers           | array    | List of browsers, from rake\_tasks/browsers.rb, to run the tests in. Will only attempt to run tests in those browsers which are available on the system. If absent, defaults to all browsers on the system. |

Assuming browsers = \[‘ff’, ‘chrome’], for target //foo, the implicit targets: //foo\_ff:run and //foo\_chrome:run will be generated, which run the tests in each of those browsers, and the implicit target //foo:run will be generated, which runs the tests in both ff and chrome.

### py\_test

* **Output:** Creates the directory structure required to run the listed python tests.
* **Implicit Targets:** `_`BROWSER:run, run
* **Required Attributes:** name.

| **Attribute Name**       | **Type** | **Meaning**                                                                                                                                                                                                     |
| ------------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| deps                     | array    | Other py\_test rule(s), whose tests should also be run.                                                                                                                                                         |
| common\_tests            | array    | Test file(s) to be run in all browsers. These tests will be passed through a template, with browser-specific substitutions, so that they are laid out properly for each browser in the python output file tree. |
| BROWSER\_specific\_tests | array    | Test file(s) to be run only in browser BROWSER.                                                                                                                                                                 |
| resources                | array    | Resources which should be copied to the python directory structure.                                                                                                                                             |
| browsers                 | array    | List of browsers, from rake\_tasks/browsers.rb, to run the tests in. Will only attempt to run tests in those browsers which are available on the system. If absent, defaults to all browsers on the system.     |

Note: Every py\_test invocation is performed in a new virtualenv.

### rake\_task

* **Output:** A crazy fun build rule that can be referred to “blow the escape” hatch and use ordinary rake targets.
* **Implicit Targets:** None
* **Required Attributes:** name, task\_name, out.

| **Attribute Name** | **Type** | **Meaning**                                          |
| ------------------ | -------- | ---------------------------------------------------- |
| name               | string   | As above                                             |
| task\_name         | string   | The ordinary rake target to call                     |
| out                | string   | The file that is generated, relative to the Rakefile |

### gcc\_library

* **Output:** Shared library file named after the “name” attribute if the “srcs” attribute is set.
* **Implicit Targets:** None.
* **Required Attributes:** “name” and “srcs”.

| **Attribute Name** | **Type** | **Meaning**                                          |
| ------------------ | -------- | ---------------------------------------------------- |
| srcs               | array    | As above                                             |
| arch               | string   | “amd64” for 64-bit builds, “i386” for 32-bit builds. |
| args               | string   | Arguments to the compiler (-I flags, for example).   |
| link\_args         | string   | Arguments to the linker (-l flags, for example)      |

Note: When building a new library for the first time, the build will succeed but copying to pre-built will fail with a similar message:

```
cp build/cpp/amd64/libimetesthandler64.so 
go aborted!
can't convert nil into String
```

Solution: Copy the just-built library to the appropriate prebuilt folder (cpp/prebuilt/arch/).

# 7.2 - Buck Build Tool

Buck is a build tool from Facebook that we were working with to replace Crazy fun. We have since replaced it with [Bazel](https://bazel.build/).

This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/Buck)\
You can read the documentation for the legacy [Crazy Fun Build tool](https://www.selenium.dev/documentation/legacy/developers/crazy_fun_build/).

## Building Selenium with Buck

The easiest thing to do is to just run “./go”. The build process will download the right version of Buck for you so long as there’s no `.nobuckcheck` file in the root of the project. The download ends up in `buck-out/crazy-fun/HASH/buck.pex` where `HASH` is the value of the current buck version (given in the `.buckversion` file in the root of the project.

If you’d like to build and run our fork of Buck, then:

```
git clone https://github.com/SeleniumHQ/buck.git
cd buck && ant
export PATH=`pwd`/bin:$PATH
cd ~/src/selenium 
buck build chrome firefox htmlunit remote leg-rc
buck test --all
```

# 7.3 - Adding new drivers to Selenium 2 code

# 7.4 - Selenium's Continuous Integration Implementation

# 7.5 - Google Summer of Code 2011

# 7.6 - Developer Tips

Details on how to execute Selenium Test Suite with Crazy Fun.

This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/Developer-Tips)

## Running an Individual Test

When developing WebDriver, it is common to want to run a single test rather than the entire test suite for a particular driver.

You can run all the tests in a given test class this way:

```
./go test_firefox onlyRun=CombinedInputActionsTest
```

You can also run a single test directly from the command line by typing:

```
./go test_firefox method=foo
```

## Not Halting On Errors Or Failures

The test suite will halt on errors and failures by default. You can disable this behaviour by setting the `haltonerror` or `haltonfailure` environmental variables to `0`.

## Reviewing the Logs For the Tests

When you run the tests, the test results don’t appear on the screen. They are written to the \`./build/test\_logs’ folder. A pair of files are written. Their names are relatively consistent and include the details of the tests which were run. The pair comprise a txt file and an xml file. The xml file contains more information about the runtime environment such as the path, Ant version, etc. These files are overwritten the next time the same test target is executed so you may want to archive results if they’re important to you.

## Using Rake

Rake is very similar to using other build tools such as “make” or “ant”. You can specify a “target” to run by adding it as a parameter, and you can add more than one target at a time. Note that since WebDriver does not rely on ruby being installed and uses JRuby, rake should **not** be involved directly - use the *go* script instead. For example, in order to clean the build and then build and run the HtmlUnitDriver tests:

```
./go clean test_htmlunit
```

The default target that’s used will compile the code and run all the tests. More interesting targets are:

| **Target**     | **Description**                                                                                                                                                     |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| clean          | Delete the contents of the build directory, removing all compiled artifacts                                                                                         |
| test           | Compile the dependencies of and run all the tests for the HtmlUnitDriver, FirefoxDriver, and InternetExplorerDriver as well as the support library’s tests          |
| firefox        | Compile the FirefoxDriver                                                                                                                                           |
| htmlunit       | Compile the HtmlUnitDriver                                                                                                                                          |
| ie             | Compile the InternetExplorerDriver. This won’t compile the C++ on a non-Windows system, but will always compile the Java, no matter which OS you happen to be using |
| support        | Guess what this does :)                                                                                                                                             |
| test\_htmlunit | Compile the dependencies and then run the tests for the HtmlUnitDriver. The same “test\_x” pattern can be followed for all the compilation targets in this table.   |

### Running a remote Debugger with Java tests

You can run the tests in debug mode and wait for a remote java listener (which one would setup in eclipse or intellij).

```
./go debug=true suspend=true test_firefox
```

## Debugging the Firefox Driver

### Getting output from the Firefox process itself

This is usually useful to debug issues with Firefox starting up. The Java system property `webdriver.firefox.logfile` will instruct the FirefoxDriver to redirect the output to a file:

```
java -Dwebdriver.firefox.logfile=/dev/stdout -cp selenium-2.jar <sometest>
```

### Outputting to the Error Console

A common technique used for debugging of the Firefox driver extension is debug statements. The two following methods can be used from almost any Javascript code inside the extension:

* `Logger.dumpn()` - Logs a string into console (and converts arguments to strings). For example: `Logger.dumpn("Found element: " + node)`.
* `Logger.dump()` - Gets a single argument, an object, and dumps its entire contents: implemented interfaces, data fields, methods, etc.

### Getting output from the error console to a file

To see output generated using the `Logger` utility, one has to open up Firefox’s error console - difficult or simply impossible on remote machines. Fortunately, there’s a way to get the contents of the output dumped to a file:

```
FirefoxProfile p = new FirefoxProfile();
p.setPreference("webdriver.log.file", "/tmp/firefox_console");
WebDriver driver = new FirefoxDriver(p);
...
```

The `webdriver.log.file` preference will instruct the `Logger` to dump all contents of the console to the specified file. webdriver.log.file

### Getting even more output to the command line

When suspecting additional logging from Firefox could be beneficial, one can crank debugging level all the way up:

```
export NSPR_LOG_MODULES=all:3
```

Setting this environment variable will cause Firefox to log additional messages to the console. Use this environment variable together with `webdriver.firefox.logfile` to get a hold of Firefox’s output to the console.

## Debugging the Internet Explorer Driver

In order to get detailed information from IEDriverServer.exe you can run tests with the option devMode=true, this option will set logging level to DEBUG and redirect log output to the file iedriver.log

```
./go test_ie devMode=true
```

## Adding a test

Most of WebDriver’s test cases live under java/client/test/org/openqa/selenium. For example, to demonstrate an issue with clicking on elements, a test case should be added to ClickTest. The test cases already have a driver instance - no need to create one. The test use pages that are served by an in-process server, served from common/src/web. Their URLs are provided by the Pages class, so when adding a page and add it to the Pages class as well.

## Manually interacting with `RemoteWebDriverServer`

We can use a web browser or tools such as telnet to interact with a RemoteWebDriverServer e.g. to debug the JSON protocol. Here’s a simple example of checking the status of a server installed on the local machine

In a web browser

```
http://localhost:8080/wd/hub/status/
```

In telnet

```
telnet localhost 8080

GET /wd/hub/status/ HTTP/1.0
```

On Macs and Unix in general try `curl`

```
curl  http://localhost:8080/wd/hub/status
```

And on linux `wget`

```
wget http://localhost:8080/wd/hub/status
```

In all these cases the RemoteWebDriverServer should respond with

```

{status:0} 
```

# 7.7 - Snapshot of Roadmaps for Selenium Releases

The list of plans and things to accomplish before a release

## Preparation for Selenium 2

Date unknown This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/RoadMap/eef12bca5fdc865449ad2d1735ee08e40ba0bd2b)

The following issues need to be resolved before the final release:

| **Issue**                                                    | **Summary**                                             | **HtmlUnitDriver Progress** | **FirefoxDriver Progress** | **InternetExplorerDriver Progress** | **ChromeDriver Progress** |
| ------------------------------------------------------------ | ------------------------------------------------------- | --------------------------- | -------------------------- | ----------------------------------- | ------------------------- |
| [27](http://code.google.com/p/webdriver/issues/detail?id=27) | Handle alerts in Javascript-enabled browsers            | n/a                         | Started                    | Started                             | Not Started               |
| [32](http://code.google.com/p/webdriver/issues/detail?id=32) | User guide                                              | Started                     |                            |                                     |                           |
| [34](http://code.google.com/p/webdriver/issues/detail?id=34) | Support HTTP Basic and Digest Authentication            | Not Started                 |                            |                                     |                           |
| [35](http://code.google.com/p/webdriver/issues/detail?id=35) | [Selenium](http://www.openqa.org/selenium-rc) emulation | Done for Java and C#        |                            |                                     |                           |
| [36](http://code.google.com/p/webdriver/issues/detail?id=36) | Support for drag and drop behaviour                     | n/a                         | Done                       | Done                                | Started                   |
| none                                                         | Example tests                                           | Not Started                 |                            |                                     |                           |

----
url: https://www.selenium.dev/ja/documentation/webdriver/browsers/edge/
----

# Edge固有の機能

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L38-L38)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options = get_default_edge_options()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L9-L10)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        {
            var options = new EdgeOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L30-L31)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let options = new edge.Options();
    driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/openEdgeTest.spec.js#L11-L15)

##### /examples/javascript/test/getting\_started/openEdgeTest.spec.js

```js
const {Browser, Builder} = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');


describe('Open Edge', function () {
  let driver;



  before(async function () {
    let options = new edge.Options();
    driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options)
      .build();
  });

  after(async () => await driver.quit());

  it('Basic Edge test', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
  public void arguments() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L46)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L18)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L39)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.args << '--start-maximized'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L17)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.addArguments('--headless=new'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L12)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```java
  public void setBrowserLocation() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L55)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L29)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L49)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.binary = edge_location
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L25)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L66)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L40)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L61)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.add_extension(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L34)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L55)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L51)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

**注意**: これはすでに.NETのデフォルトの動作です。

```rb
      options.detach = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L45)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.detachDriver(true))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L32)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```java
  public void excludeSwitches() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L79)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L62)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L76)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.exclude_switches << 'disable-popup-blocking'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L53)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L22)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```java
  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L101)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Javaでもシステムプロパティを使用してファイル出力を設定できます:\
プロパティキー: `EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY`\
プロパティ値: ログファイルのパスを表す文字列

```py
def test_log_to_file(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L71)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L86)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L67)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    File logLocation = getTempFile("logsToConsole", ".log");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L114)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注**: Javaでは、システムプロパティを使用してコンソール出力を設定することもできます。\
プロパティキー: `EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY`\
プロパティ値:`DriverService.LOG_STDOUT` または `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
def test_log_to_stdout(capfd):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L82)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

`$stdout` と `$stderr`はどちらも有効な値です。

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L76)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L127-L128)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Javaでは、システムプロパティを使用してログレベルを設定することもできます：\
プロパティキー: `EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY`\
プロパティ値:`ChromiumDriverLogLevel` 列挙型の文字列表現

```py
def test_log_level(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L93)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '--log-level=DEBUG'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L87)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L143-L144)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Javaでは、これらの機能をSystem Propertyによって切り替えることもできます：\
プロパティキー:`EdgeDriverService.EDGE_DRIVER_APPEND_LOG_PROPERTY` および `EdgeDriverService.EDGE_DRIVER_READABLE_TIMESTAMP`\
プロパティ値: `"true"` または `"false"`

```py
def test_log_features(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L104)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << '--append-log'
      service.args << '--readable-timestamp'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L97-L98)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L161-L162)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注**: Javaでは、システムプロパティを使用してビルドチェックを無効にすることもできます：\
プロパティキー:`EdgeDriverService.EDGE_DRIVER_DISABLE_BUILD_CHECK`\
プロパティ値: `"true"` または `"false"`

```py
def test_build_checks(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L115)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L155)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << '--disable-build-check'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L108)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L225-L230)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L170-L174)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L119-L123)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L198-L204)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L129-L135)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L129)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    consoleLogButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L242)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L186)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      sleep 1
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L141)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    EdgeDriver driver = new EdgeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L184)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L149)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L149-L150)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### DevTools

EdgeでDevToolsを使用する際の詳細については、\[Chrome DevTools]セクションを参照してください。

----
url: https://www.selenium.dev/documentation/legacy/selenium_ide/releases/
----

# Legacy Selenium IDE Release Notes

| 73% (22) | Samit Badle             |
| -------- | ----------------------- |
| 16%( 5)  | Adam Goucher            |
| 6% (2)   | Dave Hunt               |
| 3% (1)   | Santiago Suarez Ordoñez |
| 3% (1)   | Simon Stewart           |

----
url: https://www.selenium.dev/pt-br/documentation/about/style/
----

# Guia de estilo para a documentação do Selenium

Convenções para contribuições à documentação do Selenium e exemplos de código.

Read our [contributing documentation](https://www.selenium.dev/pt-br/documentation/about/contributing/) for complete instructions on how to add content to this documentation.

## Alerts

Alerts have been added to direct potential contributors to where specific content is missing.

```html
{{< alert-content />}}
```

or

```html
{{< alert-content >}}
Additional information about what specific content is needed
{{< /alert-content >}}
```

```java
WebDriver driver = new ChromeDriver();
```

```python
driver = webdriver.Chrome()
```

```csharp
var driver = new ChromeDriver();
```

```ruby
driver = Selenium::WebDriver.for :chrome
```

```javascript
let driver = await new Builder().forBrowser('chrome').build();
```

```kotlin
val driver = ChromeDriver()
```

To generate the above tabs, this is what you need to write. Note that the `tabpane` includes `langEqualsHeader=true`. This auto-formats the code in each tab to match the header name, and ensures that all tabs on the page with a language are set to the same thing.

```
{{< tabpane langEqualsHeader=true >}}
  {{< tab header="Java" >}}
    WebDriver driver = new ChromeDriver();
  {{< /tab >}}
  {{< tab header="Python" >}}
    driver = webdriver.Chrome()
  {{< /tab >}}
  {{< tab header="CSharp" >}}
    var driver = new ChromeDriver();
  {{< /tab >}}
  {{< tab header="Ruby" >}}
    driver = Selenium::WebDriver.for :chrome
  {{< /tab >}}
  {{< tab header="JavaScript" >}}
    let driver = await new Builder().forBrowser('chrome').build();
  {{< /tab >}}
  {{< tab header="Kotlin" >}}
    val driver = ChromeDriver()
  {{< /tab >}}
{{< /tabpane >}}
```

#### Reference GitHub Examples

To ensure that all code is kept up to date, our goal is to write the code in the repo where it can be executed when Selenium versions are updated to ensure that everything is correct.

All code examples to be in our [example directories](https://github.com/SeleniumHQ/seleniumhq.github.io/tree/dev/examples).

This code can be automatically displayed in the documentation using the `gh-codeblock` shortcode. The shortcode automatically generates its own html, so we do not want it to auto-format with the language header. If all tabs are using this shortcode, set `text=true` in the `tabpane` and remove `langEqualsHeader=true`. If only some tabs are using this shortcode, keep `langEqualsHeader=true` in the `tabpane` and add `text=true` to the `tab`. Note that the `gh-codeblock` line can not be indented at all.

One great thing about using `gh-codeblock` is that it adds a link to the full example. This means you don’t have to include any additional context code, just the line(s) that are needed, and the user can navigate to the repo to see how to use it.

A basic comparison of code looks like:

```
{{< tabpane text=true >}}
{{< tab header="Java" >}}
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-L27" >}}
{{< /tab >}}
{{< tab header="Python" >}}
{{< gh-codeblock path="/examples/python/tests/getting_started/first_script.py#L18-L19" >}}
{{< /tab >}}
{{< tab header="CSharp" >}}
{{< gh-codeblock path="/examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-L26" >}}
{{< /tab >}}
{{< tab header="Ruby" >}}
{{< gh-codeblock path="/examples/ruby/spec/getting_started/first_script.rb#L17-L18" >}}
{{< /tab >}}
{{< tab header="JavaScript" >}}
{{< gh-codeblock path="/examples/javascript/test/getting_started/firstScript.spec.js#L22-L23" >}}
{{< /tab >}}
{{< tab header="Kotlin" >}}
{{< gh-codeblock path="/examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-L32" >}}
{{< /tab >}}
{{< /tabpane >}}
```

```java
        WebElement message = driver.findElement(By.id("message"));
        message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-L27)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
message = driver.find_element(by=By.ID, value="message")
text = message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L18-L19)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-L26)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
message = driver.find_element(id: 'message')
message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L17-L18)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L22-L23)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val message = driver.findElement(By.id("message"))
        val value = message.getText()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-L32)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

### Using Markdown in a Tab

If you want your example to include something other than code (default) or html (from `gh-codeblock`), you need to first set `text=true`, then change the Hugo syntax for the `tab`to use `%` instead of `<` and `>` with curly braces:

```
{{< tabpane text=true >}}
{{% tab header="Java" %}}
1. Start the driver
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12" >}}
2. Navigate to a page
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14" >}}
3. Quit the driver
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29" >}}
{{% /tab %}}
< ... >
{{< /tabpane >}}
```

This produces:

*

1. Start the driver

   ```java
           WebDriver driver = new ChromeDriver();
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

2. Navigate to a page

   ```java
           driver.get("https://www.selenium.dev/selenium/web/web-form.html");
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

3. Quit the driver

   ```java
           driver.quit();
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

This is preferred to writing code comments because those will not be translated. Only include the code that is needed for the documentation, and avoid over-explaining. Finally, remember not to indent plain text or it will rendered as a codeblock.

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/encouraged/consider_using_a_fluent_api/
----

# Considere usar uma API fluente

Martin Fowler cunhou o termo [“API Fluent”](//www.martinfowler.com/bliki/FluentInterface.html). Selenium já implementa algo assim em sua classe `FluentWait`, que é pretende ser uma alternativa à classe padrão `Wait`. Você pode habilitar o padrão de design de API fluente em seu objeto de página e, em seguida, consulte a página de pesquisa do Google com um snippet de código como este:

```java
driver.get( "http://www.google.com/webhp?hl=en&amp;tab=ww" );
GoogleSearchPage gsp = new GoogleSearchPage(driver);
gsp.setSearchString().clickSearchButton();
```

A classe de objeto da página do Google com este comportamento fluente pode ser assim:

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

public class GoogleSearchPage extends BasePage {
    public GoogleSearchPage(WebDriver driver) {
        super(driver);
        // Generally do not assert within pages or components.
        // Effectively throws an exception if the lambda condition is not met.
        new WebDriverWait(driver, Duration.ofSeconds(3)).until(d -> d.findElement(By.id("logo")));
    }

    public GoogleSearchPage setSearchString(String sstr) {
        driver.findElement(By.id("gbqfq")).sendKeys(sstr);
        return this;
    }

    public void clickSearchButton() {
        driver.findElement(By.id("gbqfb")).click();
    }
}
```

Última modificação May 17, 2023: [Consider Using a Fluent API - Fix usage (#1378) (332da70d909)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/332da70d90970623288d2e98fbcff098b7812995)

----
url: https://www.selenium.dev/ja/_print/documentation/legacy/selenium_3/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/legacy/selenium_3/).

# Selenium 3

Selenium 3 was the implementation of WebDriver without the Selenium RC Code. It has since been replaced with Selenium 4, which implements the W3C WebDriver specification.

* 1: [Grid 3](#pg-7de6b958ae01ee49598af67bc8beb54b)
* 2: [独自のグリッドを設定する](#pg-b440ee8870fc93b6895529a575702cfd)
* 3: [グリッドのコンポーネント](#pg-f6b04bbdc688aa2cc42afbe78c4d549d)

# 1 - Grid 3

Selenium Grid 3 supported WebDriver without Selenium RC code. Grid 3 was completely rewritten for the new Grid 4.

[Grid 4](https://www.selenium.dev/ja/documentation/grid/)

*Selenium Grid* は、SeleniumテストがコマンドをリモートWebブラウザーインスタンスにルーティングできるようにする賢いプロキシサーバーです。 その目的は、複数のマシンで並行してテストを実行する簡単な方法を提供することです。

Selenium Gridでは、1つのサーバーが、JSON形式のテストコマンドを1つ以上の登録済みのグリッドノードにルーティングするハブとして機能します。 テストはハブに接続して、リモートブラウザーインスタンスへのアクセスを取得します。 ハブには、アクセスを提供する登録済みサーバーのリストがあり、これらのインスタンスを制御できます。

Selenium Gridを使用すると、複数のマシンで並行してテストを実行し、さまざまなブラウザーバージョンとブラウザー構成を（個々のテストではなく）一元的に管理できます。

Selenium Gridは特効薬ではありません。 一般的な委譲および配布の問題のサブセットを解決しますが、たとえばインフラストラクチャを管理せず、特定のニーズに適さない場合があります。

# 2 - 独自のグリッドを設定する

```shell
java -jar selenium-server-standalone.jar -role hub
```

ハブはデフォルトでポート4444をリッスンします。 ブラウザーウィンドウを開いて <http://localhost:4444/grid/console> に移動すると、ハブのステータスを表示できます。

デフォルトのポートを変更するには、コマンドを実行するときにリッスンするポートを表す整数を持つオプションの `-port` フラグを追加できます。 また、JSON構成ファイル（以下を参照）に表示される他のすべてのオプションは、可能なコマンドラインフラグです。

確かに上記の簡単なコマンドだけでうまくいくことができますが、より高度な構成が必要な場合は、JSON形式の構成ファイルを指定して、開始時にハブを構成することもできます。 JSON形式の構成ファイルを指定して開始時にハブを構成する方法は以下のとおりです。

```shell
java -jar selenium-server-standalone.jar -role hub -hubConfig hubConfig.json -debug
```

以下に、 `hubConfig.json` ファイルの例を示します。 ステップ2でノード構成ファイルを提供する方法について詳しく説明します。

```json
{
  "_comment" : "Configuration for Hub - hubConfig.json",
  "host": ip,
  "maxSession": 5,
  "port": 4444,
  "cleanupCycle": 5000,
  "timeout": 300000,
  "newSessionWaitTimeout": -1,
  "servlets": [],
  "prioritizer": null,
  "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
  "throwOnCapabilityNotPresent": true,
  "nodePolling": 180000,
  "platform": "WINDOWS"}
```

### ステップ2：ノードを起動する

新しいWebDriver機能を備えたグリッドを実行するか、Selenium 1 RC機能を備えたグリッドを実行するか、または両方を同時に実行するかに関係なく、同じ `selenium-server-standalone.jar` ファイルを使用してノードを起動します。

```shell
java -jar selenium-server-standalone.jar -role node -hub http://localhost:4444
```

```shell
java -Dwebdriver.chrome.driver=chromedriver.exe -jar selenium-server-standalone.jar -role node -nodeConfig node1Config.json
```

そして、これは `nodeConfig.json` ファイルの例です。

```json
{
  "capabilities": [
    {
      "browserName": "firefox",
      "acceptSslCerts": true,
      "javascriptEnabled": true,
      "takesScreenshot": false,
      "firefox_profile": "",
      "browser-version": "27",
      "platform": "WINDOWS",
      "maxInstances": 5,
      "firefox_binary": "",
      "cleanSession": true
    },
    {
      "browserName": "chrome",
      "maxInstances": 5,
      "platform": "WINDOWS",
      "webdriver.chrome.driver": "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"
    },
    {
      "browserName": "internet explorer",
      "maxInstances": 1,
      "platform": "WINDOWS",
      "webdriver.ie.driver": "C:/Program Files (x86)/Internet Explorer/iexplore.exe"
    }
  ],
  "configuration": {
    "_comment" : "Configuration for Node",
    "cleanUpCycle": 2000,
    "timeout": 30000,
    "proxy": "org.openqa.grid.selenium.proxy.WebDriverRemoteProxy",
    "port": 5555,
    "host": ip,
    "register": true,
    "hubPort": 4444,
    "maxSession": 5
  }
}
```

```shell
java -jar selenium-server-standalone.jar -role hub -log log.txt
```

お気に入りのテキストエディターを使用してログファイル（上記の例ではlog.txt）を開き、問題が発生した場合に"エラー"ログを見つけます。

### `-debug` 引数を使用する

-debug引数を使用して、デバッグログをコンソールに出力することもできます。 `-debug` 引数を使用してSeleniumグリッドハブまたはノードを起動します。 以下の例をご覧ください。

```shell
java -jar selenium-server-standalone.jar -role hub -debug
```

# 3 - グリッドのコンポーネント

----
url: https://www.selenium.dev/ja/_print/documentation/legacy/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/legacy/).

# レガシー

このセクションでは、Seleniumのレガシーコンポーネントに関連するすべてのドキュメントを見つけることができます。 これは、非推奨コンポーネントを使用する動機としてではなく、純粋に歴史的な理由で保持されることを意図しています。

* 1: [Selenium RC (Selenium 1)](#pg-e110624c2173a008ef22f9868f67af24)
* 2: [Selenium 2](#pg-ede019ded97a1a192cb78af69ca6d9e0)
* * 2.1: [RCからWebDriverへの移行](#pg-a933946e45b79ed277508ff2adf95523)
  * 2.2: [リモートWebDriverサーバー](#pg-3cf3554f61b84dbd1b188df5fe81a963)
  3: [Selenium 3](#pg-eb898089792ca95955a3e178c30668c5)
* * 3.1: [Grid 3](#pg-7de6b958ae01ee49598af67bc8beb54b)
  * 3.2: [独自のグリッドを設定する](#pg-b440ee8870fc93b6895529a575702cfd)
  * 3.3: [グリッドのコンポーネント](#pg-f6b04bbdc688aa2cc42afbe78c4d549d)
  4: [レガシー Selenium IDE](#pg-0e6ac56fecd03a41b9fe9f76020a6bfe)
  * 4.1: [HTMLランナー](#pg-83d0a8171b15b9b98fe401350fa5a31d)

**Most of the documentation found in this section is still in English. Please note we are not accepting pull requests to translate this content as translating documentation of legacy components does not add value to the community nor the project.

# 1 - Selenium RC (Selenium 1)

```shell
    java -jar selenium-server-standalone-<version-number>.jar
```

これは、上記のコマンドを含むバッチまたはシェル実行可能ファイル（Windowsでは.bat、Linuxでは.sh）を作成することで簡素化できます。 次に、デスクトップ上でその実行可能ファイルへのショートカットを作成し、アイコンをダブルクリックしてサーバーを起動します。

サーバーを実行するには、Javaをインストールし、PATH環境変数をコンソールから実行するように正しく構成する必要があります。 コンソールで次を実行すると、Javaが正しくインストールされていることを確認できます。

```shell
       java -version
```

|                   |                            |             |
| ----------------- | -------------------------- | ----------- |
| open              | /                          |             |
| type              | q                          | selenium rc |
| clickAndWait      | btnG                       |             |
| assertTextPresent | Results \* for selenium rc |             |

注：この例は、Google検索ページ <http://www.google.com> で機能します。

### プログラミングコードとしてのSelenese

サポートされている各プログラミング言語に(Selenium-IDE経由で)エクスポートされたテストスクリプトを次に示します。 オブジェクト指向プログラミング言語の少なくとも基本的な知識がある場合は、これらの例のいずれかを読むことで、SeleniumがSeleneseコマンドを実行する方法を理解できます。 特定の言語の例を表示するには、これらのボタンのいずれかを選択します。

#### CSharp

```csharp

        using System;
        using System.Text;
        using System.Text.RegularExpressions;
        using System.Threading;
        using NUnit.Framework;
        using Selenium;

        namespace SeleniumTests
        {
            [TestFixture]
            public class NewTest
            {
                private ISelenium selenium;
                private StringBuilder verificationErrors;
                
                [SetUp]
                public void SetupTest()
                {
                    selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
                    selenium.Start();
                    verificationErrors = new StringBuilder();
                }
                
                [TearDown]
                public void TeardownTest()
                {
                    try
                    {
                        selenium.Stop();
                    }
                    catch (Exception)
                    {
                        // Ignore errors if unable to close the browser
                    }
                    Assert.AreEqual("", verificationErrors.ToString());
                }
                
                [Test]
                public void TheNewTest()
                {
                    selenium.Open("/");
                    selenium.Type("q", "selenium rc");
                    selenium.Click("btnG");
                    selenium.WaitForPageToLoad("30000");
                    Assert.AreEqual("selenium rc - Google Search", selenium.GetTitle());
                }
            }
        }
```

#### Java

```java
      
	  /** Add JUnit framework to your classpath if not already there 
	   *  for this example to work
	  */
      package com.example.tests;

      import com.thoughtworks.selenium.*;
      import java.util.regex.Pattern;

      public class NewTest extends SeleneseTestCase {
          public void setUp() throws Exception {
              setUp("http://www.google.com/", "*firefox");
          }
            public void testNew() throws Exception {
                selenium.open("/");
                selenium.type("q", "selenium rc");
                selenium.click("btnG");
                selenium.waitForPageToLoad("30000");
                assertTrue(selenium.isTextPresent("Results * for selenium rc"));
          }
      }
```

#### Php

```php
      <?php

      require_once 'PHPUnit/Extensions/SeleniumTestCase.php';

      class Example extends PHPUnit_Extensions_SeleniumTestCase
      {
        function setUp()
        {
          $this->setBrowser("*firefox");
          $this->setBrowserUrl("http://www.google.com/");
        }

        function testMyTestCase()
        {
          $this->open("/");
          $this->type("q", "selenium rc");
          $this->click("btnG");
          $this->waitForPageToLoad("30000");
          $this->assertTrue($this->isTextPresent("Results * for selenium rc"));
        }
      }
      ?>
```

#### Python

```python

     from selenium import selenium
      import unittest, time, re

      class NewTest(unittest.TestCase):
          def setUp(self):
              self.verificationErrors = []
              self.selenium = selenium("localhost", 4444, "*firefox",
                      "http://www.google.com/")
              self.selenium.start()
         
          def test_new(self):
              sel = self.selenium
              sel.open("/")
              sel.type("q", "selenium rc")
              sel.click("btnG")
              sel.wait_for_page_to_load("30000")
              self.failUnless(sel.is_text_present("Results * for selenium rc"))
         
          def tearDown(self):
              self.selenium.stop()
              self.assertEqual([], self.verificationErrors)
```

#### Ruby

```ruby

      require "selenium/client"
      require "test/unit"

      class NewTest < Test::Unit::TestCase
        def setup
          @verification_errors = []
          if $selenium
            @selenium = $selenium
          else
            @selenium =  Selenium::Client::Driver.new("localhost", 4444, "*firefox", "http://www.google.com/", 60);
            @selenium.start
          end
          @selenium.set_context("test_new")
        end

        def teardown
          @selenium.stop unless $selenium
          assert_equal [], @verification_errors
        end

        def test_new
          @selenium.open "/"
          @selenium.type "q", "selenium rc"
          @selenium.click "btnG"
          @selenium.wait_for_page_to_load "30000"
          assert @selenium.is_text_present("Results * for selenium rc")
        end
      end
```

```java
    selenium = new DefaultSelenium("localhost", 4444, "*iehta", "http://www.google.com/");
```

Selenium-IDEで生成されたコードは次のようになります。 この例では、わかりやすくするためにコメントを手動で追加しています。

```java
   package com.example.tests;
   // We specify the package of our tests

   import com.thoughtworks.selenium.*;
   // This is the driver's import. You'll use this for instantiating a
   // browser and making it do what you need.

   import java.util.regex.Pattern;
   // Selenium-IDE add the Pattern module because it's sometimes used for 
   // regex validations. You can remove the module if it's not used in your 
   // script.

   public class NewTest extends SeleneseTestCase {
   // We create our Selenium test case

         public void setUp() throws Exception {
           setUp("http://www.google.com/", "*firefox");
                // We instantiate and start the browser
         }

         public void testNew() throws Exception {
              selenium.open("/");
              selenium.type("q", "selenium rc");
              selenium.click("btnG");
              selenium.waitForPageToLoad("30000");
              assertTrue(selenium.isTextPresent("Results * for selenium rc"));
              // These are the real test steps
        }
   }
```

### `C#`

.NETクライアントドライバーはMicrosoft.NETで動作します。 NUnitやVisual Studio 2005 Team Systemなどの.NETテストフレームワークで利用できます。

Selenium-IDEは、テストフレームワークとしてNUnitを使用することを想定しています。 以下の生成コードでこれを確認できます。 NUnitの *using* ステートメントと、テストクラスの各メンバー関数の役割を識別する対応するNUnit属性が含まれています。

おそらく、テストクラスの名前を"NewTest"から独自の選択に変更する必要があります。 また、ステートメントのブラウザで開くパラメーターを変更する必要があります。

```csharp
    selenium = new DefaultSelenium("localhost", 4444, "*iehta", "http://www.google.com/");
```

生成されたコードは次のようになります。

```csharp

    using System;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading;
    using NUnit.Framework;
    using Selenium;
    
    namespace SeleniumTests

    {
        [TestFixture]

        public class NewTest

        {
        private ISelenium selenium;

        private StringBuilder verificationErrors;

        [SetUp]

        public void SetupTest()

        {
            selenium = new DefaultSelenium("localhost", 4444, "*iehta",
            "http://www.google.com/");

            selenium.Start();

            verificationErrors = new StringBuilder();
        }

        [TearDown]

        public void TeardownTest()
        {
            try
            {
            selenium.Stop();
            }

            catch (Exception)
            {
            // Ignore errors if unable to close the browser
            }

            Assert.AreEqual("", verificationErrors.ToString());
        }
        [Test]

        public void TheNewTest()
        {
            // Open Google search engine.        
            selenium.Open("http://www.google.com/"); 
            
            // Assert Title of page.
            Assert.AreEqual("Google", selenium.GetTitle());
            
            // Provide search term as "Selenium OpenQA"
            selenium.Type("q", "Selenium OpenQA");
            
            // Read the keyed search term and assert it.
            Assert.AreEqual("Selenium OpenQA", selenium.GetValue("q"));
            
            // Click on Search button.
            selenium.Click("btnG");
            
            // Wait for page to load.
            selenium.WaitForPageToLoad("5000");
            
            // Assert that "www.openqa.org" is available in search results.
            Assert.IsTrue(selenium.IsTextPresent("www.openqa.org"));
            
            // Assert that page title is - "Selenium OpenQA - Google Search"
            Assert.AreEqual("Selenium OpenQA - Google Search", 
                         selenium.GetTitle());
        }
        }
    }
```

NUnitにテストの実行を管理させることができます。 または、テストオブジェクトをインスタンス化し、`SetupTest()`、`TheNewTest()`、`TeardownTest()` の各メソッドを順番に実行する単純な `main()` プログラムを作成することもできます。

### Python

Pyunitは、Pythonで使用するテストフレームワークです。

基本的なテスト構造は次のとおりです。

```python

   from selenium import selenium
   # This is the driver's import.  You'll use this class for instantiating a
   # browser and making it do what you need.

   import unittest, time, re
   # This are the basic imports added by Selenium-IDE by default.
   # You can remove the modules if they are not used in your script.

   class NewTest(unittest.TestCase):
   # We create our unittest test case

       def setUp(self):
           self.verificationErrors = []
           # This is an empty array where we will store any verification errors
           # we find in our tests

           self.selenium = selenium("localhost", 4444, "*firefox",
                   "http://www.google.com/")
           self.selenium.start()
           # We instantiate and start the browser

       def test_new(self):
           # This is the test code.  Here you should put the actions you need
           # the browser to do during your test.
            
           sel = self.selenium
           # We assign the browser to the variable "sel" (just to save us from 
           # typing "self.selenium" each time we want to call the browser).
            
           sel.open("/")
           sel.type("q", "selenium rc")
           sel.click("btnG")
           sel.wait_for_page_to_load("30000")
           self.failUnless(sel.is_text_present("Results * for selenium rc"))
           # These are the real test steps

       def tearDown(self):
           self.selenium.stop()
           # we close the browser (I'd recommend you to comment this line while
           # you are creating and debugging your tests)

           self.assertEqual([], self.verificationErrors)
           # And make the test fail if we found that any verification errors
           # were found
```

### Ruby

Selenium-IDEの古い（2.0より前の）バージョンは、古いSelenium gemを必要とするRubyコードを生成します。 したがって、IDEによって生成されたRubyスクリプトを次のように更新することをお勧めします。

1. １行目を `require "selenium"` から `require "selenium/client"` に変更

2. 11行目を `Selenium::SeleniumDriver.new` から `Selenium::Client::Driver.new` に変更

クラス名を"Untitled"よりもわかりやすい名前に変更し、テストメソッドの名前を"test\_untitled"以外の名前に変更することもできます。

上記のように、Selenium IDEによって生成されたRubyコードを変更して作成された簡単な例を次に示します。

```ruby

   # load the Selenium-Client gem
   require "selenium/client"

   # Load Test::Unit, Ruby's default test framework.
   # If you prefer RSpec, see the examples in the Selenium-Client
   # documentation.
   require "test/unit"

   class Untitled < Test::Unit::TestCase

     # The setup method is called before each test.
     def setup

       # This array is used to capture errors and display them at the
       # end of the test run.
       @verification_errors = []

       # Create a new instance of the Selenium-Client driver.
       @selenium = Selenium::Client::Driver.new \
         :host => "localhost",
         :port => 4444,
         :browser => "*chrome",
         :url => "http://www.google.com/",
         :timeout_in_second => 60

       # Start the browser session
       @selenium.start

       # Print a message in the browser-side log and status bar
       # (optional).
       @selenium.set_context("test_untitled")

     end

     # The teardown method is called after each test.
     def teardown

       # Stop the browser session.
       @selenium.stop

       # Print the array of error messages, if any.
       assert_equal [], @verification_errors
     end

     # This is the main body of your test.
     def test_untitled
     
       # Open the root of the site we specified when we created the
       # new driver instance, above.
       @selenium.open "/"

       # Type 'selenium rc' into the field named 'q'
       @selenium.type "q", "selenium rc"

       # Click the button named "btnG"
       @selenium.click "btnG"

       # Wait for the search results page to load.
       # Note that we don't need to set a timeout here, because that
       # was specified when we created the new driver instance, above.
       @selenium.wait_for_page_to_load

       begin

          # Test whether the search results contain the expected text.
	  # Notice that the star (*) is a wildcard that matches any
	  # number of characters.
	  assert @selenium.is_text_present("Results * for selenium rc")
	  
       rescue Test::Unit::AssertionFailedError
       
          # If the assertion fails, push it onto the array of errors.
	  @verification_errors << $!

       end
     end
   end
```

### Perl, PHP

ドキュメントチームのメンバーは、PerlまたはPHPでSelenium RCを使用していません。 これらの2つの言語のいずれかでSelenium RCを使用している場合は、ドキュメントチームに連絡してください（貢献に関する章を参照）。 PerlおよびPHPユーザーをサポートするために、あなたとあなたの経験からいくつかの例を含めたいと思います。

## APIを学ぶ

Selenium RC APIは、Seleneseを理解していると仮定すると、インターフェイスのほとんどが自明である命名規則を使用します。 ただし、ここでは、最も重要で、おそらくそれほど明白ではない側面について説明します。

### ブラウザーを起動する

#### CSharp

```csharp
      selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
      selenium.Start();
```

#### Java

```java

      setUp("http://www.google.com/", "*firefox");
```

#### Perl

```perl
      my $sel = Test::WWW::Selenium->new( host => "localhost", 
                                          port => 4444, 
                                          browser => "*firefox", 
                                          browser_url => "http://www.google.com/" );
```

#### Php

```php
      $this->setBrowser("*firefox");
      $this->setBrowserUrl("http://www.google.com/");
```

#### Python

```python
      self.selenium = selenium("localhost", 4444, "*firefox",
                               "http://www.google.com/")
      self.selenium.start()
```

#### Ruby

```ruby
      @selenium = Selenium::ClientDriver.new("localhost", 4444, "*firefox", "http://www.google.com/", 10000);
      @selenium.start
```

```
    selenium.type("field-id","string to type")
```

|                   |                              |               |
| ----------------- | ---------------------------- | ------------- |
| open              | /                            |               |
| type              | q                            | selenium rc   |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium rc   |               |
| type              | q                            | selenium ide  |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium ide  |               |
| type              | q                            | selenium grid |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium grid |               |

同じ手順を3回実行するためにコードが繰り返されています。 ただし、同じコードのコピーを複数作成することは、維持する作業が増えるため、プログラムとしては適切ではありません。 プログラミング言語を使用することで、検索結果を反復処理して、より柔軟で保守可能なソリューションを実現できます。

#### `C#` の場合

```csharp
   // Collection of String values.
   String[] arr = {"ide", "rc", "grid"};    
        
   // Execute loop for each String in array 'arr'.
   foreach (String s in arr) {
       sel.open("/");
       sel.type("q", "selenium " +s);
       sel.click("btnG");
       sel.waitForPageToLoad("30000");
       assertTrue("Expected text: " +s+ " is missing on page."
       , sel.isTextPresent("Results * for selenium " + s));
    }
```

### 条件ステートメント

テストでの条件の使用を説明するために、例から始めます。 Seleniumテストの実行中に発生する一般的な問題は、ページで予期される要素が利用できない場合に発生します。 たとえば、次の行を実行する場合です。

```
   selenium.type("q", "selenium " +s);
```

要素 ‘q’がページにない場合、例外がスローされます。

```java
   com.thoughtworks.selenium.SeleniumException: ERROR: Element q not found
```

これにより、テストが中断する可能性があります。 いくつかのテストでは、それがあなたの望むものです。 しかし、多くの場合、テストスクリプトには実行する他の多くのテストがあるため、これは望ましくありません。

より良いアプローチは、まず要素が実際に存在するかどうかを検証し、次に存在しない場合に代替手段を取ることです。 Javaを使用してこれを見てみましょう。

```java
   // If element is available on page then perform type operation.
   if(selenium.isElementPresent("q")) {
       selenium.type("q", "Selenium rc");
   } else {
       System.out.printf("Element: " +q+ " is not available on page.")
   }
```

このアプローチの利点は、ページで一部のUI要素が利用できない場合でも、テストの実行を続行できることです。

### テストからJavaScriptを実行する

JavaScriptは、セレンによって直接サポートされていないアプリケーションを実行する際に非常に便利です。 Selenium APIの **getEval** メソッドを使用して、Selenium RCからJavaScriptを実行できます。

静的な識別子のないチェックボックスを持つアプリケーションを考えてください。 この場合、Selenium RCからJavaScriptを評価して、すべてのチェックボックスのIDを取得し、それらを実行できます。

```java
   public static String[] getAllCheckboxIds () { 
		String script = "var inputId  = new Array();";// Create array in java script.
		script += "var cnt = 0;"; // Counter for check box ids.  
		script += "var inputFields  = new Array();"; // Create array in java script.
		script += "inputFields = window.document.getElementsByTagName('input');"; // Collect input elements.
		script += "for(var i=0; i<inputFields.length; i++) {"; // Loop through the collected elements.
		script += "if(inputFields[i].id !=null " +
		"&& inputFields[i].id !='undefined' " +
		"&& inputFields[i].getAttribute('type') == 'checkbox') {"; // If input field is of type check box and input id is not null.
		script += "inputId[cnt]=inputFields[i].id ;" + // Save check box id to inputId array.
		"cnt++;" + // increment the counter.
		"}" + // end of if.
		"}"; // end of for.
		script += "inputId.toString();" ;// Convert array in to string.			
		String[] checkboxIds = selenium.getEval(script).split(","); // Split the string.
		return checkboxIds;
    }
```

ページ上の画像の数を数えるには、以下のとおりです。

```java
   selenium.getEval("window.document.images.length;");
```

デフォルトでは、テストウィンドウではなくSeleniumウィンドウが参照されるため、DOM式の場合は必ずウィンドウオブジェクトを使用してください。

## サーバーオプション

サーバーの起動時に、コマンドラインオプションを使用してデフォルトのサーバーの動作を変更できます。

サーバーを起動するには、次を実行してください。

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar
```

オプションのリストを表示するには、 `-h` オプションを指定してサーバーを実行します。

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar -h
```

サーバーで使用できるすべてのオプションのリストとそれぞれの簡単な説明が表示されます。 提供された説明では必ずしも十分ではないため、いくつかのより重要なオプションについて説明しました。

### プロキシ設定

AUTが認証を必要とするHTTPプロキシの後ろにある場合、次のコマンドを使用してhttp.proxyHost、http.proxyPort、http.proxyUserおよびhttp.proxyPasswordを設定する必要があります。

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar -Dhttp.proxyHost=proxy.com -Dhttp.proxyPort=8080 -Dhttp.proxyUser=username -Dhttp.proxyPassword=password
```

### マルチウィンドウモード

Selenium 1.0を使用している場合は、マルチウィンドウモードがデフォルトの動作であるため、おそらくこのセクションをスキップできます。 ただし、バージョン1.0より前は、Seleniumはデフォルトで、ここに示すようにサブフレームでテスト対象のアプリケーションを実行していました。

一部のアプリケーションはサブフレームで正しく実行されず、ウィンドウの上部フレームにロードする必要がありました。 マルチウィンドウモードオプションにより、AUTはデフォルトフレームではなく別のウィンドウで実行でき、そこで必要なトップフレームを取得できました。

Seleniumの古いバージョンでは、次のオプションで明示的にマルチウィンドウモードを指定する必要があります。

```bash
   -multiwindow 
```

Selenium RC 1.0の時点で、単一のフレーム内でテストを実行する場合（つまり、以前のSeleniumバージョンの標準を使用する場合）、オプションを使用してこれをSelenium Serverに指定できます。

```bash
   -singlewindow 
```

### Firefoxプロファイルの指定

Firefoxは、インスタンスごとに個別のプロファイルを指定しない限り、2つのインスタンスを同時に実行しません。 Selenium RC 1.0以降は個別のプロファイルで自動的に実行されるため、Selenium 1.0を使用している場合は、このセクションをスキップできます。 ただし、Seleniumの古いバージョンを使用している場合、またはテストに特定のプロファイルを使用する必要がある場合（https証明書の追加やアドオンのインストールなど）、プロファイルを明示的に指定する必要があります。

最初に、別のFirefoxプロファイルを作成するには、次の手順に従います。 Windowsのスタートメニューを開き、“実行"を選択して、次のいずれかを入力します。

```bash
   firefox.exe -profilemanager 
```

```bash
   firefox.exe -P 
```

ダイアログを使用して新しいプロファイルを作成します。 次に、Seleniumサーバーを実行するときに、サーバーのコマンドラインオプション *-firefoxProfileTemplate* でこの新しいFirefoxプロファイルを使用し、ファイル名とディレクトリパスを使用してプロファイルへのパスを指定するように指示します。

```bash
   -firefoxProfileTemplate "path to the profile" 
```

**警告**: 必ずデフォルトとは別の新しいフォルダーにプロファイルを入れてください!!! Firefoxプロファイルマネージャーツールは、プロファイルを削除すると、プロファイルファイルであるかどうかに関係なく、フォルダー内のすべてのファイルを削除します。

Firefoxプロファイルの詳細については、[Mozillaのナレッジベース](http://support.mozilla.com/en/kb/Managing+profiles)をご覧ください。

### -htmlSuiteを使用してサーバー内でSeleneseを直接実行する

HTMLファイルをサーバーのコマンドラインに渡すことで、Selenese HTMLファイルをSelenium Server内で直接実行できます。 例えば、

```bash
   java -jar selenium-server-standalone-<version-number>.jar -htmlSuite "*firefox" 
   "http://www.google.com" "c:\absolute\path\to\my\HTMLSuite.html" 
   "c:\absolute\path\to\my\results.html"
```

これにより、HTMLスイートが自動的に起動され、すべてのテストが実行され、結果とともにHTMLレポートが保存されます。

*注意:* このオプションを使用すると、サーバーはテストを開始し、テストが完了するまで指定された秒数待機します。 その時間内にテストが完了しない場合、コマンドはゼロ以外の終了コードで終了し、結果ファイルは生成されません。

このコマンドラインは非常に長いため、入力するときは注意してください。 これには、単一のテストではなく、HTML Seleneseスイートを渡す必要があることに注意してください。 また、 -htmlSuite オプションは`-interactive`と互換性がないことに注意してください。 両方を同時に実行することはできません。

### Seleniumサーバーのログ

#### サーバー側のログ

Seleniumサーバーを起動するときに、 **-log** オプションを使用して、Seleniumサーバーによってレポートされた貴重なデバッグ情報をテキストファイルに記録できます。

```bash
   java -jar selenium-server-standalone-<version-number>.jar -log selenium.log
```

このログファイルは、標準のコンソールログよりも詳細です（DEBUGレベルのログメッセージが含まれます）。 ログファイルには、ロガー名、およびメッセージを記録したスレッドのID番号も含まれます。 例えば、

```bash
   20:44:25 DEBUG [12] org.openqa.selenium.server.SeleniumDriverResourceHandler - 
   Browser 465828/:top frame1 posted START NEW
```

メッセージの形式は、以下のとおりです。

```bash
   TIMESTAMP(HH:mm:ss) LEVEL [THREAD] LOGGER - MESSAGE
```

このメッセージは複数行の場合があります。

#### ブラウザ側のログ

ブラウザ側のJavaScript（Selenium Core）も重要なメッセージを記録します。 多くの場合、これらは通常のSeleniumサーバーログよりもエンドユーザーにとって有用です。 ブラウザ側のログにアクセスするには、 **-browserSideLog** 引数をSeleniumサーバーに渡します。

```bash
   java -jar selenium-server-standalone-<version-number>.jar -browserSideLog
```

**-browserSideLog** を **-log** 引数と組み合わせて、browserSideLogs（および他のすべてのDEBUGレベルのログメッセージ）をファイルに記録する必要があります。

## 特定のブラウザへのパスを指定する

特定のブラウザーへのパスをSelenium RCに指定できます。 これは、同じブラウザーの異なるバージョンがあり、特定のブラウザーを使用する場合に便利です。 また、これは、Selenium RCで直接サポートされていないブラウザーに対してテストを実行できるようにするために使用されます。 実行モードを指定するときは、ブラウザの実行可能ファイルへのフルパスが後に続く \*custom 指定子を使用します。

```bash
   *custom <path to browser> 
```

```bash
   cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\MyBrowser.exe&2=http://www.google.com
```

### 異なるブラウザー設定でテストを実行する

通常、Selenium RCはブラウザーを自動的に設定しますが、”\*custom" 実行モードを使用してブラウザーを起動する場合、自動設定を使用せずにSelenium RCにブラウザーをそのまま強制的に起動させることができます。

たとえば、次のようなカスタム設定でFirefoxを起動できます。

```bash
   cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\firefox.exe&2=http://www.google.com
```

この方法でブラウザーを起動する場合、Selenium Serverをプロキシとして使用するようにブラウザーを手動で設定する必要があることに注意してください。 通常、これはブラウザーの設定を開き、“localhost:4444"をHTTPプロキシとして指定することを意味しますが、この手順はブラウザーごとに根本的に異なる場合があります。 詳細については、ブラウザーのドキュメントを参照してください。

Mozillaブラウザは、起動と停止の方法が異なる場合があることに注意してください。 Mozillaブラウザの動作をもう少し予測可能にするために、MOZ\_NO\_REMOTE環境変数を設定する必要があるかもしれません。 Unixユーザーは、シェルスクリプトを使用してブラウザを起動しないでください。 一般に、バイナリ実行可能ファイル（firefox-binなど）を直接使用することをお勧めします。

## 一般的な問題のトラブルシューティング

Selenium RCの使用を開始すると、一般的に発生する可能性のある問題がいくつかあります。 ここでそれらとその解決策を紹介します。

### サーバーに接続できません

テストプログラムがSeleniumサーバーに接続できない場合、Seleniumはテストプログラムで例外をスローします。 このメッセージまたは同様のメッセージが表示されるはずです。

```bash
    "Unable to connect to remote server (Inner Exception Message: 
	No connection could be made because the target machine actively 
	refused it )"
    
	(using .NET and XP Service Pack 2) 
```

このようなメッセージが表示された場合は、必ずSeleniumサーバーを起動してください。 その場合、SeleniumクライアントライブラリとSeleniumサーバー間の接続に問題があります。

Selenium RCを使用する場合、ほとんどの人は、同じマシンでテストプログラム（Seleniumクライアントライブラリを使用）とSeleniumサーバーを実行することから始めます。 これを行うには、接続パラメーターとして"localhost"を使用します。 開始する潜在的なネットワークの問題の影響を軽減するため、この方法で開始することをお勧めします。 オペレーティングシステムに一般的なネットワーク設定とTCP/IP設定があると仮定すると、ほとんど問題はありません。 実際、多くの人がこの方法でテストを実行することを選択します。

ただし、リモートマシンでSeleniumサーバーを実行する場合は、2台のマシン間に有効なTCP/IP接続があると仮定すると、接続は良好です。

接続に問題がある場合は、 *ping* 、*telnet* 、 *ifconfig(Unix)/ipconfig(Windows)* などの一般的なネットワークツールを使用して、有効なネットワーク接続を確保できます。 これらに不慣れな場合は、システム管理者が支援できます。

### ブラウザをロードできません

わかりやすいエラーメッセージではありません。 申し訳ありませんが、Seleniumサーバーがブラウザをロードできない場合、このエラーが表示される可能性があります。

```bash
    (500) Internal Server Error
```

```bash
    Error:  java.lang.RuntimeException: Firefox refused shutdown while 
    preparing a profile 
```

サーバーからの完全なエラーメッセージを次に示します。

```bash
    16:20:03.919 INFO - Preparing Firefox profile... 
    16:20:27.822 WARN - GET /selenium-server/driver/?cmd=getNewBrowserSession&1=*fir 
    efox&2=http%3a%2f%2fsage-webapp1.qa.idc.com HTTP/1.1 
    java.lang.RuntimeException: Firefox refused shutdown while preparing a profile 
            at org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLaunc 
    her.waitForFullProfileToBeCreated(FirefoxCustomProfileLauncher.java:277) 
    ... 
    Caused by: org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLaunc 
    her$FileLockRemainedException: Lock file still present! C:\DOCUME~1\jsvec\LOCALS 
    ~1\Temp\customProfileDir203138\parent.lock 
```

これを解決するには、個別のFirefoxプロファイルの指定に関するセクションを参照してください。

### バージョン管理の問題

Seleniumのバージョンがブラウザのバージョンをサポートしていることを確認してください。 たとえば、Selenium RC 0.92はFirefox 3をサポートしていません。 時には幸運かもしれません（私はそうでした）。 ただし、使用しているSeleniumのバージョンでサポートされているブラウザのバージョンを確認することを忘れないでください。 疑わしい場合は、ブラウザの最も広く使用されているバージョンでSeleniumの最新リリースバージョンを使用してください。

### サーバーの起動中のエラーメッセージ： “(Unsupported major.minor version 49.0)”

このエラーは、正しいバージョンのJavaを使用していないことを示しています。 Selenium ServerにはJava 1.5以降が必要です。

Javaバージョンを再確認するには、コマンドラインからこれを実行します。

```bash
   java -version
```

Javaバージョンを示すメッセージが表示されます。

```bash
   java version "1.5.0_07"
   Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03)
   Java HotSpot(TM) Client VM (build 1.5.0_07-b03, mixed mode)
```

```bash
   cmd=getNewBrowserSession&1=*firefox /usr/local/firefox/firefox-bin&2=http://www.google.com
```

```bash
   /usr/lib/firefox-x.x.x/ 
```

x.x.xは現在使用しているバージョン番号です。 そのため、そのパスをユーザーのパスに追加します。 以下を.bashrcファイルに追加する必要があります。

```bash
   export PATH="$PATH:/usr/lib/firefox-x.x.x/"
```

必要に応じて、次のようにテストで直接firefox-binへのパスを指定できます。

```bash
   "*firefox /usr/lib/firefox-x.x.x/firefox-bin"
```

### IEおよびスタイル属性

Internet Explorerでテストを実行していて、style属性を使用して要素を見つけられない場合、例えば、次のような場合があります。

```bash
    //td[@style="background-color:yellow"]
```

これはFirefox、Opera、またはSafariで完全に機能しますが、IEでは機能しません。 IEは `@style` のキーを大文字として解釈します。 したがって、ソースコードが小文字であっても、下記のように使用したほうがよいです。

```bash
    //td[@style="BACKGROUND-COLOR:yellow"]
```

テストが複数のブラウザーで動作することを意図している場合、これは問題ですが、簡単にテストをコーディングして状況を検出し、IEでのみ動作する代替ロケーターを試すことができます。

### エラーが発生しました-\*googlechromeブラウザーのシャットダウン時に"Cannot convert object to primitive value”

このエラーを回避するには、同一オリジンポリシーチェックを無効にするオプションでブラウザを起動する必要があります。

```bash
   selenium.start("commandLineFlags=--disable-web-security");
```

### IEでエラーが発生しました - “Couldn’t open app window; is the pop-up blocker enabled?”

このエラーを回避するには、ブラウザを設定する必要があります。 ポップアップブロッカーを無効にし、ツール » オプション »セキュリティで’保護モードを有効にする’オプションをオフにします。

***

1. ブラウザーは、 localhost:4444 をHTTPプロキシーとして設定した構成プロファイルで起動されます。 これが、ブラウザーが行うHTTP要求がSeleniumサーバーを通過し、レスポンスが実サーバーからではなく通過する理由です。 [↩︎](#fnref:1)

2. プロキシは、2つの部分の間でボールを渡す中間の第三者です。 AUTをブラウザに配信する"Webサーバー"として機能します。 プロキシであるため、Seleniumサーバーはテスト対象アプリケーションの実際のURLについて"嘘をつく"機能を提供します。 [↩︎](#fnref:2)

# 2 - Selenium 2

Selenium 2 was a rewrite of Selenium 1 that was implemented with WebDriver code.

# 2.1 - RCからWebDriverへの移行

```java
Selenium selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.yoursite.com");
selenium.start();
```

これは次のように置き換える必要があります。

```java
WebDriver driver = new FirefoxDriver();
Selenium selenium = new WebDriverBackedSelenium(driver, "http://www.yoursite.com");
```

## 次のステップ

テストがエラーなしで実行されたら、次の段階は実際のテストコードを移行してWebDriver APIを使用することです。 コードがどれだけ適切に抽象化されているかによって、これは短いプロセスまたは長いプロセスになります。 どちらの場合でも、アプローチは同じであり、簡単に要約できます。 編集するときに新しいAPIを使用するようにコードを変更します。

基になるWebDriver実装をSeleniumインスタンスから抽出する必要がある場合は、WrapsDriverにキャストするだけです。

```java
WebDriver driver = ((WrapsDriver) selenium).getWrappedDriver();
```

これにより、通常どおりSeleniumインスタンスの受け渡しを続けることができますが、必要に応じてWebDriverインスタンスのラップを解除できます。

ある時点で、コードベースは主に新しいAPIを使用します。 この時点で、WebDriverを使用して関係を反転し、オンデマンドでSeleniumインスタンスをインスタンス化できます。

```java
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);
```

## 一般的な問題

幸いなことに、この移行を最初に行ったのはあなたではないので、他の人が経験した一般的な問題とその解決方法を以下に示します。

### クリックと入力がより完全に

Selenium RCテストの一般的なパターンは、以下のとおりです。

```java
selenium.type("name", "exciting tex");
selenium.keyDown("name", "t");
selenium.keyPress("name", "t");
selenium.keyUp("name", "t");
```

```java
Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(30));
WebElement element= wait.until(visibilityOfElementLocated(By.id("some_id")));
```

“visibilityOfElementLocated” は次のように実装されます。

```java
public ExpectedCondition<WebElement> visibilityOfElementLocated(final By locator) {
  return new ExpectedCondition<WebElement>() {
    public WebElement apply(WebDriver driver) {
      WebElement toReturn = driver.findElement(locator);
      if (toReturn.isDisplayed()) {
        return toReturn;
      }
      return null;
    }
  };
}
```

これは複雑に見えるかもしれませんが、ほとんどすべての定型コードです。 唯一の興味深い点は、 “apply” メソッドが “null” でもBoolean.FALSEでもないものを返すまで、 “ExpectedCondition” が繰り返し評価されることです。

もちろん、これらの “wait” 呼び出しをすべて追加すると、コードが混乱する可能性があります。 その場合で、ニーズが単純な場合は、暗黙的な待機の使用を検討してください。

```java
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
```

```java
String name = selenium.getEval(
    "selenium.browserbot.findElement('id=foo', browserbot.getCurrentWindow()).tagName");
```

このようになります。

```java
WebElement element = driver.findElement(By.id("foo"));
String name = (String) ((JavascriptExecutor) driver).executeScript(
    "return arguments[0].tagName", element);
```

渡された “element” 変数が、JS標準の “arguments” 配列の最初の項目としてどのように表示されるかに注目してください。

### Executing Javascript Doesn’t Return Anything

WebDriverのJavascriptExecutorは、すべてのJSをラップし、匿名式として評価します。 これは、 “return” キーワードを使用する必要があることを意味します。

```java
String title = selenium.getEval("browserbot.getCurrentWindow().document.title");
```

このようになります。

```java
((JavascriptExecutor) driver).executeScript("return document.title;");
```

# 2.2 - リモートWebDriverサーバー

サーバーは、テストするブラウザーがインストールされたマシンで常に実行されます。 サーバーは、コマンドラインから、またはコード設定を通じて使用できます。

## コマンドラインからサーバーを起動する

一旦、`selenium-server-standalone-{VERSION}.jar`をダウンロードしたら、テストしたいブラウザーのあるコンピューターに配置します。 次に、jarを含むディレクトリから、次のコマンドを実行します。

```shell
java -jar selenium-server-standalone-{VERSION}.jar
```

## サーバーを実行するにあたって考慮すること

呼び出し元は、`Selenium#stop()`または`WebDriver#quit`を呼び出して、各セッションを適切に終了すべきです。

selenium-serverは、進行中の各セッションのメモリ内ログを保持します。 これらのログは、`Selenium#stop()`または`WebDriver#quit`が呼び出されるとクリアされます。 これらのセッションの終了を忘れると、サーバーでメモリリークが発生する可能性があります。 非常に長時間実行されるセッションを維持する場合は、時々停止または終了する必要があります（または-Xmx jvmオプションでメモリを増やします）。

## タイムアウト (version 2.21以降)

サーバーには2つの異なるタイムアウトがあり、次のように設定できます。

```shell
java -jar selenium-server-standalone-{VERSION}.jar -timeout=20 -browserTimeout=60
```

```java
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.security.SslSocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;

import javax.servlet.Servlet;
import java.io.File;

import org.openqa.selenium.remote.server.DriverServlet;

public class AppServer {
  private Server server = new Server();

  public AppServer() throws Exception {
    WebAppContext context = new WebAppContext();
    context.setContextPath("");
    context.setWar(new File("."));
    server.addHandler(context);

    context.addServlet(DriverServlet.class, "/wd/*");

    SelectChannelConnector connector = new SelectChannelConnector();
    connector.setPort(3001);
    server.addConnector(connector);

    server.start();
  }
}
```

# 3 - Selenium 3

Selenium 3 was the implementation of WebDriver without the Selenium RC Code. It has since been replaced with Selenium 4, which implements the W3C WebDriver specification.

# 3.1 - Grid 3

Selenium Grid 3 supported WebDriver without Selenium RC code. Grid 3 was completely rewritten for the new Grid 4.

[Grid 4](https://www.selenium.dev/ja/documentation/grid/)

*Selenium Grid* は、SeleniumテストがコマンドをリモートWebブラウザーインスタンスにルーティングできるようにする賢いプロキシサーバーです。 その目的は、複数のマシンで並行してテストを実行する簡単な方法を提供することです。

Selenium Gridでは、1つのサーバーが、JSON形式のテストコマンドを1つ以上の登録済みのグリッドノードにルーティングするハブとして機能します。 テストはハブに接続して、リモートブラウザーインスタンスへのアクセスを取得します。 ハブには、アクセスを提供する登録済みサーバーのリストがあり、これらのインスタンスを制御できます。

Selenium Gridを使用すると、複数のマシンで並行してテストを実行し、さまざまなブラウザーバージョンとブラウザー構成を（個々のテストではなく）一元的に管理できます。

Selenium Gridは特効薬ではありません。 一般的な委譲および配布の問題のサブセットを解決しますが、たとえばインフラストラクチャを管理せず、特定のニーズに適さない場合があります。

# 3.2 - 独自のグリッドを設定する

```shell
java -jar selenium-server-standalone.jar -role hub
```

ハブはデフォルトでポート4444をリッスンします。 ブラウザーウィンドウを開いて <http://localhost:4444/grid/console> に移動すると、ハブのステータスを表示できます。

デフォルトのポートを変更するには、コマンドを実行するときにリッスンするポートを表す整数を持つオプションの `-port` フラグを追加できます。 また、JSON構成ファイル（以下を参照）に表示される他のすべてのオプションは、可能なコマンドラインフラグです。

確かに上記の簡単なコマンドだけでうまくいくことができますが、より高度な構成が必要な場合は、JSON形式の構成ファイルを指定して、開始時にハブを構成することもできます。 JSON形式の構成ファイルを指定して開始時にハブを構成する方法は以下のとおりです。

```shell
java -jar selenium-server-standalone.jar -role hub -hubConfig hubConfig.json -debug
```

以下に、 `hubConfig.json` ファイルの例を示します。 ステップ2でノード構成ファイルを提供する方法について詳しく説明します。

```json
{
  "_comment" : "Configuration for Hub - hubConfig.json",
  "host": ip,
  "maxSession": 5,
  "port": 4444,
  "cleanupCycle": 5000,
  "timeout": 300000,
  "newSessionWaitTimeout": -1,
  "servlets": [],
  "prioritizer": null,
  "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
  "throwOnCapabilityNotPresent": true,
  "nodePolling": 180000,
  "platform": "WINDOWS"}
```

### ステップ2：ノードを起動する

新しいWebDriver機能を備えたグリッドを実行するか、Selenium 1 RC機能を備えたグリッドを実行するか、または両方を同時に実行するかに関係なく、同じ `selenium-server-standalone.jar` ファイルを使用してノードを起動します。

```shell
java -jar selenium-server-standalone.jar -role node -hub http://localhost:4444
```

```shell
java -Dwebdriver.chrome.driver=chromedriver.exe -jar selenium-server-standalone.jar -role node -nodeConfig node1Config.json
```

そして、これは `nodeConfig.json` ファイルの例です。

```json
{
  "capabilities": [
    {
      "browserName": "firefox",
      "acceptSslCerts": true,
      "javascriptEnabled": true,
      "takesScreenshot": false,
      "firefox_profile": "",
      "browser-version": "27",
      "platform": "WINDOWS",
      "maxInstances": 5,
      "firefox_binary": "",
      "cleanSession": true
    },
    {
      "browserName": "chrome",
      "maxInstances": 5,
      "platform": "WINDOWS",
      "webdriver.chrome.driver": "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"
    },
    {
      "browserName": "internet explorer",
      "maxInstances": 1,
      "platform": "WINDOWS",
      "webdriver.ie.driver": "C:/Program Files (x86)/Internet Explorer/iexplore.exe"
    }
  ],
  "configuration": {
    "_comment" : "Configuration for Node",
    "cleanUpCycle": 2000,
    "timeout": 30000,
    "proxy": "org.openqa.grid.selenium.proxy.WebDriverRemoteProxy",
    "port": 5555,
    "host": ip,
    "register": true,
    "hubPort": 4444,
    "maxSession": 5
  }
}
```

```shell
java -jar selenium-server-standalone.jar -role hub -log log.txt
```

お気に入りのテキストエディターを使用してログファイル（上記の例ではlog.txt）を開き、問題が発生した場合に"エラー"ログを見つけます。

### `-debug` 引数を使用する

-debug引数を使用して、デバッグログをコンソールに出力することもできます。 `-debug` 引数を使用してSeleniumグリッドハブまたはノードを起動します。 以下の例をご覧ください。

```shell
java -jar selenium-server-standalone.jar -role hub -debug
```

# 3.3 - グリッドのコンポーネント


# 4 - レガシー Selenium IDE

```html
<tr>
    <td>Command</td>
    <td>target (locator)</td>
    <td>Value</td>
</tr>
```

|            |              |       |
| ---------- | ------------ | ----- |
| verifyText | //div//a\[2] | Login |

パラメーターは必ずしも必要ではありません。 コマンドに依存します。 両方のパラメータが必要な場合もあれば、1つのパラメータが必要な場合もあります。 また、コマンドがパラメータをまったく受け取らない場合もあります。 ここにいくつかの例があります。

|                   |             |                         |
| ----------------- | ----------- | ----------------------- |
| goBackAndWait     |             |                         |
| verifyTextPresent |             | Welcome to My Home Page |
| type              | id=phone    | (555) 666-7066          |
| type              | id=address1 | ${myVariableAddress}    |

```html
<table>
    <tr><td>open</td><td>/download/</td><td></td></tr>
    <tr><td>assertTitle</td><td></td><td>Downloads</td></tr>
    <tr><td>verifyText</td><td>//h2</td><td>Downloads</td></tr>
</table>
```

ブラウザでテーブルとしてレンダリングされると、次のようになります。

|             |            |           |
| ----------- | ---------- | --------- |
| open        | /download/ |           |
| assertTitle |            | Downloads |
| verifyText  | //h2       | Downloads |

The Selenese HTML syntax can be used to write and run tests without requiring knowledge of a programming language. With a basic knowledge of selenese and Selenium-IDE you can quickly produce and run testcases.

## テストスイート

テストスイートは、テストのコレクションです。 多くの場合、テストスイート内のすべてのテストを1つの連続バッチジョブとして実行します。

Selenium-IDEを使用する場合、テストスイートは単純なHTMLファイルを使用して定義することもできます。 構文も簡単です。 HTMLテーブルはテストのリストを定義し、各行は各テストへのファイルシステムパスを定義します。 例ですべてがわかります。

```html
<html>
<head>
<title>Test Suite Function Tests - Priority 1</title>
</head>
<body>
<table>
  <tr><td><b>Suite Of Tests</b></td></tr>
  <tr><td><a href="./Login.html">Login</a></td></tr>
  <tr><td><a href="./SearchValues.html">Test Searching for Values</a></td></tr>
  <tr><td><a href="./SaveValues.html">Test Save</a></td></tr>
</table>
</body>
</html>
```

| Command     | Target     | Value        |
| ----------- | ---------- | ------------ |
| open        | /download/ |              |
| assertTitle |            | Downloads    |
| verifyText  | //h2       | Downloads    |
| assertTable | 1.2.1      | Selenium IDE |
| verifyTable | 1.2.2      | June 3, 2008 |
| verifyTable | 1.2.3      | 1.0 beta 2   |

上記の例では、最初にページを開き、次にタイトルを期待値と比較することで正しいページがロードされることを“アサート”します。 これが成功した場合にのみ、次のコマンドが実行され、テキストが予想される場所に存在することを“検証”します。 テストケースは、最初のテーブルの2行目の最初の列に期待値が含まれていることを“アサート”します。 これに合格した場合にのみ、その行の残りのセルが“検証”されます。

### **verifyTextPresent**

`verifyTextPresent` コマンドは、 特定のテキストがページ上のどこかに存在することを検証するのに使います。 このコマンドは引数を 1 つだけ取ります。 引数には、検証するテキストのパターンを指定します。 次に例を示します。

| Command           | Target             | Value |
| ----------------- | ------------------ | ----- |
| verifyTextPresent | Marketing Analysis |       |

この例では、現在テストの対象になっているページ上で “Marketing Analysis” というテキスト文字列を探し、この文字列がページ上のどこかにあるかどうかを検証します。 verifyTextPresent コマンドは、テキストそれ自体がページ上に存在するかどうかだけを調べるときに使います。 テキストがページ上に現れる場所もテストの対象に含める必要がある場合には、このコマンドは使わないでください。

### **verifyElementPresent**

このコマンドは、特定の UI 要素について、その内容ではなく、要素の存在自体をチェックするのに使います。 具体的にはテキストはチェックせず、HTML タグだけをチェックします。 一般的な使い方として、画像が存在するかどうかのチェックなどがあります。

| Command              | Target      | Value |
| -------------------- | ----------- | ----- |
| verifyElementPresent | //div/p/img |       |

この例では、\<img> HTML タグの存在によって指定される画像が、ページ上に存在するかどうか、そして \<img> タグが \<div> タグと \<p> タグに続いて出現するかどうかを検証しています。 最初の (1 つだけの) パラメータは、要素を探す方法を Selenese コマンドに指示するための ロケータ です。 ロケータについては、次のセクションで説明します。

`verifyElementPresent`を使用して、ページ内のHTMLタグの存在を確認できます。 リンク、段落、分割 \<div>などの存在を確認できます。 さらにいくつかの例を示します。

| Command              | Target                        | Value |
| -------------------- | ----------------------------- | ----- |
| verifyElementPresent | //div/p                       |       |
| verifyElementPresent | //div/a                       |       |
| verifyElementPresent | id=Login                      |       |
| verifyElementPresent | link=Go to Marketing Research |       |
| verifyElementPresent | //a\[2]                       |       |
| verifyElementPresent | //head/title                  |       |

これらの例は、UI要素をテストするさまざまな方法を示しています。 繰り返しになりますが、ロケータについては次のセクションで説明します。

### **verifyText**

テキストとそのUI要素の両方をテストする必要がある場合は、`verifyText`を使用します。 verifyTextはロケーターを使用する必要があります。 *XPath* ロケーターまたは *DOM* ロケーターを選択した場合、特定のテキストが、ページ上のほかの UI コンポーネントとの相対位置で指定される特定の場所に出現するかどうかを検証できます。

| Command    | Target              | Value                                                               |
| ---------- | ------------------- | ------------------------------------------------------------------- |
| verifyText | //table/tr/td/div/p | This is my text and it occurs right after the div inside the table. |

## 要素の特定

多くの Selenium コマンドでは、対象を指定する必要があります。 この対象は、Web アプリケーションのコンテキスト内で要素を特定するためのもので、ロケーションストラテジーに続けて、 `locatorType=location` の形でロケーションを指定します。 多くの場合、ロケーションのタイプは省略できます。 ロケーションのタイプについては、以下で例を挙げながら説明します。

### 識別子による特定

この方法は、要素を特定する方法としておそらく最も一般的で、ロケータタイプとして認識されるものが使われていない場合の汎用デフォルトです。 このストラテジーでは、id 属性を持つ要素のうち、ロケーションに一致する最初の要素が使われます。 id 属性に一致する要素がない場合には、name 属性を持つ要素のうち、ロケーションに一致する最初の要素が使われます。

たとえば、ページソースに次のような id 属性と name 属性があったとします。

```html
  <html>
   <body>
    <form id="loginForm">
     <input name="username" type="text" />
     <input name="password" type="password" />
     <input name="continue" type="submit" value="Login" />
    </form>
   </body>
  <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
    </body>
   <html>
```

* `id=loginForm` (3)

### Nameによる特定

name ロケータタイプは、name 属性に一致する最初の要素を特定します。 1つの name 属性に対して、複数の要素が同じ値を持っている場合には、フィルタを使ってロケーションストラテジーの精度を高めることができます。 デフォルトのフィルタタイプは value です (value 属性に一致)。

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
  <html>
   <body>
    <p>Are you sure you want to do this?</p>
    <a href="continue.html">Continue</a> 
    <a href="cancel.html">Cancel</a>
  </body>
  <html>
```

* `link=Continue` (4)
* `link=Cancel` (5)

### DOMによる特定

ドキュメントオブジェクトモデルはHTMLドキュメントを表し、JavaScriptを使用してアクセスできます。 このロケーションストラテジーでは、ページ上の要素に評価される JavaScript を使用します。 単に階層型ドット記法を使って要素の位置を特定できます。

“document” で始まるのは `dom` ロケーターだけなので、DOMロケーターを指定するときに `dom=` ラベルを含める必要はありません。

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input class="required" name="username" type="text" />
      <input class="required passfield" name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | glob:\*Film\*Television\*             |       |

リンクをクリックして表示されるページの実際のタイトルは “De Anza Film And Television Department - Menu” でした。正確に一致するテキストではなく、パターンを使うと、ページのタイトルに “Film” と “Television” の 2 つの単語が (この順序で) 出現する限り、 `verifyTitle` はパスします。 たとえば、ページのオーナーがタイトルを短縮して “Film & Television Department” としても、テストはパスします。リンクとリンクが動作するかどうかのテスト (上の例では `verifyTitle`) との両方でパターンを使うことで、こうしたテストケースの保守の手間を大幅に減らすことができます。

#### 正規表現パターン

*正規表現* パターンは、Selenese がサポートしている 3 種類のパターンの中で最も強力です。 正規表現はほとんどの高水準プログラミング言語、多くのテキストエディタ、さらに Linux/Unix のコマンドラインユーティリティである **grep** や **sed** 、 **awk** など、さまざまなツールでもサポートされています。 Selenese では、正規表現パターンを使うと、それ以外の方法では実現が難しい数多くのタスクを実行することができます。 たとえば、テーブルの特定のセルに入力されているのが数字だけかどうかをテストする必要があるとします。 この場合、 `regexp: [0-9]+` と指定するだけで、任意の長さの数字に一致させることができます。

Selenese のグロビングパターンでサポートしているのは **\*** と **\[ ]** (文字クラス) だけですが、Selenese の正規表現パターンでは JavaScript に存在するものと同じ幅広い特殊文字を使用できます。 次に示すのは、これらの特殊文字です。

| PATTERN | MATCH                                                                            |
| ------- | -------------------------------------------------------------------------------- |
| .       | any single character                                                             |
| \[ ]    | character class: any single character that appears inside the brackets           |
| \*      | quantifier: 0 or more of the preceding character (or group)                      |
| +       | quantifier: 1 or more of the preceding character (or group)                      |
| ?       | quantifier: 0 or 1 of the preceding character (or group)                         |
| {1,5}   | quantifier: 1 through 5 of the preceding character (or group)                    |
| \|      | alternation: the character/group on the left or the character/group on the right |
| ( )     | grouping: often used with alternation and/or quantifier                          |

Selenese の正規表現パターンでは、先頭に `regexp:` または `regexpi:` を付ける必要があります。 前者は大文字と小文字を区別しますが、後者は大文字と小文字を区別しません。

Selenese コマンドでの正規表現パターンの使い方については、いくつか実例を挙げた方がわかりやすいでしょう。 最初の例は、おそらく最もよく使われる正規表現である **.\*** (“ドットスター”) を使ったものです。 この 2 文字の並びは、「任意の文字の 0 回以上の繰り返し」、もっとかみくだいて言えば、「すべて、または何もない」ものに一致します。1 文字のグロビングパターンで **\*** (アスタリスク 1 つ) と指定するのと等価です。

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | regexp:.\*Film.\*Television.\*        |       |

上のテスト例は、すでに示したグロビングパターンを使ったテストの例と機能的には同じです。 違いは、プリフィックス (**glob:** の代わりに **regexp:** が使われていること) と、「すべて、または何もない」パターンが指定されていること ( **\*** の代わりに **.\*** が使われていること) だけです。

次に示すのは、アラスカ州アンカレジの日の出時刻に関する情報が掲載されている Yahoo! Weather のページを対象としたもう少し複雑なテスト例です。

| Command           | Target                                            | Value |
| ----------------- | ------------------------------------------------- | ----- |
| open              | <http://weather.yahoo.com/forecast/USAK0012.html> |       |
| verifyTextPresent | regexp:Sunrise: \*\[0-9]{1,2}:\[0-9]{2} \[ap]m    |       |

上の例で使われている正規表現を 1 つずつ見てみましょう。

|              |                                       |
| ------------ | ------------------------------------- |
| `Sunrise: *` | **Sunrise:** という文字列とそれに続く 0 個以上の空白    |
| `[0-9]{1,2}` | 1 個または 2 個の数字 (時間を表す)                 |
| `:`          | 文字 : そのもの (特殊文字は使われていない)              |
| `[0-9]{2}`   | 2 個の数字 (分を表す) とそれに続く 1 個の空白           |
| `[ap]m`      | 文字 “a” または “p” とそれに続く “m” (am または pm) |

#### 完全一致

Selenium の **完全一致** パターンは、それほど使う機会はないでしょう。 完全一致パターンでは、特殊文字は一切使いません。 したがって、(グロビングパターンと正規表現パターンでは特別な意味を持つ) アスタリスク文字を検索する必要がある場合には、完全一致パターンを使うのも 1 つの方法です。 たとえば、ドロップダウンリストで “Real \*” というラベルの付いた項目を選択する場合、次のようなコードでは、期待どおりに動作する場合もそうでない場合もあります。 `glob:Real *`パターンに含まれるアスタリスクは、「すべて、または何もない」ものに一致します。 したがって、目的の select のオプションより前に “Real Numbers” というラベルの付いたオプションがあれば、それが選択され、目的の “Real \*” というオプションは選択されないことになります。

| Command | Target   | Value        |
| ------- | -------- | ------------ |
| select  | //select | glob:Real \* |

項目 “Real \*” が確実に選択されるようにするには、 `exact:` プリフィックスを使って次のように **完全一致** パターンを指定します。

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| select  | //select | exact:Real \* |

ただし、正規表現パターンで次のようにアスタリスクをエスケープしても同じ結果が得られます。

| Command | Target   | Value            |
| ------- | -------- | ---------------- |
| select  | //select | regexp:Real \\\* |

| Command | Target            | Value |
| ------- | ----------------- | ----- |
| store   | <paul@mysite.org> |       |

上のように記述すると、スクリプトのあとの方で、変数に格納された値を利用できます。 変数の値にアクセスするには、次に示すように、変数をブレース ({}) で囲み、先頭にドル記号を付けます。

| Command    | Target  | Value         |
| ---------- | ------- | ------------- |
| verifyText | //div/p | \\${userName} |

変数の一般的な使い方の 1 つに、入力フィールドへの入力を格納する操作があります。

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| type    | id=login | \\${userName} |

| Command         | Target                                         | Value       |
| --------------- | ---------------------------------------------- | ----------- |
| store           | 10                                             | hits        |
| storeXpathCount | //blockquote                                   | blockquotes |
| storeEval       | storedVars\[‘hits’].storedVars\[‘blockquotes’] | paragraphs  |

次に示すのは、JavaScript コードの断片でメソッドを呼び出す例です。 この例では、JavaScript String オブジェクトの `toUpperCase` メソッドと `toLowerCase` メソッドを呼び出しています。

| Command   | Target                            | Value |
| --------- | --------------------------------- | ----- |
| store     | Edith Wharton                     | name  |
| storeEval | storedVars\[’name’].toUpperCase() | uc    |
| storeEval | storedVars\[’name’].toUpperCase() | lc    |

#### 非スクリプトパラメータでの JavaScript の使用

コマンドが取るパラメータの種類が **スクリプト** ではない場合でも、パラメータに使う値を JavaScript を使って生成することができます。 ただし、この場合には特別な構文が必要になり、JavaScript コードの断片をブレースで囲み、その前にラベル javascript を付ける必要があります。 具体的には、 `javascript {*ここにコードを記述*}` のように指定します。 次に示すのは、 `type` コマンドの 2 番目のパラメータ `value` を、特別な構文を使って JavaScript コードから生成する例です。

| Command | Target            | Value                                                 |
| ------- | ----------------- | ----------------------------------------------------- |
| store   | league of nations | searchString                                          |
| type    | q                 | javascript{storedVars\[‘searchString’].toUpperCase()} |

## *echo* - Selenese の Print コマンド

Selenese には、テスト出力にテキストを書き込むことができる簡単なコマンドが用意されています。 このコマンドを使うと、テストの実行中に進捗状況を示す情報をコンソールに表示できるので便利です。 これらの情報を使えば、テスト結果のレポートに実行時の状況を埋め込むこともできるので、テストで問題が見つかったときに、ページ上のどこにバグがあるのか探すのに役立ちます。 また、echo 文を使うと、Selenium 変数の内容を出力できます。次に例を示します。

| Command | Target                    | Value |
| ------- | ------------------------- | ----- |
| echo    | Testing page footer now.  |       |
| echo    | Username is \\${userName} |       |

## 警告、ポップアップ、および複数のウィンドウ

次のようなページをテストしているとします。

```html
  <!DOCTYPE HTML>
  <html>
  <head>
    <script type="text/javascript">
      function output(resultText){
        document.getElementById('output').childNodes[0].nodeValue=resultText;
      }

      function show_confirm(){
        var confirmation=confirm("Chose an option.");
        if (confirmation==true){
          output("Confirmed.");
        }
        else{
          output("Rejected!");
        }
      }
      
      function show_alert(){
        alert("I'm blocking!");
        output("Alert is gone.");
      }
      function show_prompt(){
        var response = prompt("What's the best web QA tool?","Selenium");
        output(response);
      }
      function open_window(windowName){
        window.open("newWindow.html",windowName);
      }
      </script>
  </head>
  <body>

    <input type="button" id="btnConfirm" onclick="show_confirm()" value="Show confirm box" />
    <input type="button" id="btnAlert" onclick="show_alert()" value="Show alert" />
    <input type="button" id="btnPrompt" onclick="show_prompt()" value="Show prompt" />
    <a href="newWindow.html" id="lnkNewWindow" target="_blank">New Window Link</a>
    <input type="button" id="btnNewNamelessWindow" onclick="open_window()" value="Open Nameless Window" />
    <input type="button" id="btnNewNamedWindow" onclick="open_window('Mike')" value="Open Named Window" />

    <br />
    <span id="output">
    </span>
  </body>
  </html>
```

ユーザーは、アラート/確認ボックスに応答するとともに、新しく開いたポップアップウィンドウにフォーカスを移動する必要があります。 幸いなことに、SeleniumはJavaScriptポップアップをカバーできます。

ただし、アラート/確認/プロンプトを個別に詳細に説明する前に、それらの共通点を理解しておくと役立ちます。 アラート、確認ボックス、プロンプトにはすべて次のバリエーションがあります。

| Command                   | Description                          |
| ------------------------- | ------------------------------------ |
| assertFoo(pattern)        | パターンがポップアップのテキストと一致しない場合、エラーをスローします  |
| assertFooPresent          | ポップアップが利用できない場合はエラーをスローします           |
| assertFooNotPresent       | ポップアップが存在する場合、エラーをスローします             |
| storeFoo(variable)        | ポップアップのテキストを変数に保存します                 |
| storeFooPresent(variable) | ポップアップのテキストを変数に保存し、trueまたはfalseを返します |

Seleniumで実行している場合、JavaScriptポップアップは表示されません。 これは、関数呼び出しが実行時に実際にSeleniumのJavaScriptによってオーバーライドされるためです。 ただし、ポップアップが表示されないからといって、ポップアップを処理する必要はありません。 ポップアップを処理するには、その `assertFoo(pattern)` 関数を呼び出す必要があります。 ポップアップの存在をアサートしないと、次のコマンドがブロックされ、次のようなエラーが表示されます。 `[エラー]エラー：予期しない確認がありました！ [オプションを選択してください。]`

### アラート

アラートは処理が最も簡単なポップアップなので、始めましょう。 まず、ブラウザで上記のHTMLサンプルを開き、“Show alert” ボタンをクリックします。 アラートを閉じると、“Alert is gone.” というテキストが表示されます。 ページに表示されます。 次に、Selenium IDE記録で同じ手順を実行し、アラートを閉じた後にテキストが追加されたことを確認します。 テストは次のようになります。

| Command           | Target         | Value |
| ----------------- | -------------- | ----- |
| open              | /              |       |
| click             | btnAlert       |       |
| assertAlert       | I’m blocking!  |       |
| verifyTextPresent | Alert is gone. |       |

あなたは「それはおかしい、私はそのアラートをアサートしようとしたことはない」と考えているかもしれません。 ただし、これはSelenium-IDEの処理であり、アラートを閉じます。 そのステップを削除してテストを再生すると、次のエラーが表示されます `[エラー]エラー：予期しないアラートがありました！ [I'm blocking!]` 。 アラートの存在を確認するには、アラートのアサーションを含める必要があります。

アラートが存在することをアサートしたいが、アラートに含まれるテキストがわからないか気にする必要がない場合は、`assertAlertPresent`を使うことができます。 これはtrueまたはfalseを返し、falseはテストを停止します。

### 確認

確認はアラートとほぼ同じように動作し、 `assertConfirmation` と `assertConfirmationPresent` は対応するアラートと同じ特性を提供します。 ただし、デフォルトでは、確認が表示されたときにSeleniumはOKを選択します。 サンプルページの"確認ダイアログを表示"ボタンをクリックして記録を試みますが、ポップアップの"キャンセル"ボタンをクリックして、出力テキストをアサートします。 テストは次のようになります。

| Command                        | Target            | Value |
| ------------------------------ | ----------------- | ----- |
| open                           | /                 |       |
| click                          | btnConfirm        |       |
| chooseCancelOnNextConfirmation |                   |       |
| assertConfirmation             | Choose an option. |       |
| verifyTextPresent              | Rejected          |       |

`chooseCancelOnNextConfirmation` 関数は、後続のすべての確認がfalseを返すことをSeleniumに伝えます。 chooseOkOnNextConfirmationを呼び出すことでリセットできます。

Seleniumは未処理の確認があると苦情を言うので、このテストを再生できないことに気付くかもしれません。 これは、Selenium-IDEが記録するイベントの順序により、クリックしてchooseCancelOnNextConfirmationが間違った順序になるためです（考えてみれば、Seleniumは、確認を開く前にキャンセルしていることを知ることができません）。 これら2つのコマンドを切り替えると、テストは正常に実行されます。

### プロンプト

プロンプトは、`assertPrompt` および `assertPromptPresent` が対応するアラートと同じ特性を提供することで、アラートとほぼ同じように動作します。 デフォルトでは、Seleniumはプロンプトがポップアップしたときにデータの入力を待機します。 サンプルページの “Show prompt” ボタンをクリックして記録を試み、プロンプトに “Selenium” と入力します。 テストは次のようになります。

| Command            | Target                       | Value |
| ------------------ | ---------------------------- | ----- |
| open               | /                            |       |
| answerOnNextPrompt | Selenium!                    |       |
| click              | id=btnPrompt                 |       |
| assertPrompt       | What’s the best web QA tool? |       |
| verifyTextPresent  | Selenium!                    |       |

```html
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Sample Selenium Test Suite</title>
    </head>
    <body>
        <table cellpadding="1" cellspacing="1" border="1">
            <thead>
                <tr><td>Test Cases for De Anza A-Z Directory Links</td></tr>
            </thead>
        <tbody>
            <tr><td><a href="./a.html">A Links</a></td></tr>
            <tr><td><a href="./b.html">B Links</a></td></tr>
            <tr><td><a href="./c.html">C Links</a></td></tr>
            <tr><td><a href="./d.html">D Links</a></td></tr>
        </tbody>
        </table>
    </body>
</html>
```

***

*error loading test case: no command found*

「ファイル」メニューの「開く」を使用して、テストスイートファイルを開こうとしました。 代わりに「ファイル」メニューの「テストスイートを開く」を使用してください。

このエラーメッセージを改善するために、機能の拡張がリクエストされました。 詳細は、[issue 1010](http://code.google.com/p/selenium/issues/detail?id=1010)を参照してください。

***

このタイプの **エラー** は、タイミングの問題を示している可能性があります。 つまり、コマンドのロケーターによって指定された要素が、コマンドの実行時に完全にロードされていません。 コマンドの前に **pause 5000** を入れて、問題が本当にタイミングに関連しているかどうかを判断してください。 その場合、失敗したコマンドの前に適切な **waitFor\*** または **\*AndWait** コマンドを使って調査してください。

***

上記の **open** コマンドの場合のように変数置換を使用しようとして失敗した場合は、アクセスしようとしている値を持つ変数を実際に作成していないことを示します。 これは、変数を **Target** フィールドに配置する必要がある場合に **Value** フィールドに配置するか、その逆の場合があります。 上記の例では、storeコマンドの2つのパラメーターが、必要なものと逆の順序で誤って配置されています。 Seleneseコマンドの場合、最初の必須パラメーターは **Target** フィールドに入力し、2番目の必須パラメーター（存在する場合）は **Value** フィールドに入力する必要があります。

***

*error loading test case: \[Exception… “Component returned failure code: 0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND) \[nsIFileInputStream.init]” nresult: “0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND)” location: “JS frame :: chrome://selenium-ide/content/file-utils.js :: anonymous :: line 48” data: no]*

テストスイートのテストケースの1つが見つかりません。 テストケースが配置されていることを示すテストスイートが実際に配置されていることを確認してください。 また、実際のテストケースファイルのファイル名と参照先のテストスイートファイルの両方に.html拡張子が付いていることを確認してください。

このエラーメッセージを改善するために、機能の拡張がリクエストされました。 詳細は、[issue 1011](http://code.google.com/p/selenium/issues/detail?id=1011)を参照してください。

***

拡張ファイルの内容が、Selenium-IDEによって読み取られていません。 Selenium-IDE の *“オプション” メニューで “設定” をクリックし、 “一般” タブ* の **Selenium Core 拡張スクリプト (user-extension.js) のパス** フィールドに適切なパス名を指定していることを確認してください。 また、 **Selenium Core 拡張スクリプト (user-extension.js) のパス** フィールドの内容を変更した後は、Selenium-IDEを再起動する必要があります。

# 4.1 - HTMLランナー

```shell
[user@localhost ~]$ cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

[user@localhost ~]$ rpm -qa | egrep -i "xvfb|java-1.8|firefox"
xorg-x11-server-Xvfb-1.19.3-11.el7.x86_64
firefox-52.4.0-1.el7.centos.x86_64
java-1.8.0-openjdk-1.8.0.151-1.b12.el7_4.x86_64
java-1.8.0-openjdk-headless-1.8.0.151-1.b12.el7_4.x86_64
```

テストスイートの例

```html
[user@localhost ~]$ cat testsuite.html
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
  <title>Test Suite</title>
</head>
<body>
<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium"><tbody>
<tr><td><b>Test Suite</b></td></tr>
<tr><td><a href="YOUR-TEST-SCENARIO.html">YOUR-TEST-SCENARIO</a></td></tr>
</tbody></table>
</body>
</html>
```

## selenium-html-runnerをヘッドレスで実行する方法

さて、最も重要な部分、selenium-html-runnerの実行方法の例！ 経験によってソフトウェアの組み合わせ、- geckodriver / FF / html-runnerリリースによって異なる場合があります。

```shell
xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
```

```shell
[user@localhost ~]$ xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "*firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
Multi-window mode is longer used as an option and will be ignored.
1510061109691   geckodriver     INFO    geckodriver 0.18.0
1510061109708   geckodriver     INFO    Listening on 127.0.0.1:2885
1510061110162   geckodriver::marionette INFO    Starting browser /usr/bin/firefox with args ["-marionette"]
1510061111084   Marionette      INFO    Listening on port 43229
1510061111187   Marionette      WARN    TLS certificate errors will be ignored for this session
Nov 07, 2017 1:25:12 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
2017-11-07 13:25:12.714:INFO::main: Logging initialized @3915ms to org.seleniumhq.jetty9.util.log.StdErrLog
2017-11-07 13:25:12.804:INFO:osjs.Server:main: jetty-9.4.z-SNAPSHOT
2017-11-07 13:25:12.822:INFO:osjsh.ContextHandler:main: Started o.s.j.s.h.ContextHandler@87a85e1{/tests,null,AVAILABLE}
2017-11-07 13:25:12.843:INFO:osjs.AbstractConnector:main: Started ServerConnector@52102734{HTTP/1.1,[http/1.1]}{0.0.0.0:31892}
2017-11-07 13:25:12.843:INFO:osjs.Server:main: Started @4045ms
Nov 07, 2017 1:25:13 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |open | /auth_mellon.php |  |
Nov 07, 2017 1:25:14 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |waitForPageToLoad | 3000 |  |
.
.
.etc

<td>result:</td>
<td>PASS</td>
```

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/discouraged/link_spidering/
----

# 爬取链接

建议您不要使用WebDriver来通过链接进行爬网， 并非因为无法完成，而是因为它绝对不是最理想的工具。 WebDriver需要一些时间来启动，并且可能要花几秒钟到一分钟的时间， 具体取决于测试的编写方式，仅仅是为了获取页面并遍历DOM.

除了使用WebDriver之外， 您还可以通过执行 [curl](https://curl.se/) 命令或 使用诸如BeautifulSoup之类的库来节省大量时间， 因为这些方法不依赖于创建浏览器和导航至页面. 通过不使用WebDriver可以节省大量时间.

----
url: https://www.selenium.dev/documentation/grid/advanced_features/observability/
----

# Observability in Selenium Grid

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar standalone --log-level FINE
```

2. Jaeger UI - OpenTelemetry provides the APIs and SDKs to instrument traces in the code. Whereas Jaeger is a tracing backend, that aids in collecting the tracing telemetry data and providing querying, filtering and visualizing features for the data.

Detailed instructions of visualizing traces using Jaeger UI can be obtained by running the command :

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar info tracing
```

[A very good example and scripts to run the server and send traces to Jaeger](https://github.com/manoj9788/tracing-selenium-grid)

## Leveraging event logs

Tracing has to be enabled for event logging as well, even if one does not wish to export traces to visualize them.\
**By default, tracing is enabled. No additional parameters need to be passed to see logs on the console.** All events within a span are logged at FINE level. Error events are logged at WARN level.

All event logs have the following fields :

| Field            | Field value     | Description                                                                                                                                                                            |
| ---------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Event time       | eventId         | Timestamp of the event record in epoch nanoseconds.                                                                                                                                    |
| Trace Id         | tracedId        | Each trace is uniquely identified by a trace id.                                                                                                                                       |
| Span Id          | spanId          | Each span within a trace is uniquely identified by a span id.                                                                                                                          |
| Span Kind        | spanKind        | Span kind is a property of span indicating the type of span. It helps in understanding the nature of the unit of work done by the Span.                                                |
| Event name       | eventName       | This maps to the log message.                                                                                                                                                          |
| Event attributes | eventAttributes | This forms the crux of the event logs, based on the operation executed, it has JSON formatted key-value pairs. This also includes a handler class attribute, to show the logger class. |

Sample log

```
FINE [LoggingOptions$1.lambda$export$1] - {
  "traceId": "fc8aef1d44b3cc8bc09eb8e581c4a8eb",
  "spanId": "b7d3b9865d3ddd45",
  "spanKind": "INTERNAL",
  "eventTime": 1597819675128886121,
  "eventName": "Session request execution complete",
  "attributes": {
    "http.status_code": 200,
    "http.handler_class": "org.openqa.selenium.grid.router.HandleSession",
    "http.url": "\u002fsession\u002fdd35257f104bb43fdfb06242953f4c85",
    "http.method": "DELETE",
    "session.id": "dd35257f104bb43fdfb06242953f4c85"
  }
}
```

In addition to the above fields, based on [OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/exceptions.md) error logs consist of :

| Field                | Field value          | Description                                                                                                                   |
| -------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Exception type       | exception.type       | The class name of the exception.                                                                                              |
| Exception message    | exception.message    | Reason for the exception.                                                                                                     |
| Exception stacktrace | exception.stacktrace | Prints the call stack at the point of time when the exception was thrown. Helps in understanding the origin of the exception. |

Sample error log

```
WARN [LoggingOptions$1.lambda$export$1] - {
  "traceId": "7efa5ea57e02f89cdf8de586fe09f564",
  "spanId": "914df6bc9a1f6e2b",
  "spanKind": "INTERNAL",
  "eventTime": 1597820253450580272,
  "eventName": "exception",
  "attributes": {
    "exception.type": "org.openqa.selenium.ScriptTimeoutException",
    "exception.message": "Unable to execute request: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist ..." (full message will be printed),
    "exception.stacktrace": "org.openqa.selenium.ScriptTimeoutException: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist\nBuild info: version: '4.0.0-alpha-7', revision: 'Unknown'\nSystem info: host: 'XYZ-MacBook-Pro.local', ip: 'fe80:0:0:0:10d5:b63a:bdc6:1aff%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.7'\nDriver info: driver.version: unknown ...." (full stack will be printed),
    "http.handler_class": "org.openqa.selenium.grid.distributor.remote.RemoteDistributor",
    "http.url": "\u002fsession",
    "http.method": "POST"
  }
}
```

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/browsers/
----

# Navegadores suportados

Cada navegador tem capacidades e características únicas.

***

##### [Funcionalidade específica do Chrome](/pt-br/documentation/webdriver/browsers/chrome/)

Estas capacidades e características são específicas ao navegador Google Chrome.

##### [Funcionalidade específica do Edge](/pt-br/documentation/webdriver/browsers/edge/)

Estas capacidades e características são específicas ao navegador Microsoft Edge.

##### [Funcionalidade específica do Firefox](/pt-br/documentation/webdriver/browsers/firefox/)

Estas capacidades e características são específicas ao navegador Mozilla Firefox.

##### [Funcionalidade específica do IE](/pt-br/documentation/webdriver/browsers/internet_explorer/)

Estas capacidades e características são específicas ao navegador Microsoft Internet Explorer.

##### [Funcionalidade específica do Safari](/pt-br/documentation/webdriver/browsers/safari/)

Estas capacidades e características são específicas ao navegador Apple Safari.

Última modificação November 3, 2022: [Translate Browser pages, closes #870 (#1211) (cf4fe36501b)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/cf4fe36501b15d161b7b8c93bee00ab24383df0b)

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/design_strategies/
----

# 设计模式和开发策略

```java
package com.example.webdriver;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class EditIssue {

  private final WebDriver driver;

  public EditIssue(WebDriver driver) {
    this.driver = driver;
  }

  public void setTitle(String title) {
    WebElement field = driver.findElement(By.id("issue_title")));
    clearAndType(field, title);
  }

  public void setBody(String body) {
    WebElement field = driver.findElement(By.id("issue_body"));
    clearAndType(field, body);
  }

  public void setHowToReproduce(String howToReproduce) {
    WebElement field = driver.findElement(By.id("issue_form_repro-command"));
    clearAndType(field, howToReproduce);
  }

  public void setLogOutput(String logOutput) {
    WebElement field = driver.findElement(By.id("issue_form_logs"));
    clearAndType(field, logOutput);
  }

  public void setOperatingSystem(String operatingSystem) {
    WebElement field = driver.findElement(By.id("issue_form_operating-system"));
    clearAndType(field, operatingSystem);
  }

  public void setSeleniumVersion(String seleniumVersion) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-version"));
    clearAndType(field, logOutput);
  }

  public void setBrowserVersion(String browserVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-versions"));
    clearAndType(field, browserVersion);
  }

  public void setDriverVersion(String driverVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-driver-versions"));
    clearAndType(field, driverVersion);
  }

  public void setUsingGrid(String usingGrid) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-grid-version"));
    clearAndType(field, usingGrid);
  }

  public IssueList submit() {
    driver.findElement(By.cssSelector("button[type='submit']")).click();
    return new IssueList(driver);
  }

  private void clearAndType(WebElement field, String text) {
    field.clear();
    field.sendKeys(text);
  }
}
```

In order to turn this into a LoadableComponent, all we need to do is to set that as the base type:

```java
public class EditIssue extends LoadableComponent<EditIssue> {
  // rest of class ignored for now
}
```

This signature looks a little unusual, but it all means is that this class represents a LoadableComponent that loads the EditIssue page.

By extending this base class, we need to implement two new methods:

```java
  @Override
  protected void load() {
    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();
    assertTrue("Not on the issue entry page: " + url, url.endsWith("/new"));
  }
```

The `load` method is used to navigate to the page, whilst the `isLoaded` method is used to determine whether we are on the right page. Although the method looks like it should return a boolean, instead it performs a series of assertions using JUnit’s Assert class. There can be as few or as many assertions as you like. By using these assertions it’s possible to give users of the class clear information that can be used to debug tests.

With a little rework, our PageObject looks like:

```java
package com.example.webdriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

import static junit.framework.Assert.assertTrue;

public class EditIssue extends LoadableComponent<EditIssue> {

  private final WebDriver driver;
  
  // By default the PageFactory will locate elements with the same name or id
  // as the field. Since the issue_title element has an id attribute of "issue_title"
  // we don't need any additional annotations.
  private WebElement issue_title;
  
  // But we'd prefer a different name in our code than "issue_body", so we use the
  // FindBy annotation to tell the PageFactory how to locate the element.
  @FindBy(id = "issue_body") private WebElement body;
  
  public EditIssue(WebDriver driver) {
    this.driver = driver;
    
    // This call sets the WebElement fields.
    PageFactory.initElements(driver, this);
  }

  @Override
  protected void load() {
    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();
    assertTrue("Not on the issue entry page: " + url, url.endsWith("/new"));
  }

  public void setHowToReproduce(String howToReproduce) {
    WebElement field = driver.findElement(By.id("issue_form_repro-command"));
    clearAndType(field, howToReproduce);
  }

  public void setLogOutput(String logOutput) {
    WebElement field = driver.findElement(By.id("issue_form_logs"));
    clearAndType(field, logOutput);
  }

  public void setOperatingSystem(String operatingSystem) {
    WebElement field = driver.findElement(By.id("issue_form_operating-system"));
    clearAndType(field, operatingSystem);
  }

  public void setSeleniumVersion(String seleniumVersion) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-version"));
    clearAndType(field, logOutput);
  }

  public void setBrowserVersion(String browserVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-versions"));
    clearAndType(field, browserVersion);
  }

  public void setDriverVersion(String driverVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-driver-versions"));
    clearAndType(field, driverVersion);
  }

  public void setUsingGrid(String usingGrid) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-grid-version"));
    clearAndType(field, usingGrid);
  }

  public IssueList submit() {
    driver.findElement(By.cssSelector("button[type='submit']")).click();
    return new IssueList(driver);
  }

  private void clearAndType(WebElement field, String text) {
    field.clear();
    field.sendKeys(text);
  }
}
```

That doesn’t seem to have bought us much, right? One thing it has done is encapsulate the information about how to navigate to the page into the page itself, meaning that this information’s not scattered through the code base. It also means that we can do this in our tests:

```java
EditIssue page = new EditIssue(driver).get();
```

This call will cause the driver to navigate to the page if that’s necessary.

### Nested Components

LoadableComponents start to become more useful when they are used in conjunction with other LoadableComponents. Using our example, we could view the “edit issue” page as a component within a project’s website (after all, we access it via a tab on that site). You also need to be logged in to file an issue. We could model this as a tree of nested components:

```
 + ProjectPage
 +---+ SecuredPage
     +---+ EditIssue
```

What would this look like in code? For a start, each logical component would have its own class. The “load” method in each of them would “get” the parent. The end result, in addition to the EditIssue class above is:

ProjectPage.java:

```java
package com.example.webdriver;

import org.openqa.selenium.WebDriver;

import static org.junit.Assert.assertTrue;

public class ProjectPage extends LoadableComponent<ProjectPage> {

  private final WebDriver driver;
  private final String projectName;

  public ProjectPage(WebDriver driver, String projectName) {
    this.driver = driver;
    this.projectName = projectName;
  }

  @Override
  protected void load() {
    driver.get("http://" + projectName + ".googlecode.com/");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();

    assertTrue(url.contains(projectName));
  }
}
```

and SecuredPage.java:

```java
package com.example.webdriver;

import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import static org.junit.Assert.fail;

public class SecuredPage extends LoadableComponent<SecuredPage> {

  private final WebDriver driver;
  private final LoadableComponent<?> parent;
  private final String username;
  private final String password;

  public SecuredPage(WebDriver driver, LoadableComponent<?> parent, String username, String password) {
    this.driver = driver;
    this.parent = parent;
    this.username = username;
    this.password = password;
  }

  @Override
  protected void load() {
    parent.get();

    String originalUrl = driver.getCurrentUrl();

    // Sign in
    driver.get("https://www.google.com/accounts/ServiceLogin?service=code");
    driver.findElement(By.name("Email")).sendKeys(username);
    WebElement passwordField = driver.findElement(By.name("Passwd"));
    passwordField.sendKeys(password);
    passwordField.submit();

    // Now return to the original URL
    driver.get(originalUrl);
  }

  @Override
  protected void isLoaded() throws Error {
    // If you're signed in, you have the option of picking a different login.
    // Let's check for the presence of that.

    try {
      WebElement div = driver.findElement(By.id("multilogin-dropdown"));
    } catch (NoSuchElementException e) {
      fail("Cannot locate user name link");
    }
  }
}
```

The “load” method in EditIssue now looks like:

```java
  @Override
  protected void load() {
    securedPage.get();

    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }
```

This shows that the components are all “nested” within each other. A call to `get()` in EditIssue will cause all its dependencies to load too. The example usage:

```java
public class FooTest {
  private EditIssue editIssue;

  @Before
  public void prepareComponents() {
    WebDriver driver = new FirefoxDriver();

    ProjectPage project = new ProjectPage(driver, "selenium");
    SecuredPage securedPage = new SecuredPage(driver, project, "example", "top secret");
    editIssue = new EditIssue(driver, securedPage);
  }

  @Test
  public void demonstrateNestedLoadableComponents() {
    editIssue.get();

    editIssue.title.sendKeys('Title');
    editIssue.body.sendKeys('What Happened');
    editIssue.setHowToReproduce('How to Reproduce');
    editIssue.setLogOutput('Log Output');
    editIssue.setOperatingSystem('Operating System');
    editIssue.setSeleniumVersion('Selenium Version');
    editIssue.setBrowserVersion('Browser Version');
    editIssue.setDriverVersion('Driver Version');
    editIssue.setUsingGrid('I Am Using Grid');
  }
}
```

If you’re using a library such as [Guiceberry](https://github.com/zorzella/guiceberry) in your tests, the preamble of setting up the PageObjects can be omitted leading to nice, clear, readable tests.

## Bot Pattern

(previously located: <https://github.com/SeleniumHQ/selenium/wiki/Bot-Style-Tests>)

Although PageObjects are a useful way of reducing duplication in your tests, it’s not always a pattern that teams feel comfortable following. An alternative approach is to follow a more “command-like” style of testing.

A “bot” is an action-oriented abstraction over the raw Selenium APIs. This means that if you find that commands aren’t doing the Right Thing for your app, it’s easy to change them. As an example:

```java
public class ActionBot {
  private final WebDriver driver;

  public ActionBot(WebDriver driver) {
    this.driver = driver;
  }

  public void click(By locator) {
    driver.findElement(locator).click();
  }

  public void submit(By locator) {
    driver.findElement(locator).submit();
  }

  /** 
   * Type something into an input field. WebDriver doesn't normally clear these
   * before typing, so this method does that first. It also sends a return key
   * to move the focus out of the element.
   */
  public void type(By locator, String text) { 
    WebElement element = driver.findElement(locator);
    element.clear();
    element.sendKeys(text + "\n");
  }
}
```

```py
import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L6-L26)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L28-L65)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L67-L80)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L82-L172)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L174-L240)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

最后修改 May 6, 2025: [\[docs\]: fix build issues \[deploy site\] (7615cca5ebc)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/7615cca5ebc3a7681e9ec9e6cdb4b1ddd681ef00)

----
url: https://www.selenium.dev/ja/documentation/webdriver/drivers/service/
----

# ドライバーサービスクラス

```java
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L15-L16)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L5-L6)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L14-L15)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

```rb
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L14-L15)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

```java
    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L25-L26)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(executable_path=chromedriver_bin)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L15)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```cs
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L23)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
    service.executable_path = driver_path
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L26)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

```java
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L33)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(port=1234)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L23)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            service.Port = 1234;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L32)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
    service.port = 1234
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L33)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

----
url: https://www.selenium.dev/_print/documentation/test_practices/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/test_practices/).

# Test Practices

Some guidelines and recommendations on testing from the Selenium project.

* 1: [Design patterns and development strategies](#pg-3286224775779710c4672907b2b831b0)
* 2: [Overview of Test Automation](#pg-6973a0beac803dee5b57954d5e663a70)
* 3: [Types of Testing](#pg-ae27e7b17b96484d414ce569b3da687a)
* 4: [Encouraged behaviors](#pg-a0035ce2a3f2cebdffec2bcf375d9b27)
* * 4.1: [Page object models](#pg-fa5d8fda885160f5bac36ddd0a759f2c)
  * 4.2: [Domain specific language](#pg-2fa3bc7763585631cae7ebbfd2ab6f4d)
  * 4.3: [Generating application state](#pg-806a27b179478d057a2a72eaecbb5a7f)
  * 4.4: [Mock external services](#pg-8e67210230ed00981653880f12c0854b)
  * 4.5: [Improved reporting](#pg-2fc5231d4be0c254ce4f3da24dd7ecac)
  * 4.6: [Avoid sharing state](#pg-95634a04429bc3ee0d73ad583f402ecf)
  * 4.7: [Tips on working with locators](#pg-84640ae953713c14fe36c508f185cc39)
  * 4.8: [Test independency](#pg-86fac44b429f8cec078f2c489c86beb0)
  * 4.9: [Consider using a fluent API](#pg-9a56c997c2608d98dbbc2d6cb49a33e0)
  * 4.10: [Fresh browser per test](#pg-a725d846f871bf74490745badf015de3)
  5: [Discouraged behaviors](#pg-57da8a2b64fc86fcbf7aa26f82072089)
  * 5.1: [Captchas](#pg-3b5620c52a2bef6c4d263b6166817252)
  * 5.2: [File downloads](#pg-412b120e2f3e7939c790abf3c78fe23c)
  * 5.3: [HTTP response codes](#pg-b10eceb097750b67d81f2781a6a7826c)
  * 5.4: [Gmail, email and Facebook logins](#pg-f94ff72a0e04621b23443ef2c2946b5c)
  * 5.5: [Test dependency](#pg-592156e95c121f26c09a41092841d50b)
  * 5.6: [Performance testing](#pg-ca2d7e5feff08f93a1b71dd68ea8bba8)
  * 5.7: [Link spidering](#pg-7093b50bd3c1a0db58ef8ce55b3bc209)
  * 5.8: [Two Factor Authentication](#pg-224ad84522a037ac1a20e467084f55e5)

A note on “Best Practices”: We’ve intentionally avoided the phrase “Best Practices” in this documentation. No one approach works for all situations. We prefer the idea of “Guidelines and Recommendations.” We encourage you to read through these and thoughtfully decide what approaches will work for you in your particular environment.

Functional testing is challenging to get right for many reasons. As if application state, complexity, and dependencies do not make testing difficult enough, dealing with browsers (especially with cross-browser incompatibilities) makes writing good tests a challenge.

Selenium provides tools to make functional user interaction easier, but does not help you write well-architected test suites. In this chapter, we offer advice, guidelines, and recommendations on how to approach functional web page automation.

This chapter records software design patterns popular amongst many of the users of Selenium that have proven successful over the years.

# 1 - Design patterns and development strategies

```java
package com.example.webdriver;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class EditIssue {

  private final WebDriver driver;

  public EditIssue(WebDriver driver) {
    this.driver = driver;
  }

  public void setTitle(String title) {
    WebElement field = driver.findElement(By.id("issue_title")));
    clearAndType(field, title);
  }

  public void setBody(String body) {
    WebElement field = driver.findElement(By.id("issue_body"));
    clearAndType(field, body);
  }

  public void setHowToReproduce(String howToReproduce) {
    WebElement field = driver.findElement(By.id("issue_form_repro-command"));
    clearAndType(field, howToReproduce);
  }

  public void setLogOutput(String logOutput) {
    WebElement field = driver.findElement(By.id("issue_form_logs"));
    clearAndType(field, logOutput);
  }

  public void setOperatingSystem(String operatingSystem) {
    WebElement field = driver.findElement(By.id("issue_form_operating-system"));
    clearAndType(field, operatingSystem);
  }

  public void setSeleniumVersion(String seleniumVersion) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-version"));
    clearAndType(field, logOutput);
  }

  public void setBrowserVersion(String browserVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-versions"));
    clearAndType(field, browserVersion);
  }

  public void setDriverVersion(String driverVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-driver-versions"));
    clearAndType(field, driverVersion);
  }

  public void setUsingGrid(String usingGrid) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-grid-version"));
    clearAndType(field, usingGrid);
  }

  public IssueList submit() {
    driver.findElement(By.cssSelector("button[type='submit']")).click();
    return new IssueList(driver);
  }

  private void clearAndType(WebElement field, String text) {
    field.clear();
    field.sendKeys(text);
  }
}
```

In order to turn this into a LoadableComponent, all we need to do is to set that as the base type:

```java
public class EditIssue extends LoadableComponent<EditIssue> {
  // rest of class ignored for now
}
```

This signature looks a little unusual, but all it means is that this class represents a LoadableComponent that loads the EditIssue page.

By extending this base class, we need to implement two new methods:

```java
  @Override
  protected void load() {
    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();
    assertTrue("Not on the issue entry page: " + url, url.endsWith("/new"));
  }
```

The `load` method is used to navigate to the page, whilst the `isLoaded` method is used to determine whether we are on the right page. Although the method looks like it should return a boolean, instead it performs a series of assertions using JUnit’s Assert class. There can be as few or as many assertions as you like. By using these assertions it’s possible to give users of the class clear information that can be used to debug tests.

With a little rework, our PageObject looks like:

```java
package com.example.webdriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

import static junit.framework.Assert.assertTrue;

public class EditIssue extends LoadableComponent<EditIssue> {

  private final WebDriver driver;
  
  // By default the PageFactory will locate elements with the same name or id
  // as the field. Since the issue_title element has an id attribute of "issue_title"
  // we don't need any additional annotations.
  private WebElement issue_title;
  
  // But we'd prefer a different name in our code than "issue_body", so we use the
  // FindBy annotation to tell the PageFactory how to locate the element.
  @FindBy(id = "issue_body") private WebElement body;
  
  public EditIssue(WebDriver driver) {
    this.driver = driver;
    
    // This call sets the WebElement fields.
    PageFactory.initElements(driver, this);
  }

  @Override
  protected void load() {
    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();
    assertTrue("Not on the issue entry page: " + url, url.endsWith("/new"));
  }

  public void setHowToReproduce(String howToReproduce) {
    WebElement field = driver.findElement(By.id("issue_form_repro-command"));
    clearAndType(field, howToReproduce);
  }

  public void setLogOutput(String logOutput) {
    WebElement field = driver.findElement(By.id("issue_form_logs"));
    clearAndType(field, logOutput);
  }

  public void setOperatingSystem(String operatingSystem) {
    WebElement field = driver.findElement(By.id("issue_form_operating-system"));
    clearAndType(field, operatingSystem);
  }

  public void setSeleniumVersion(String seleniumVersion) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-version"));
    clearAndType(field, logOutput);
  }

  public void setBrowserVersion(String browserVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-versions"));
    clearAndType(field, browserVersion);
  }

  public void setDriverVersion(String driverVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-driver-versions"));
    clearAndType(field, driverVersion);
  }

  public void setUsingGrid(String usingGrid) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-grid-version"));
    clearAndType(field, usingGrid);
  }

  public IssueList submit() {
    driver.findElement(By.cssSelector("button[type='submit']")).click();
    return new IssueList(driver);
  }

  private void clearAndType(WebElement field, String text) {
    field.clear();
    field.sendKeys(text);
  }
}
```

That doesn’t seem to have bought us much, right? One thing it has done is encapsulate the information about how to navigate to the page into the page itself, meaning that this information’s not scattered through the code base. It also means that we can do this in our tests:

```java
EditIssue page = new EditIssue(driver).get();
```

This call will cause the driver to navigate to the page if that’s necessary.

### Nested Components

LoadableComponents start to become more useful when they are used in conjunction with other LoadableComponents. Using our example, we could view the “edit issue” page as a component within a project’s website (after all, we access it via a tab on that site). You also need to be logged in to file an issue. We could model this as a tree of nested components:

```
 + ProjectPage
 +---+ SecuredPage
     +---+ EditIssue
```

What would this look like in code? For a start, each logical component would have its own class. The “load” method in each of them would “get” the parent. The end result, in addition to the EditIssue class above is:

ProjectPage.java:

```java
package com.example.webdriver;

import org.openqa.selenium.WebDriver;

import static org.junit.Assert.assertTrue;

public class ProjectPage extends LoadableComponent<ProjectPage> {

  private final WebDriver driver;
  private final String projectName;

  public ProjectPage(WebDriver driver, String projectName) {
    this.driver = driver;
    this.projectName = projectName;
  }

  @Override
  protected void load() {
    driver.get("http://" + projectName + ".googlecode.com/");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();

    assertTrue(url.contains(projectName));
  }
}
```

and SecuredPage.java:

```java
package com.example.webdriver;

import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import static org.junit.Assert.fail;

public class SecuredPage extends LoadableComponent<SecuredPage> {

  private final WebDriver driver;
  private final LoadableComponent<?> parent;
  private final String username;
  private final String password;

  public SecuredPage(WebDriver driver, LoadableComponent<?> parent, String username, String password) {
    this.driver = driver;
    this.parent = parent;
    this.username = username;
    this.password = password;
  }

  @Override
  protected void load() {
    parent.get();

    String originalUrl = driver.getCurrentUrl();

    // Sign in
    driver.get("https://www.google.com/accounts/ServiceLogin?service=code");
    driver.findElement(By.name("Email")).sendKeys(username);
    WebElement passwordField = driver.findElement(By.name("Passwd"));
    passwordField.sendKeys(password);
    passwordField.submit();

    // Now return to the original URL
    driver.get(originalUrl);
  }

  @Override
  protected void isLoaded() throws Error {
    // If you're signed in, you have the option of picking a different login.
    // Let's check for the presence of that.

    try {
      WebElement div = driver.findElement(By.id("multilogin-dropdown"));
    } catch (NoSuchElementException e) {
      fail("Cannot locate user name link");
    }
  }
}
```

The “load” method in EditIssue now looks like:

```java
  @Override
  protected void load() {
    securedPage.get();

    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }
```

This shows that the components are all “nested” within each other. A call to `get()` in EditIssue will cause all its dependencies to load too. The example usage:

```java
public class FooTest {
  private EditIssue editIssue;

  @Before
  public void prepareComponents() {
    WebDriver driver = new FirefoxDriver();

    ProjectPage project = new ProjectPage(driver, "selenium");
    SecuredPage securedPage = new SecuredPage(driver, project, "example", "top secret");
    editIssue = new EditIssue(driver, securedPage);
  }

  @Test
  public void demonstrateNestedLoadableComponents() {
    editIssue.get();

    editIssue.title.sendKeys('Title');
    editIssue.body.sendKeys('What Happened');
    editIssue.setHowToReproduce('How to Reproduce');
    editIssue.setLogOutput('Log Output');
    editIssue.setOperatingSystem('Operating System');
    editIssue.setSeleniumVersion('Selenium Version');
    editIssue.setBrowserVersion('Browser Version');
    editIssue.setDriverVersion('Driver Version');
    editIssue.setUsingGrid('I Am Using Grid');
  }

}
```

If you’re using a library such as [Guiceberry](https://github.com/zorzella/guiceberry) in your tests, the preamble of setting up the PageObjects can be omitted leading to nice, clear, readable tests.

## Bot Pattern

(previously located: <https://github.com/SeleniumHQ/selenium/wiki/Bot-Style-Tests>)

Although PageObjects are a useful way of reducing duplication in your tests, it’s not always a pattern that teams feel comfortable following. An alternative approach is to follow a more “command-like” style of testing.

A “bot” is an action-oriented abstraction over the raw Selenium APIs. This means that if you find that commands aren’t doing the Right Thing for your app, it’s easy to change them. As an example:

```java
public class ActionBot {
  private final WebDriver driver;

  public ActionBot(WebDriver driver) {
    this.driver = driver;
  }

  public void click(By locator) {
    driver.findElement(locator).click();
  }

  public void submit(By locator) {
    driver.findElement(locator).submit();
  }

  /** 
   * Type something into an input field. WebDriver doesn't normally clear these
   * before typing, so this method does that first. It also sends a return key
   * to move the focus out of the element.
   */
  public void type(By locator, String text) { 
    WebElement element = driver.findElement(locator);
    element.clear();
    element.sendKeys(text + "\n");
  }
}
```

```py
import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L6-L26)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L28-L65)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L67-L80)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L82-L172)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L174-L240)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

# 2 - Overview of Test Automation

```java
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
User user = UserFactory.createCommonUser(); //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
AccountPage accountPage = loginAs(user.getEmail(), user.getPassword());
  
```

```python
# Create a user who has read-only permissions--they can configure a unicorn,
# but they do not have payment information set up, nor do they have
# administrative privileges. At the time the user is created, its email
# address and password are randomly generated--you don't even need to
# know them.
user = user_factory.create_common_user() #This method is defined elsewhere.

# Log in as this user.
# Logging in on this site takes you to your personal "My Account" page, so the
# AccountPage object is returned by the loginAs method, allowing you to then
# perform actions from the AccountPage.
account_page = login_as(user.get_email(), user.get_password())
  
```

```csharp
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
User user = UserFactory.CreateCommonUser(); //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
AccountPage accountPage = LoginAs(user.Email, user.Password);
  
```

```ruby
# Create a user who has read-only permissions--they can configure a unicorn,
# but they do not have payment information set up, nor do they have
# administrative privileges. At the time the user is created, its email
# address and password are randomly generated--you don't even need to
# know them.
user = UserFactory.create_common_user #This method is defined elsewhere.

# Log in as this user.
# Logging in on this site takes you to your personal "My Account" page, so the
# AccountPage object is returned by the loginAs method, allowing you to then
# perform actions from the AccountPage.
account_page = login_as(user.email, user.password)
  
```

```javascript
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
var user = userFactory.createCommonUser(); //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
var accountPage = loginAs(user.email, user.password);
  
```

```kotlin
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
val user = UserFactory.createCommonUser() //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
val accountPage = loginAs(user.getEmail(), user.getPassword())
  
```

```java
// The Unicorn is a top-level Object--it has attributes, which are set here. 
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
Unicorn sparkles = new Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS);

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.
AddUnicornPage addUnicornPage = accountPage.addUnicorn();

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
UnicornConfirmationPage unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles);
  
```

```python
# The Unicorn is a top-level Object--it has attributes, which are set here.
# This only stores the values; it does not fill out any web forms or interact
# with the browser in any way.
sparkles = Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

# Since we're already "on" the account page, we have to use it to get to the
# actual place where you configure unicorns. Calling the "Add Unicorn" method
# takes us there.
add_unicorn_page = account_page.add_unicorn()

# Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
# its createUnicorn() method. This method will take Sparkles' attributes,
# fill out the form, and click submit.
unicorn_confirmation_page = add_unicorn_page.create_unicorn(sparkles)
  
```

```csharp
// The Unicorn is a top-level Object--it has attributes, which are set here. 
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
Unicorn sparkles = new Unicorn("Sparkles", UnicornColors.Purple, UnicornAccessories.Sunglasses, UnicornAdornments.StarTattoos);

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.
AddUnicornPage addUnicornPage = accountPage.AddUnicorn();

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
UnicornConfirmationPage unicornConfirmationPage = addUnicornPage.CreateUnicorn(sparkles);
  
```

```ruby
# The Unicorn is a top-level Object--it has attributes, which are set here.
# This only stores the values; it does not fill out any web forms or interact
# with the browser in any way.
sparkles = Unicorn.new('Sparkles', UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

# Since we're already "on" the account page, we have to use it to get to the
# actual place where you configure unicorns. Calling the "Add Unicorn" method
# takes us there.
add_unicorn_page = account_page.add_unicorn

# Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
# its createUnicorn() method. This method will take Sparkles' attributes,
# fill out the form, and click submit.
unicorn_confirmation_page = add_unicorn_page.create_unicorn(sparkles)
  
```

```javascript
// The Unicorn is a top-level Object--it has attributes, which are set here.
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
var sparkles = new Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS);

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.

var addUnicornPage = accountPage.addUnicorn();

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
var unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles);

  
```

```kotlin
// The Unicorn is a top-level Object--it has attributes, which are set here. 
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
val sparkles = Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.
val addUnicornPage = accountPage.addUnicorn()

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles)

  
```

```java
// The exists() method from UnicornConfirmationPage will take the Sparkles 
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
Assert.assertTrue("Sparkles should have been created, with all attributes intact", unicornConfirmationPage.exists(sparkles));
  
```

```python
# The exists() method from UnicornConfirmationPage will take the Sparkles
# object--a specification of the attributes you want to see, and compare
# them with the fields on the page.
assert unicorn_confirmation_page.exists(sparkles), "Sparkles should have been created, with all attributes intact"
  
```

```csharp
// The exists() method from UnicornConfirmationPage will take the Sparkles 
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
Assert.True(unicornConfirmationPage.Exists(sparkles), "Sparkles should have been created, with all attributes intact");
  
```

```ruby
# The exists() method from UnicornConfirmationPage will take the Sparkles
# object--a specification of the attributes you want to see, and compare
# them with the fields on the page.
expect(unicorn_confirmation_page.exists?(sparkles)).to be, 'Sparkles should have been created, with all attributes intact'
  
```

```javascript
// The exists() method from UnicornConfirmationPage will take the Sparkles
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
assert(unicornConfirmationPage.exists(sparkles), "Sparkles should have been created, with all attributes intact");

  
```

```kotlin
// The exists() method from UnicornConfirmationPage will take the Sparkles 
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
assertTrue("Sparkles should have been created, with all attributes intact", unicornConfirmationPage.exists(sparkles))
  
```

Note that the tester still has not done anything but talk about unicorns in this code– no buttons, no locators, no browser controls. This method of *modelling* the application allows you to keep these test-level commands in place and unchanging, even if Larry decides next week that he no longer likes Ruby-on-Rails and decides to re-implement the entire site in the latest Haskell bindings with a Fortran front-end.

Your page objects will require some small maintenance in order to conform to the site redesign, but these tests will remain the same. Taking this basic design, you will want to keep going through your workflows with the fewest browser-facing steps possible. Your next workflow will involve adding a unicorn to the shopping cart. You will probably want many iterations of this test in order to make sure the cart is keeping its state properly: Is there more than one unicorn in the cart before you start? How many can fit in the shopping cart? If you create more than one with the same name and/or features, will it break? Will it only keep the existing one or will it add another?

Each time you move through the workflow, you want to try to avoid having to create an account, login as the user, and configure the unicorn. Ideally, you will be able to create an account and pre-configure a unicorn via the API or database. Then all you have to do is log in as the user, locate Sparkles, and add her to the cart.

### To automate or not to automate?

Is automation always advantageous? When should one decide to automate test cases?

It is not always advantageous to automate test cases. There are times when manual testing may be more appropriate. For instance, if the application’s user interface will change considerably in the near future, then any automation might need to be rewritten anyway. Also, sometimes there simply is not enough time to build test automation. For the short term, manual testing may be more effective. If an application has a very tight deadline, there is currently no test automation available, and it’s imperative that the testing gets done within that time frame, then manual testing is the best solution.

# 3 - Types of Testing

### Acceptance testing

This type of testing is done to determine if a feature or system meets the customer expectations and requirements. This type of testing generally involves the customer’s cooperation or feedback, being a validation activity that answers the question:

> Are we building the ***right*** product?

For web applications, the automation of this testing can be done directly with Selenium by simulating user expected behaviour. This simulation could be done by record/playback or through the different supported languages as explained in this documentation. Note: Acceptance testing is a subtype of ***functional testing***, which some people might also refer to.

### Functional testing

This type of testing is done to determine if a feature or system functions properly without issues. It checks the system at different levels to ensure that all scenarios are covered and that the system does *what* it’s supposed to do. It’s a verification activity that answers the question:

> Are we building the product ***right?***

This generally includes: the tests work without errors (404, exceptions…), in a usable way (correct redirections), in an accessible way and matching its specifications (see ***acceptance testing*** above).

For web applications, the automation of this testing can be done directly with Selenium by simulating expected returns. This simulation could be done by record/playback or through the different supported languages as explained in this documentation.

### Integration Tests

Integration tests verify the interactions between different components or modules of a system. Several modules are together tested. The purpose of Integration tests is to make sure that all modules integrate and work together as expected. Automated integration tests help ensure that these interactions work as expected and that integrated components function properly together.

> For example, ***Testing the flow of placing the order for an item in an ecommerce website along with payment.***

### System Tests

System Testing is a complete fully integrated product Testing. It is an end-to-end testing where in testing environment is similar to the production environment. Here, we navigate through all the features of the software and test if the end business / end feature works. We just test the end feature and don’t check for data flow or do functional testing and all.

> For example, ***Testing the end to end flow from login to placing an order and rechecking the order in My Orders page and logoff from an ecommerce website.***

### Performance testing

As its name indicates, performance tests are done to measure how well an application is performing.

There are two main sub-types for performance testing:

#### Load testing

Load testing is done to verify how well the application works under different defined loads (usually a particular number of users connected at once).

> For example, ***Testing that the site can handle numerous orders/users at once.***

#### Stress testing

Stress testing is done to verify how well the application works under stress (or above the maximum supported load).

> For example, ***Testing that your ecommerce site can handle Black Friday***

> For example, ***Testing that your new search bar doesn’t break the other buttons on the menu***

# 4 - Encouraged behaviors

Some guidelines and recommendations on testing from the Selenium project.

A note on “Best Practices”: We’ve intentionally avoided the phrase “Best Practices” in this documentation. No one approach works for all situations. We prefer the idea of “Guidelines and Recommendations”. We encourage you to read through these and thoughtfully decide what approaches will work for you in your particular environment.

Functional testing is difficult to get right for many reasons. As if application state, complexity, and dependencies do not make testing difficult enough, dealing with browsers (especially with cross-browser incompatibilities) makes writing good tests a challenge.

Selenium provides tools to make functional user interaction easier, but does not help you write well-architected test suites. In this chapter we offer advice, guidelines, and recommendations on how to approach functional web page automation.

This chapter records software design patterns popular amongst many of the users of Selenium that have proven successful over the years.

# 4.1 - Page object models

```java
/***
 * Tests login feature
 */
public class Login {

  public void testLogin() {
    // fill login data on sign-in page
    driver.findElement(By.name("user_name")).sendKeys("userName");
    driver.findElement(By.name("password")).sendKeys("my supersecret password");
    driver.findElement(By.name("sign-in")).click();

    // verify h1 tag is "Hello userName" after login
    driver.findElement(By.tagName("h1")).isDisplayed();
    assertThat(driver.findElement(By.tagName("h1")).getText(), is("Hello userName"));
  }
}
```

There are two problems with this approach.

* There is no separation between the test method and the AUT’s locators (IDs in this example); both are intertwined in a single method. If the AUT’s UI changes its identifiers, layout, or how a login is input and processed, the test itself must change.
* The ID-locators would be spread in multiple tests, in all tests that had to use this login page.

Applying the page object model, this example could be rewritten like this in the following example of a page object for a Sign-in page.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Sign-in page.
 */
public class SignInPage {
  protected WebDriver driver;

  // <input name="user_name" type="text" value="">
  private By usernameBy = By.name("user_name");
  // <input name="password" type="password" value="">
  private By passwordBy = By.name("password");
  // <input name="sign_in" type="submit" value="SignIn">
  private By signinBy = By.name("sign_in");

  public SignInPage(WebDriver driver){
    this.driver = driver;
     if (!driver.getTitle().equals("Sign In Page")) {
      throw new IllegalStateException("This is not Sign In Page," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Login as valid user
    *
    * @param userName
    * @param password
    * @return HomePage object
    */
  public HomePage loginValidUser(String userName, String password) {
    driver.findElement(usernameBy).sendKeys(userName);
    driver.findElement(passwordBy).sendKeys(password);
    driver.findElement(signinBy).click();
    return new HomePage(driver);
  }
}
```

and page object for a Home page could look like this.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Home Page
 */
public class HomePage {
  protected WebDriver driver;

  // <h1>Hello userName</h1>
  private By messageBy = By.tagName("h1");

  public HomePage(WebDriver driver){
    this.driver = driver;
    if (!driver.getTitle().equals("Home Page of logged in user")) {
      throw new IllegalStateException("This is not Home Page of logged in user," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Get message (h1 tag)
    *
    * @return String message text
    */
  public String getMessageText() {
    return driver.findElement(messageBy).getText();
  }

  public HomePage manageProfile() {
    // Page encapsulation to manage profile functionality
    return new HomePage(driver);
  }
  /* More methods offering the services represented by Home Page
  of Logged User. These methods in turn might return more Page Objects
  for example click on Compose mail button could return ComposeMail class object */
}
```

So now, the login test would use these two page objects as follows.

```java
/***
 * Tests login feature
 */
public class TestLogin {

  @Test
  public void testLogin() {
    SignInPage signInPage = new SignInPage(driver);
    HomePage homePage = signInPage.loginValidUser("userName", "password");
    assertThat(homePage.getMessageText(), is("Hello userName"));
  }

}
```

```html
<!-- Products Page -->
<div class="header_container">
    <span class="title">Products</span>
</div>

<div class="inventory_list">
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
</div>
```

Each product is a component of the Products page.

```html
<!-- Inventory Item -->
<div class="inventory_item">
    <div class="inventory_item_name">Backpack</div>
    <div class="pricebar">
        <div class="inventory_item_price">$29.99</div>
        <button id="add-to-cart-backpack">Add to cart</button>
    </div>
</div>
```

The Products page HAS-A list of products. This object relationship is called Composition. In simpler terms, something is *composed of* another thing.

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

// Page Object
public class ProductsPage extends BasePage {
    public ProductsPage(WebDriver driver) {
        super(driver);
        // No assertions, throws an exception if the element is not loaded
        new WebDriverWait(driver, Duration.ofSeconds(3))
            .until(d -> d.findElement(By.className​("header_container")));
    }

    // Returning a list of products is a service of the page
    public List<Product> getProducts() {
        return driver.findElements(By.className​("inventory_item"))
            .stream()
            .map(e -> new Product(e)) // Map WebElement to a product component
            .toList();
    }

    // Return a specific product using a boolean-valued function (predicate)
    // This is the behavioral Strategy Pattern from GoF
    public Product getProduct(Predicate<Product> condition) {
        return getProducts()
            .stream()
            .filter(condition) // Filter by product name or price
            .findFirst()
            .orElseThrow(() -> new RuntimeException("Product not found")); // Error thrown during actual test run
    }
}
```

The Product component object is used inside the Products page object.

```java
public abstract class BaseComponent {
    protected WebElement root;

    public BaseComponent(WebElement root) {
        this.root = root;
    }
}

// Page Component Object
public class Product extends BaseComponent {
    // The root element contains the entire component
    public Product(WebElement root) {
        super(root); // inventory_item
    }

    public String getName() {
        // Locating an element begins at the root of the component
        return root.findElement(By.className("inventory_item_name")).getText();
    }

    public BigDecimal getPrice() {
        return new BigDecimal(
                root.findElement(By.className("inventory_item_price"))
                    .getText()
                    .replace("$", "")
            ).setScale(2, RoundingMode.UNNECESSARY); // Sanitation and formatting
    }

    public void addToCart() {
        root.findElement(By.id("add-to-cart-backpack")).click();
    }
}
```

So now, the products test would use the page object and the page component object as follows.

```java
public class ProductsTest {
    @Test
    public void testProductInventory() {
        var productsPage = new ProductsPage(driver); // page object
        var products = productsPage.getProducts();
        assertEquals(6, products.size()); // expected, actual
    }
    
    @Test
    public void testProductPrices() {
        var productsPage = new ProductsPage(driver);

        // Pass a lambda expression (predicate) to filter the list of products
        // The predicate or "strategy" is the behavior passed as parameter
        var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); // page component object
        var bikeLight = productsPage.getProduct(p -> p.getName().equals("Bike Light"));

        assertEquals(new BigDecimal("29.99"), backpack.getPrice());
        assertEquals(new BigDecimal("9.99"), bikeLight.getPrice());
    }
}
```

```java
public class LoginPage {
    public HomePage loginAs(String username, String password) {
        // ... clever magic happens here
    }
    
    public LoginPage loginAsExpectingError(String username, String password) {
        //  ... failed login here, maybe because one or both of the username and password are wrong
    }
    
    public String getErrorMessage() {
        // So we can verify that the correct error is shown
    }
}
```

The code presented above shows an important point: the tests, not the Page Objects, should be responsible for making assertions about the state of a page. For example:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    inbox.assertMessageWithSubjectIsUnread("I like cheese");
    inbox.assertMessageWithSubjectIsNotUnread("I'm not fond of tofu");
}
```

could be re-written as:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    assertTrue(inbox.isMessageWithSubjectIsUnread("I like cheese"));
    assertFalse(inbox.isMessageWithSubjectIsUnread("I'm not fond of tofu"));
}
```

```java
public class LoginPage {
    private final WebDriver driver;

    public LoginPage(WebDriver driver) {
        this.driver = driver;

        // Check that we're on the right page.
        if (!"Login".equals(driver.getTitle())) {
            // Alternatively, we could navigate to the login page, perhaps logging out first
            throw new IllegalStateException("This is not the login page");
        }
    }

    // The login page contains several HTML elements that will be represented as WebElements.
    // The locators for these elements should only be defined once.
        By usernameLocator = By.id("username");
        By passwordLocator = By.id("passwd");
        By loginButtonLocator = By.id("login");

    // The login page allows the user to type their username into the username field
    public LoginPage typeUsername(String username) {
        // This is the only place that "knows" how to enter a username
        driver.findElement(usernameLocator).sendKeys(username);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to type their password into the password field
    public LoginPage typePassword(String password) {
        // This is the only place that "knows" how to enter a password
        driver.findElement(passwordLocator).sendKeys(password);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to submit the login form
    public HomePage submitLogin() {
        // This is the only place that submits the login form and expects the destination to be the home page.
        // A seperate method should be created for the instance of clicking login whilst expecting a login failure. 
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the login page ever
        // go somewhere else (for example, a legal disclaimer) then changing the method signature
        // for this method will mean that all tests that rely on this behaviour won't compile.
        return new HomePage(driver);	
    }

    // The login page allows the user to submit the login form knowing that an invalid username and / or password were entered
    public LoginPage submitLoginExpectingFailure() {
        // This is the only place that submits the login form and expects the destination to be the login page due to login failure.
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the user ever be navigated to the home page after submiting a login with credentials 
        // expected to fail login, the script will fail when it attempts to instantiate the LoginPage PageObject.
        return new LoginPage(driver);	
    }

    // Conceptually, the login page offers the user the service of being able to "log into"
    // the application using a user name and password. 
    public HomePage loginAs(String username, String password) {
        // The PageObject methods that enter username, password & submit login have already defined and should not be repeated here.
        typeUsername(username);
        typePassword(password);
        return submitLogin();
    }
}
```

# 4.2 - Domain specific language

```java
/**
 * Takes a username and password, fills out the fields, and clicks "login".
 * @return An instance of the AccountPage
 */
public AccountPage loginAsUser(String username, String password) {
  WebElement loginField = driver.findElement(By.id("loginField"));
  loginField.clear();
  loginField.sendKeys(username);

  // Fill out the password field. The locator we're using is "By.id", and we should
  // have it defined elsewhere in the class.
  WebElement passwordField = driver.findElement(By.id("password"));
  passwordField.clear();
  passwordField.sendKeys(password);

  // Click the login button, which happens to have the id "submit".
  driver.findElement(By.id("submit")).click();

  // Create and return a new instance of the AccountPage (via the built-in Selenium
  // PageFactory).
  return PageFactory.newInstance(AccountPage.class);
}
```

This method completely abstracts the concepts of input fields, buttons, clicking, and even pages from your test code. Using this approach, all a tester has to do is call this method. This gives you a maintenance advantage: if the login fields ever changed, you would only ever have to change this method - not your tests.

```java
public void loginTest() {
    loginAsUser("cbrown", "cl0wn3");

    // Now that we're logged in, do some other stuff--since we used a DSL to support
    // our testers, it's as easy as choosing from available methods.
    do.something();
    do.somethingElse();
    Assert.assertTrue("Something should have been done!", something.wasDone());

    // Note that we still haven't referred to a button or web control anywhere in this
    // script...
}
```

It bears repeating: one of your primary goals should be writing an API that allows your tests to address **the problem at hand, and NOT the problem of the UI**. The UI is a secondary concern for your users – they do not care about the UI, they just want to get their job done. Your test scripts should read like a laundry list of things the user wants to DO, and the things they want to KNOW. The tests should not concern themselves with HOW the UI requires you to go about it.

\***AUT**: Application under test

# 4.3 - Generating application state

Selenium should not be used to prepare a test case. All repetitive actions and preparations for a test case, should be done through other methods. For example, most web UIs have authentication (e.g. a login form). Eliminating logging in via web browser before every test will improve both the speed and stability of the test. A method should be created to gain access to the AUT\* (e.g. using an API to login and set a cookie). Also, creating methods to pre-load data for testing should not be done using Selenium. As mentioned previously, existing APIs should be leveraged to create data for the AUT\*.

\***AUT**: Application under test

# 4.4 - Mock external services

Eliminating the dependencies on external services will greatly improve the speed and stability of your tests.

# 4.5 - Improved reporting

Selenium is not designed to report on the status of test cases run. Taking advantage of the built-in reporting capabilities of unit test frameworks is a good start. Most unit test frameworks have reports that can generate xUnit or HTML formatted reports. xUnit reports are popular for importing results to a Continuous Integration (CI) server like Jenkins, Travis, Bamboo, etc. Here are some links for more information regarding report outputs for several languages.

[NUnit 3 Console Runner](//github.com/nunit/docs/wiki/Console-Runner)

[NUnit 3 Console Command Line](//github.com/nunit/docs/wiki/Console-Command-Line)

[xUnit getting test results in TeamCity](//xunit.net/docs/getting-test-results-in-teamcity)

[xUnit getting test results in CruiseControl.NET](//xunit.net/docs/getting-test-results-in-ccnet)

[xUnit getting test results in Azure DevOps](//xunit.net/docs/getting-test-results-in-azure-devops)

# 4.6 - Avoid sharing state

Although mentioned in several places, it is worth mentioning again. We must ensure that the tests are isolated from one another.

* Do not share test data. Imagine several tests that each query the database for valid orders before picking one to perform an action on. Should two tests pick up the same order you are likely to get unexpected behavior.

* Clean up stale data in the application that might be picked up by another test e.g. invalid order records.

* Create a new WebDriver instance per test. This helps ensure test isolation and makes parallelization simpler.

  * If you choose [pytest](https://pytest.org/) as your test runner, this can be easily done by yielding your driver in a global fixture. This way each test gets its own driver instance, and you can ensure that drivers always quit after a test is finished (pass or fail).

# 4.7 - Tips on working with locators

# 4.8 - Test independency

Write each test as its own unit. Write the tests in a way that will not be reliant on other tests to complete:

Let us say there is a content management system with which you can create some custom content which then appears on your website as a module after publishing, and it may take some time to sync between the CMS and the application.

A wrong way of testing your module is that the content is created and published in one test, and then checking the module in another test. This is not feasible as the content may not be available immediately for the other test after publishing.

Instead, you can create a stub content which can be turned on and off within the affected test, and use that for validating the module. However, for content creation, you can still have a separate test.

# 4.9 - Consider using a fluent API

Martin Fowler coined the term [“Fluent API”](//www.martinfowler.com/bliki/FluentInterface.html). Selenium already implements something like this in their `FluentWait` class, which is meant as an alternative to the standard `Wait` class. You could enable the Fluent API design pattern in your page object and then query the Google search page with a code snippet like this one:

```java
driver.get( "http://www.google.com/webhp?hl=en&amp;tab=ww" );
GoogleSearchPage gsp = new GoogleSearchPage(driver);
gsp.setSearchString().clickSearchButton();
```

The Google page object class with this fluent behavior might look like this:

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

public class GoogleSearchPage extends BasePage {
    public GoogleSearchPage(WebDriver driver) {
        super(driver);
        // Generally do not assert within pages or components.
        // Effectively throws an exception if the lambda condition is not met.
        new WebDriverWait(driver, Duration.ofSeconds(3)).until(d -> d.findElement(By.id("logo")));
    }

    public GoogleSearchPage setSearchString(String sstr) {
        driver.findElement(By.id("gbqfq")).sendKeys(sstr);
        return this;
    }

    public void clickSearchButton() {
        driver.findElement(By.id("gbqfb")).click();
    }
}
```

# 4.10 - Fresh browser per test

Start each test from a clean, known state. Ideally, spin up a new virtual machine for each test. If spinning up a new virtual machine is not practical, at least start a new WebDriver for each test. Most browser drivers like GeckoDriver and ChromeDriver will start with a clean known state with a new user profile, by default.

```java
WebDriver driver = new FirefoxDriver();
```

# 5 - Discouraged behaviors

Things to avoid when automating browsers with Selenium.

# 5.1 - Captchas

CAPTCHA, short for *Completely Automated Public Turing test to tell Computers and Humans Apart*, is explicitly designed to prevent automation, so do not try! There are two primary strategies to get around CAPTCHA checks:

* Disable CAPTCHAs in your test environment
* Add a hook to allow tests to bypass the CAPTCHA

# 5.2 - File downloads

Whilst it is possible to start a download by clicking a link with a browser under Selenium’s control, the API does not expose download progress, making it less than ideal for testing downloaded files. This is because downloading files is not considered an important aspect of emulating user interaction with the web platform. Instead, find the link using Selenium (and any required cookies) and pass it to a HTTP request library like [curl](https:////curl.se/).

The [HtmlUnit driver](https://github.com/SeleniumHQ/htmlunit-driver) can download attachments by accessing them as input streams by implementing the [AttachmentHandler](https://htmlunit.sourceforge.io/apidocs/com/gargoylesoftware/htmlunit/attachment/AttachmentHandler.html) interface. The AttachmentHandler can then be added to the [HtmlUnit](https://htmlunit.sourceforge.io/) WebClient.

# 5.3 - HTTP response codes

For some browser configurations in Selenium RC, Selenium acted as a proxy between the browser and the site being automated. This meant that all browser traffic passed through Selenium could be captured or manipulated. The `captureNetworkTraffic()` method purported to capture all of the network traffic between the browser and the site being automated, including HTTP response codes.

Selenium WebDriver is a completely different approach to browser automation, preferring to act more like a user. This is represented in the way you write tests with WebDriver. In automated functional testing, checking the status code is not a particularly important detail of a test’s failure; the steps that preceded it are more important.

The browser will always represent the HTTP status code, imagine for example a 404 or a 500 error page. A simple way to “fail fast” when you encounter one of these error pages is to check the page title or content of a reliable point (e.g. the `<h1>` tag) after every page load. If you are using the page object model, you can include this check in your class constructor or similar point where the page load is expected. Occasionally, the HTTP code may even be represented in the browser’s error page and you could use WebDriver to read this and improve your debugging output.

Checking the webpage itself is in line with WebDriver’s ideal practice of representing and asserting upon the user’s view of the website.

If you insist, an advanced solution to capturing HTTP status codes is to replicate the behaviour of Selenium RC by using a proxy. WebDriver API provides the ability to set a proxy for the browser, and there are a number of proxies that will programmatically allow you to manipulate the contents of requests sent to and received from the web server. Using a proxy lets you decide how you want to respond to redirection response codes. Additionally, not every browser makes the response codes available to WebDriver, so opting to use a proxy allows you to have a solution that works for every browser.

# 5.4 - Gmail, email and Facebook logins

For multiple reasons, logging into sites like Gmail and Facebook using WebDriver is not recommended. Aside from being against the usage terms for these sites (where you risk having the account shut down), it is slow and unreliable.

The ideal practice is to use the APIs that email providers offer, or in the case of Facebook the developer tools service which exposes an API for creating test accounts, friends and so forth. Although using an API might seem like a bit of extra hard work, you will be paid back in speed, reliability, and stability. The API is also unlikely to change, whereas webpages and HTML locators change often and require you to update your test framework.

Logging in to third party sites using WebDriver at any point of your test increases the risk of your test failing because it makes your test longer. A general rule of thumb is that longer tests are more fragile and unreliable.

WebDriver implementations that are [W3C conformant](//w3c.github.io/webdriver/webdriver-spec.html) also annotate the `navigator` object with a `WebDriver` property so that Denial of Service attacks can be mitigated.

# 5.5 - Test dependency

A common idea and misconception about automated testing is regarding a specific test order. Your tests should be able to run in **any** order, and not rely on other tests to complete in order to be successful.

# 5.6 - Performance testing

Performance testing using Selenium and WebDriver is generally not advised. Not because it is incapable, but because it is not optimised for the job and you are unlikely to get good results.

It may seem ideal to performance test in the context of the user but a suite of WebDriver tests are subjected to many points of external and internal fragility which are beyond your control; for example browser startup speed, speed of HTTP servers, response of third party servers that host JavaScript or CSS, and the instrumentation penalty of the WebDriver implementation itself. Variation at these points will cause variation in your results. It is difficult to separate the difference between the performance of your website and the performance of external resources, and it is also hard to tell what the performance penalty is for using WebDriver in the browser, especially if you are injecting scripts.

The other potential attraction is “saving time” — carrying out functional and performance tests at the same time. However, functional and performance tests have opposing objectives. To test functionality, a tester may need to be patient and wait for loading, but this will cloud the performance testing results and vice versa.

To improve the performance of your website, you will need to be able to analyse overall performance independent of environment differences, identify poor code practices, breakdown of performance of individual resources (i.e. CSS or JavaScript), in order to know what to improve. There are performance testing tools available that can do this job already, that provide reporting and analysis, and can even make improvement suggestions.

Example (open source) packages to use are: [JMeter](/)

# 5.7 - Link spidering

Using WebDriver to spider through links is not a recommended practice. Not because it cannot be done, but because WebDriver is definitely not the most ideal tool for this. WebDriver needs time to start up, and can take several seconds, up to a minute depending on how your test is written, just to get to the page and traverse through the DOM.

Instead of using WebDriver for this, you could save a ton of time by executing a [curl](https://curl.se/) command, or using a library such as BeautifulSoup since these methods do not rely on creating a browser and navigating to a page. You are saving tonnes of time by not using WebDriver for this task.

# 5.8 - Two Factor Authentication

----
url: https://www.selenium.dev/ja/documentation/test_practices/discouraged/link_spidering/
----

# リンクスパイダー

WebDriverを使用してリンクをスパイダーすることは、実行できないためではなく、最も理想的なツールではないため明らかに推奨される方法ではありません。 WebDriverの起動には時間が必要であり、テストの記述方法によっては、ページに到達してDOMを通過するために数秒から1分かかる場合があります。

このためにWebDriverを使用する代わりに、[curl](https://curl.se/) コマンドを実行するか、BeautifulSoupなどのライブラリを使用することにより、これらの方法はブラウザーの作成やページへの移動に依存しないため、時間を大幅に節約できます。 このタスクにWebDriverを使用しないことで、時間を大幅に節約できます。

----
url: https://www.selenium.dev/documentation/grid/getting_started/
----

# Getting started with Selenium Grid

Instructions for a simple Selenium Grid

## Quick start

1. Prerequisites

   * Java 11 or higher installed

   * Browser(s) installed

   * Browser driver(s)

     * [Selenium Manager](https://www.selenium.dev/documentation/selenium_manager/) will configure the drivers automatically if you add `--selenium-manager true`.
     * [Installed and on the `PATH`](https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location/#use-the-path-environment-variable)

```shell
java -jar selenium-server-<version>.jar standalone
```

```shell
java -jar selenium-server-<version>.jar hub
```

By default, the server will listen for `RemoteWebDriver` requests on <http://localhost:4444>.

#### Node

During startup time, the **Node** will detect the available drivers that it can use from the System [`PATH`](https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location/#use-the-path-environment-variable).

The command below assumes the **Node** is running on the same machine where the **Hub** is running.

```shell
java -jar selenium-server-<version>.jar node
```

##### More than one Node on the same machine

**Node** 1

```shell
java -jar selenium-server-<version>.jar node --port 5555
```

**Node** 2

```shell
java -jar selenium-server-<version>.jar node --port 6666
```

##### Node and Hub on different machines

**Hub** and **Nodes** talk to each other via HTTP and the [**Event Bus**](https://www.selenium.dev/documentation/grid/components/#event-bus) (the **Event Bus** lives inside the **Hub**). A **Node** sends a message to the **Hub** via the **Event Bus** to start the registration process. When the **Hub** receives the message, reaches out to the **Node** via HTTP to confirm its existence.

To successfully register a **Node** to a **Hub**, it is important to expose the **Event Bus** ports (4442 and 4443 by default) on the **Hub** machine. This also applies for the **Node** port. With that, both **Hub** and **Node** will be able to communicate.

If the **Hub** is using the default ports, the `--hub` flag can be used to register the **Node**

```shell
java -jar selenium-server-<version>.jar node --hub http://<hub-ip>:4444
```

When the **Hub** is not using the default ports, the `--publish-events` and `--subscribe-events` flags are needed.

For example, if the **Hub** uses ports `8886`, `8887`, and `8888`

```shell
java -jar selenium-server-<version>.jar hub --publish-events tcp://<hub-ip>:8886 --subscribe-events tcp://<hub-ip>:8887 --port 8888
```

The **Node** needs to use those ports to register successfully

```shell
java -jar selenium-server-<version>.jar node --publish-events tcp://<hub-ip>:8886 --subscribe-events tcp://<hub-ip>:8887
```

### Distributed

When using a Distributed Grid, each component is started separately, and ideally on different machines.

It is important to expose all ports properly in order to allow fluent communication between all components.

1. **Event Bus**: enables internal communication between different Grid components.

Default ports are: `4442`, `4443`, and `5557`.

```shell
java -jar selenium-server-<version>.jar event-bus --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --port 5557
```

2. **New Session Queue**: adds new session requests to a queue, which will be queried by the Distributor

Default port is `5559`.

```shell
java -jar selenium-server-<version>.jar sessionqueue --port 5559
```

3. **Session Map**: maps session IDs to the **Node** where the session is running

Default **Session Map** port is `5556`. **Session Map** interacts with the **Event Bus**.

```shell
java -jar selenium-server-<version>.jar sessions --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --port 5556
```

4. **Distributor**: queries the **New Session Queue** for new session requests, and assigns them to a **Node** when the capabilities match. **Nodes** register to the **Distributor** the way they register to the **Hub** in a **Hub/Node** Grid.

Default **Distributor** port is `5553`. **Distributor** interacts with **New Session Queue**, **Session Map**, **Event Bus**, and the **Node(s)**.

```shell
java -jar selenium-server-<version>.jar distributor --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --sessions http://<sessions-ip>:5556 --sessionqueue http://<new-session-queue-ip>:5559 --port 5553 --bind-bus false
```

5. **Router**: redirects new session requests to the queue, and redirects running sessions requests to the **Node** running that session.

Default **Router** port is `4444`. **Router** interacts with **New Session Queue**, **Session Map**, and **Distributor**.

```shell
java -jar selenium-server-<version>.jar router --sessions http://<sessions-ip>:5556 --distributor http://<distributor-ip>:5553 --sessionqueue http://<new-session-queue-ip>:5559 --port 4444
```

6. **Node(s)**

Default **Node** port is `5555`.

```shell
java -jar selenium-server-<version>.jar node --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443
```

## Metadata in tests

Add metadata to your tests and consume it via [GraphQL](https://www.selenium.dev/documentation/grid/advanced_features/graphql_support/) or visualize parts of it (like `se:name`) through the Selenium Grid UI.

Metadata can be added by prefixing a capability with `se:`. Here is a quick example in Java showing that.

```java
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setCapability("browserVersion", "100");
chromeOptions.setCapability("platformName", "Windows");
// Showing a test name instead of the session id in the Grid UI
chromeOptions.setCapability("se:name", "My simple test"); 
// Other type of metadata can be seen in the Grid UI by clicking on the 
// session info or via GraphQL
chromeOptions.setCapability("se:sampleMetadata", "Sample metadata value"); 
WebDriver driver = new RemoteWebDriver(new URL("http://gridUrl:4444"), chromeOptions);
driver.get("http://www.google.com");
driver.quit();
```

```bash
java -Dwebdriver.http.factory=jdk-http-client -jar selenium-server-<version>.jar --ext selenium-http-jdk-client-<version>.jar standalone
```

An alternative to downloading the `selenium-http-jdk-client` jar file is to use [Coursier](https://get-coursier.io/docs/cli-installation).

```bash
java -Dwebdriver.http.factory=jdk-http-client -jar selenium-server-<version>.jar --ext $(coursier fetch -p org.seleniumhq.selenium:selenium-http-jdk-client:<version>) standalone
```

Last modified August 1, 2025: [\[deploy site\] fixing bug 2402, detectify link removal (#2407) (0b29bc6e614)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/0b29bc6e6148f4e99aab014c39ae33e5fefe7222)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/bidi/cdp/script/
----

```java
    ScriptKey key = ((JavascriptExecutor) driver).pin("return arguments;");
    List<Object> arguments =
        (List<Object>) ((JavascriptExecutor) driver).executeScript(key, 1, true, element);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/ScriptTest.java#L32-L34)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/ScriptTest.java

```java
package dev.selenium.bidi.cdp;

import static org.openqa.selenium.devtools.events.CdpEventTypes.domMutation;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.HasLogEvents;
import org.openqa.selenium.support.ui.WebDriverWait;

public class ScriptTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void pinScript() {
    driver.get("https://www.selenium.dev/selenium/web/xhtmlTest.html");
    WebElement element = driver.findElement(By.id("id1"));

    ScriptKey key = ((JavascriptExecutor) driver).pin("return arguments;");
    List<Object> arguments =
        (List<Object>) ((JavascriptExecutor) driver).executeScript(key, 1, true, element);

    Assertions.assertEquals(List.of(1L, true, element), arguments);
  }

  @Test
  public void mutatedElements() {
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    CopyOnWriteArrayList<WebElement> mutations = new CopyOnWriteArrayList<>();

    ((HasLogEvents) driver).onLogEvent(domMutation(e -> mutations.add(e.getElement())));

    driver.findElement(By.id("reveal")).click();

    wait.until(_d -> !mutations.isEmpty());
    Assertions.assertEquals(mutations.get(0), driver.findElement(By.id("revealed")));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs#L21-L22)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs

```cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class ScriptTest : BaseChromeTest
    {
        [TestMethod]
        public async Task PinScript()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/xhtmlTest.html";
            var element = driver.FindElement(By.Id("id1"));

            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);

            var expected = new List<object>
            {
                1L,
                true,
                element
            };
            CollectionAssert.AreEqual(expected, (ICollection)arguments);
        }

        [TestMethod]
        public async Task MutatedElements()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            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();

            driver.FindElement(By.Id("reveal")).Click();
            
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !mutations.IsNullOrEmpty());
            await monitor.DisableDomMutationMonitoring();
            monitor.StopEventMonitoring();

            var revealed = driver.FindElement(By.Id("revealed")); 
            Assert.AreEqual(revealed, mutations[0]);
        }
    }
}
```

```rb
    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/script_spec.rb#L12-L13)

##### /examples/ruby/spec/bidi/cdp/script\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Script' do
  let(:driver) { start_session }

  it 'pins script' do
    driver.get('https://www.selenium.dev/selenium/web/xhtmlTest.html')
    element = driver.find_element(id: 'id1')

    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)

    expect(arguments).to eq([1, true, element])
  end

  it 'gets mutated elements' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'

    mutations = []
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }

    driver.find_element(id: 'reveal').click
    Selenium::WebDriver::Wait.new(timeout: 30).until { mutations.any? }

    expect(mutations).to include(driver.find_element(id: 'revealed'))
  end
end
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).mutation_events() as event:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_script.py#L10-L11)

##### /examples/python/tests/bidi/cdp/test\_script.py

```py
import pytest
import trio
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

@pytest.mark.trio
async def test_mutation(driver):
    async with driver.bidi_connection() as session:
        async with Log(driver, session).mutation_events() as event:
            await trio.to_thread.run_sync(lambda: driver.get('https://www.selenium.dev/selenium/web/dynamic.html'))
            await trio.to_thread.run_sync(lambda: WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "reveal"))))
            await trio.to_thread.run_sync(lambda: driver.find_element(By.ID, "reveal").click())

    assert event["element"] == driver.find_element(By.ID, "revealed")
```

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs#L39-L46)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs

```cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class ScriptTest : BaseChromeTest
    {
        [TestMethod]
        public async Task PinScript()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/xhtmlTest.html";
            var element = driver.FindElement(By.Id("id1"));

            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);

            var expected = new List<object>
            {
                1L,
                true,
                element
            };
            CollectionAssert.AreEqual(expected, (ICollection)arguments);
        }

        [TestMethod]
        public async Task MutatedElements()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            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();

            driver.FindElement(By.Id("reveal")).Click();
            
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !mutations.IsNullOrEmpty());
            await monitor.DisableDomMutationMonitoring();
            monitor.StopEventMonitoring();

            var revealed = driver.FindElement(By.Id("revealed")); 
            Assert.AreEqual(revealed, mutations[0]);
        }
    }
}
```

```rb
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/script_spec.rb#L22)

##### /examples/ruby/spec/bidi/cdp/script\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Script' do
  let(:driver) { start_session }

  it 'pins script' do
    driver.get('https://www.selenium.dev/selenium/web/xhtmlTest.html')
    element = driver.find_element(id: 'id1')

    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)

    expect(arguments).to eq([1, true, element])
  end

  it 'gets mutated elements' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'

    mutations = []
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }

    driver.find_element(id: 'reveal').click
    Selenium::WebDriver::Wait.new(timeout: 30).until { mutations.any? }

    expect(mutations).to include(driver.find_element(id: 'revealed'))
  end
end
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Add Example](/documentation/about/contributing/#creating-examples)

Última modificação November 5, 2024: [Add examples for Drivers HTTP Client in Java and Python (#2041) (2ce6752bfc8)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/2ce6752bfc8a0d1643519fbbe6934f903e33d097)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/interactions/windows/
----

# 同窗口和标签一起工作

```java
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L16-L20)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L16-L18)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L17-L21)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
driver.window_handle
```

```javascript
await driver.getWindowHandle();
```

```kotlin
driver.windowHandle
```

```java
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L22-L29)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L22-L32)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L23-L30)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
    # 存储原始窗口的 ID
original_window = driver.window_handle

    #检查一下，我们还没有打开其他的窗口
assert(driver.window_handles.length == 1,'Expected one window')

    #点击在新窗口中打开的链接
driver.find_element(link:'new window').click

    #等待新窗口或标签页
wait.until {driver.window_handles.length == 2}

    #循环执行，直到找到一个新的窗口句柄
driver.window_handles.each do |handle|
if handle != original_window
driver.switch_to.window handle
break
end
end

    #等待新标签页完成加载内容
wait.until {driver.title =='Selenium documentation'}
```

```javascript
// 存储原始窗口的 ID
const originalWindow = await driver.getWindowHandle();

// 检查一下，我们还没有打开其他的窗口
assert((await driver.getAllWindowHandles()).length === 1);

// 点击在新窗口中打开的链接
await driver.findElement(By.linkText('new window')).click();

// 等待新窗口或标签页
await driver.wait(async () => (await driver.getAllWindowHandles()).length === 2,
10000
);

// 循环执行，直到找到一个新的窗口句柄
const windows = await driver.getAllWindowHandles();
windows.forEach(async handle => {if (handle !== originalWindow) {await driver.switchTo().window(handle);
}
});

// 等待新标签页完成加载内容
await driver.wait(until.titleIs('Selenium documentation'), 10000);
```

```kotlin
// 存储原始窗口的 ID
val originalWindow = driver.getWindowHandle()

// 检查一下，我们还没有打开其他的窗口
assert(driver.getWindowHandles().size() === 1)

// 点击在新窗口中打开的链接
driver.findElement(By.linkText("new window")).click()

// 等待新窗口或标签页
wait.until(numberOfWindowsToBe(2))

// 循环执行，直到找到一个新的窗口句柄
for (windowHandle in driver.getWindowHandles()) {
if (!originalWindow.contentEquals(windowHandle)) {
driver.switchTo().window(windowHandle)
break
}
}

// 等待新标签页完成加载内容
wait.until(titleIs("Selenium documentation"))
```

```java
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L31-L34)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L46-L46)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L32-L35)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
    #关闭标签页或窗口
driver.close

    #切回到之前的标签页或窗口
driver.switch_to.window original_window
```

```javascript
//关闭标签页或窗口
await driver.close();

//切回到之前的标签页或窗口
await driver.switchTo().window(originalWindow);
```

```kotlin
//关闭标签页或窗口
driver.close()

//切回到之前的标签页或窗口
driver.switchTo().window(originalWindow)
```

```java
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L36-L42)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L53-L58)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L37-L43)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

打开新标签页并切换到新标签页

```rb
    driver.switch_to.new_window(:tab)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/windows_spec.rb#L9)

##### /examples/ruby/spec/interactions/windows\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Windows' do
  let(:driver) { start_session }

  it 'opens new tab' do
    driver.switch_to.new_window(:tab)

    expect(driver.window_handles.size).to eq 2
  end

  it 'opens new window' do
    driver.switch_to.new_window(:window)

    expect(driver.window_handles.size).to eq 2
  end
end
```

打开一个新窗口并切换到新窗口

```rb
    driver.switch_to.new_window(:window)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/windows_spec.rb#L15)

##### /examples/ruby/spec/interactions/windows\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Windows' do
  let(:driver) { start_session }

  it 'opens new tab' do
    driver.switch_to.new_window(:tab)

    expect(driver.window_handles.size).to eq 2
  end

  it 'opens new window' do
    driver.switch_to.new_window(:window)

    expect(driver.window_handles.size).to eq 2
  end
end
```

// 打开新标签页并切换到新标签页

```js
    await driver.switchTo().newWindow('tab');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L70)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

// 打开一个新窗口并切换到新窗口

```js
    await driver.switchTo().newWindow('window');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L75)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// 打开新标签页并切换到新标签页
driver.switchTo().newWindow(WindowType.TAB)

// 打开一个新窗口并切换到新窗口
driver.switchTo().newWindow(WindowType.WINDOW)
```

```java
        //quitting driver
        driver.quit(); //close all windows
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L44-L45)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L13-L13)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //quitting driver
              driver.Quit(); //close all windows
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L45-L46)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
driver.quit
```

```javascript
await driver.quit();
```

```kotlin
driver.quit()
```

```java
/**
* 使用 JUnit 的例子
* https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
*/
@AfterAll
public static void tearDown() {
    driver.quit();
}
```

```python
    # unittest teardown
    # https://docs.python.org/3/library/unittest.html?highlight=teardown#unittest.TestCase.tearDown
def tearDown(self):
self.driver.quit()
```

```csharp
/*
使用 Visual Studio 的 UnitTesting 的例子
https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.aspx
*/
[TestCleanup]
public void TearDown()
{driver.Quit();
}
```

```ruby
    # UnitTest Teardown
    # https://www.rubydoc.info/github/test-unit/test-unit/Test/Unit/TestCase
def teardown
@driver.quit
end
```

```javascript
/**
* 使用 Mocha 的例子
* https://mochajs.org/#hooks
  */
  after('Tear down', async function () {await driver.quit();
  });
  
```

```kotlin
/**
* 使用 JUnit 的例子
* https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
*/
@AfterAll
fun tearDown() {
	driver.quit()
}
```

```java
try {
    //WebDriver 代码…
} finally {
    driver.quit();
}
```

```python
try:
    #WebDriver 代码…
finally:
driver.quit()
```

```csharp
try {//WebDriver 代码…} finally {driver.Quit();
}
```

```ruby
begin
    #WebDriver 代码…
ensure
driver.quit
end
```

```javascript
try {//WebDriver 代码…} finally {await driver.quit();
}
```

```kotlin
try {//WebDriver 代码…} finally {driver.quit()
}
```

Python 的 WebDriver 现在支持 Python 上下文管理器，当使用 with 关键字时，可以在执行结束时自动退出驱动程序。

```python
with webdriver.Firefox() as driver:
  # WebDriver 代码…

# 在此缩进位置后 WebDriver 会自动退出
```

```java
// 分别获取每个尺寸
int width = driver.manage().window().getSize().getWidth();
int height = driver.manage().window().getSize().getHeight();

// 或者存储尺寸并在以后查询它们
Dimension size = driver.manage().window().getSize();
int width1 = size.getWidth();
int height1 = size.getHeight();
```

```python
    # 分别获取每个尺寸
width = driver.get_window_size().get("width")
height = driver.get_window_size().get("height")

    # 或者存储尺寸并在以后查询它们
size = driver.get_window_size()
width1 = size.get("width")
height1 = size.get("height")
```

```csharp
// 分别获取每个尺寸
int width = driver.Manage().Window.Size.Width;
int height = driver.Manage().Window.Size.Height;

// 或者存储尺寸并在以后查询它们
System.Drawing.Size size = driver.Manage().Window.Size;
int width1 = size.Width;
int height1 = size.Height;
```

```ruby
    # 分别获取每个尺寸
width = driver.manage.window.size.width
height = driver.manage.window.size.height

    # 或者存储尺寸并在以后查询它们
size = driver.manage.window.size
width1 = size.width
height1 = size.height
```

分别获取每个尺寸

```js
    const { width, height } = await driver.manage().window().getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L93)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

或者存储尺寸并在以后查询它们

```js
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L96-L98)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// 分别获取每个尺寸
val width = driver.manage().window().size.width
val height = driver.manage().window().size.height

// 或者存储尺寸并在以后查询它们
val size = driver.manage().window().size
val width1 = size.width
val height1 = size.height
```

```java
driver.manage().window().setSize(new Dimension(1024, 768));
```

```python
driver.set_window_size(1024, 768)
```

```csharp
driver.Manage().Window.Size = new Size(1024, 768);
```

```ruby
driver.manage.window.resize_to(1024,768)
```

```javascript
await driver.manage().window().setRect({width: 1024, height: 768});
```

```kotlin
driver.manage().window().size = Dimension(1024, 768)
```

```java
// 分别获取每个尺寸
int x = driver.manage().window().getPosition().getX();
int y = driver.manage().window().getPosition().getY();

// 或者存储尺寸并在以后查询它们
Point position = driver.manage().window().getPosition();
int x1 = position.getX();
int y1 = position.getY();
```

```python
    # 分别获取每个尺寸
x = driver.get_window_position().get('x')
y = driver.get_window_position().get('y')

    # 或者存储尺寸并在以后查询它们
position = driver.get_window_position()
x1 = position.get('x')
y1 = position.get('y')
```

```csharp
// 分别获取每个尺寸
int x = driver.Manage().Window.Position.X;
int y = driver.Manage().Window.Position.Y;

// 或者存储尺寸并在以后查询它们
Point position = driver.Manage().Window.Position;
int x1 = position.X;
int y1 = position.Y;
```

```ruby
    #Access each dimension individually
x = driver.manage.window.position.x
y = driver.manage.window.position.y

    # Or store the dimensions and query them later
rect  = driver.manage.window.rect
x1 = rect.x
y1 = rect.y
```

分别获取每个尺寸

```js
    const { x, y } = await driver.manage().window().getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L108)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

或者存储尺寸并在以后查询它们

```js
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L111-L113)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// 分别获取每个尺寸
val x = driver.manage().window().position.x
val y = driver.manage().window().position.y

// 或者存储尺寸并在以后查询它们
val position = driver.manage().window().position
val x1 = position.x
val y1 = position.y
```

```java
// 将窗口移动到主显示器的左上角
driver.manage().window().setPosition(new Point(0, 0));
```

```python
    # 将窗口移动到主显示器的左上角
driver.set_window_position(0, 0)
```

```csharp
// 将窗口移动到主显示器的左上角
driver.Manage().Window.Position = new Point(0, 0);
```

```ruby
driver.manage.window.move_to(0,0)
```

```javascript
// 将窗口移动到主显示器的左上角
await driver.manage().window().setRect({x: 0, y: 0});
```

```kotlin
// 将窗口移动到主显示器的左上角
driver.manage().window().position = Point(0,0)
```

```java
driver.manage().window().maximize();
```

```python
driver.maximize_window()
```

```csharp
driver.Manage().Window.Maximize();
```

```ruby
driver.manage.window.maximize
```

```javascript
await driver.manage().window().maximize();
```

```kotlin
driver.manage().window().maximize()
```

```java
driver.manage().window().minimize();
```

```python
driver.minimize_window()
```

```csharp
driver.Manage().Window.Minimize();
```

```ruby
driver.manage.window.minimize
```

```javascript
await driver.manage().window().minimize();
```

```kotlin
driver.manage().window().minimize()
```

```java
driver.manage().window().fullscreen();
```

```python
driver.fullscreen_window()
```

```csharp
driver.Manage().Window.FullScreen();
```

```ruby
driver.manage.window.full_screen
```

```javascript
await driver.manage().window().fullscreen();
```

```kotlin
driver.manage().window().fullscreen()
```

```java
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.*;
import org.openqa.selenium.*;

public class SeleniumTakeScreenshot {
	public static void main(String args[]) throws IOException {
		WebDriver driver = new ChromeDriver();
		driver.get("http://www.example.com");
		File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
		FileUtils.copyFile(scrFile, new File("./image.png"));
		driver.quit();
	}
}
```

```python
from selenium import webdriver

driver = webdriver.Chrome()

    # Navigate to url
driver.get("http://www.example.com")

    # Returns and base64 encoded string into image
driver.save_screenshot('./image.png')

driver.quit()
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;

    var driver = new ChromeDriver();
    driver.Navigate().GoToUrl("http://www.example.com");
    Screenshot screenshot = (driver as ITakesScreenshot).GetScreenshot();
    screenshot.SaveAsFile("screenshot.png", ScreenshotImageFormat.Png); // Format values are Bmp, Gif, Jpeg, Png, Tiff
```

```ruby
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
driver.get 'https://example.com/'

    # Takes and Stores the screenshot in specified path
driver.save_screenshot('./image.png')

end
```

```js
    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L56-L59)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
import com.oracle.tools.packager.IOUtils.copyFile
import org.openqa.selenium.*
import org.openqa.selenium.chrome.ChromeDriver
import java.io.File

fun main(){
val driver =  ChromeDriver()
driver.get("https://www.example.com")
val scrFile = (driver as TakesScreenshot).getScreenshotAs<File>(OutputType.FILE)
copyFile(scrFile, File("./image.png"))
driver.quit()
}
```

```java
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.File;
import java.io.IOException;

public class SeleniumelementTakeScreenshot {
public static void main(String args[]) throws IOException {
	WebDriver driver = new ChromeDriver();
		driver.get("https://www.example.com");
		WebElement element = driver.findElement(By.cssSelector("h1"));
		File scrFile = element.getScreenshotAs(OutputType.FILE);
		FileUtils.copyFile(scrFile, new File("./image.png"));
		driver.quit();
	}
}
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

    # Navigate to url
driver.get("http://www.example.com")

ele = driver.find_element(By.CSS_SELECTOR, 'h1')

    # Returns and base64 encoded string into image
ele.screenshot('./image.png')

driver.quit()
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;

    // Webdriver
    var driver = new ChromeDriver();
    driver.Navigate().GoToUrl("http://www.example.com");

    // Fetch element using FindElement
    var webElement = driver.FindElement(By.CssSelector("h1"));

    // Screenshot for the element
    var elementScreenshot = (webElement as ITakesScreenshot).GetScreenshot();
    elementScreenshot.SaveAsFile("screenshot_of_element.png");
```

```ruby
    # Works with Selenium4-alpha7 Ruby bindings and above
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
driver.get 'https://example.com/'
ele = driver.find_element(:css, 'h1')

    # Takes and Stores the element screenshot in specified path
ele.save_screenshot('./image.jpg')
end
```

```js
    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L44-L48)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
import org.apache.commons.io.FileUtils
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.*
import java.io.File

fun main() {
val driver = ChromeDriver()
driver.get("https://www.example.com")
val element = driver.findElement(By.cssSelector("h1"))
val scrFile: File = element.getScreenshotAs(OutputType.FILE)
FileUtils.copyFile(scrFile, File("./image.png"))
driver.quit()
}
```

```java
//Creating the JavascriptExecutor interface object by Type casting
JavascriptExecutor js = (JavascriptExecutor)driver;
//Button Element
WebElement button =driver.findElement(By.name("btnLogin"));
//Executing JavaScript to click on element
js.executeScript("arguments[0].click();", button);
//Get return value from script
String text = (String) js.executeScript("return arguments[0].innerText", button);
//Executing JavaScript directly
js.executeScript("console.log('hello world')");
```

```python
    # Stores the header element
header = driver.find_element(By.CSS_SELECTOR, "h1")

    # Executing JavaScript to capture innerText of header element
driver.execute_script('return arguments[0].innerText', header)
```

```csharp
//creating Chromedriver instance
	IWebDriver driver = new ChromeDriver();
	//Creating the JavascriptExecutor interface object by Type casting
	IJavaScriptExecutor js = (IJavaScriptExecutor) driver;
	//Button Element
	IWebElement button = driver.FindElement(By.Name("btnLogin"));
	//Executing JavaScript to click on element
	js.ExecuteScript("arguments[0].click();", button);
	//Get return value from script
	String text = (String)js.ExecuteScript("return arguments[0].innerText", button);
	//Executing JavaScript directly
	js.ExecuteScript("console.log('hello world')");
```

```ruby
    # Stores the header element
header = driver.find_element(css: 'h1')

    # Get return value from script
result = driver.execute_script("return arguments[0].innerText", header)

    # Executing JavaScript directly
driver.execute_script("alert('hello world')")
```

```js
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L33-L37)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Stores the header element
val header = driver.findElement(By.cssSelector("h1"))

// Get return value from script
val result = driver.executeScript("return arguments[0].innerText", header)

// Executing JavaScript directly
driver.executeScript("alert('hello world')")
```

```java
import org.openqa.selenium.print.PrintOptions;

driver.get("https://www.selenium.dev");
printer = (PrintsPage) driver;

PrintOptions printOptions = new PrintOptions();
printOptions.setPageRanges("1-2");

Pdf pdf = printer.print(printOptions);
String content = pdf.getContent();
```

```python
from selenium.webdriver.common.print_page_options import PrintOptions

    print_options = PrintOptions()
    print_options.page_ranges = ['1-2']

    driver.get("printPage.html")

    base64code = driver.print_page(print_options)
```

```csharp
// code sample not available please raise a PR
```

```ruby
driver.navigate_to 'https://www.selenium.dev'

    base64encodedContent = driver.print_page(orientation: 'landscape')
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L22-L25)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
driver.get("https://www.selenium.dev")
val printer = driver as PrintsPage

val printOptions = PrintOptions()
printOptions.setPageRanges("1-2")

val pdf: Pdf = printer.print(printOptions)
val content = pdf.content
```

最后修改 May 11, 2026: [Move Python examples in Windows interactions docs (#2629) (d368a9324d6)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/d368a9324d6aa6bb62c016bb5572d28966a7f091)

----
url: https://www.selenium.dev/ja/documentation/test_practices/discouraged/test_dependency/
----

# テストの依存関係

自動テストに関する一般的な考え方と誤解は、特定のテスト順序に関するものです。 テストは **任意** の順序で実行でき、成功するために完了するために他のテストに依存してはなりません。

----
url: https://www.selenium.dev/pt-br/_print/documentation/webdriver/support_features/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/webdriver/support_features/).

# Recursos de suporte

As classes de suporte fornecem características opcionais de nível superior.

* 1: [Command Listeners](#pg-c11d90018b3105dae8c565ff7258c45c)
* 2: [Trabalhando com cores](#pg-64b6f497f154a3e1419884438ccac857)
* 3: [ThreadGuard](#pg-25d02816398c5d9aedeb1adf2da757cd)
* 4: [Trabalhando com elementos select](#pg-13b6577722718e297cce9a3a8b5813d8)
* 5:[](#pg-c3f3e2b076a631603223e406a7ccf951)

As bibliotecas principais do Selenium tentam ser de baixo nível e não opinativas. As classes de suporte em cada linguagem fornecem invólucros opinativos para interações comuns que podem ser usadas para simplificar alguns comportamentos.

# 1 - Command Listeners

These allow you to execute custom actions in every time specific Selenium commands are sent

*
*
*
*
*
*

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

# 2 - Trabalhando com cores

```java
import org.openqa.selenium.support.Color;
  
```

```python
from selenium.webdriver.support.color import Color
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
include Selenium::WebDriver::Support
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
import org.openqa.selenium.support.Color
```

```java
private final Color HEX_COLOUR = Color.fromString("#2F7ED8");
private final Color RGB_COLOUR = Color.fromString("rgb(255, 255, 255)");
private final Color RGB_COLOUR = Color.fromString("rgb(40%, 20%, 40%)");
private final Color RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)");
private final Color RGBA_COLOUR = Color.fromString("rgba(40%, 20%, 40%, 0.5)");
private final Color HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)");
private final Color HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)");
  
```

```python
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
  
```

```javascript
// Essa funcionalidade não está implementada - Nos ajude enviando um PR implementando essa funcionalidade
  
```

```kotlin
private val HEX_COLOUR = Color.fromString("#2F7ED8")
private val RGB_COLOUR = Color.fromString("rgb(255, 255, 255)")
private val RGB_COLOUR_PERCENT = Color.fromString("rgb(40%, 20%, 40%)")
private val RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)")
private val RGBA_COLOUR_PERCENT = Color.fromString("rgba(40%, 20%, 40%, 0.5)")
private val HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)")
private val HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)")
  
```

```java
private final Color BLACK = Color.fromString("black");
private final Color CHOCOLATE = Color.fromString("chocolate");
private final Color HOTPINK = Color.fromString("hotpink");
  
```

```python
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
  
```

```javascript
// Essa funcionalidade não está implementada - Nos ajude enviando um PR implementando essa funcionalidade
  
```

```kotlin
private val BLACK = Color.fromString("black")
private val CHOCOLATE = Color.fromString("chocolate")
private val HOTPINK = Color.fromString("hotpink")
  
```

```java
private final Color TRANSPARENT = Color.fromString("transparent");
  
```

```python
TRANSPARENT = Color.from_string('transparent')
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
TRANSPARENT = Color.from_string('transparent')
  
```

```javascript
// Essa funcionalidade não está implementada - Nos ajude enviando um PR implementando essa funcionalidade
  
```

```kotlin
private val TRANSPARENT = Color.fromString("transparent")
  
```

```java
Color loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"));

Color loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"));
  
```

```python
login_button_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('color'))

login_button_background_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('background-color'))
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
login_button_colour = Color.from_string(driver.find_element(id: 'login').css_value('color'))

login_button_background_colour = Color.from_string(driver.find_element(id: 'login').css_value('background-color'))
  
```

```javascript
// Essa funcionalidade não está implementada - Nos ajude enviando um PR implementando essa funcionalidade
  
```

```kotlin
val loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"))

val loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"))
  
```

```java
assert loginButtonBackgroundColour.equals(HOTPINK);
  
```

```python
assert login_button_background_colour == HOTPINK
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
assert(login_button_background_colour == HOTPINK)
  
```

```javascript
// Essa funcionalidade não está implementada - Nos ajude enviando um PR implementando essa funcionalidade
  
```

```kotlin
assert(loginButtonBackgroundColour.equals(HOTPINK))
  
```

```java
assert loginButtonBackgroundColour.asHex().equals("#ff69b4");
assert loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)");
assert loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)");
  
```

```python
assert login_button_background_colour.hex == '#ff69b4'
assert login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)'
assert login_button_background_colour.rgb == 'rgb(255, 105, 180)'
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
assert(login_button_background_colour.hex == '#ff69b4')
assert(login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)')
assert(login_button_background_colour.rgb == 'rgb(255, 105, 180)')
  
```

```javascript
// Essa funcionalidade não está implementada - Nos ajude enviando um PR implementando essa funcionalidade
  
```

```kotlin
assert(loginButtonBackgroundColour.asHex().equals("#ff69b4"))
assert(loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)"))
assert(loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)"))
  
```

As cores não são mais um problema.

# 3 - ThreadGuard

Esta classe está disponível apenas no Java Binding

ThreadGuard verifica se um driver é chamado apenas da mesma thread que o criou. Problemas de threading, especialmente durante a execução de testes em paralelo, podem ter erros misteriosos e difíceis de diagnosticar. Usar este wrapper evita esta categoria de erros e gerará uma exceção quando isso acontecer.

O exemplo a seguir simula um conflito de threads:

```java
public class DriverClash {
  //thread main (id 1) criou este driver
  private WebDriver protectedDriver = ThreadGuard.protect(new ChromeDriver()); 

  static {
    System.setProperty("webdriver.chrome.driver", "<Set path to your Chromedriver>");
  }
  
  //Thread-1 (id 24) está chamando o mesmo driver causando o conflito
  Runnable r1 = () -> {protectedDriver.get("https://selenium.dev");};
  Thread thr1 = new Thread(r1);
   
  void runThreads(){
    thr1.start();
  }

  public static void main(String[] args) {
    new DriverClash().runThreads();
  }
}
```

O resultado mostrado abaixo:

```text
Exception in thread "Thread-1" org.openqa.selenium.WebDriverException:
Thread safety error; this instance of WebDriver was constructed
on thread main (id 1)and is being accessed by thread Thread-1 (id 24)
This is not permitted and *will* cause undefined behaviour
```

# 4 - Trabalhando com elementos select

```html
<select name="selectomatic">
    <option selected="selected" id="non_multi_option" value="one">One</option>
    <option value="two">Two</option>
    <option value="four">Four</option>
    <option value="still learning how to count, apparently">Still learning how to count, apparently</option>
</select>
```

### Multiple select

This select list allows selecting and deselecting more than one option at a time. This only applies to `<select>` elements with the `multiple` attribute.

```html
<select name="multi" id="multi" multiple="multiple">
    <option selected="selected" value="eggs">Eggs</option>
    <option value="ham">Ham</option>
    <option selected="selected" value="sausages">Sausages</option>
    <option value="onion gravy">Onion gravy</option>
</select>
```

```java
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L23-L24)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L9-L10)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L23-L24)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L13-L14)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js

  it('Select an option', async function () {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L18-L19)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L20-L21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        List<WebElement> optionList = select.getOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L51)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    option_list = select.options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L37)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            IList<IWebElement> optionList = select.Options;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L52)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    option_list = select.options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L40)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L45)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val optionList = select.getOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L48)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L54)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    selected_option_list = select.all_selected_options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L40)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L56)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    selected_option_list = select.selected_options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L43)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L51)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val selectedOptionList = select.getAllSelectedOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L51)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByVisibleText("Four");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L30)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_visible_text('Four')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L16)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByText("Four");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L30)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:text, 'Four')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L20)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L25)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByVisibleText("Four")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L27)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByValue("two");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L33)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_value('two')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L19)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByValue("two");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L33)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:value, 'two')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L23)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await fourElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L28)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByValue("two")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L30)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByIndex(3);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L36)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_index(3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L22)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByIndex(3);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L36)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:index, 3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L26)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await twoElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L31)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByIndex(3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L33)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

### Disabled options

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

Options with a `disabled` attribute may not be selected.

```html
    <select name="single_disabled">
      <option id="sinlge_disabled_1" value="enabled">Enabled</option>
      <option id="sinlge_disabled_2" value="disabled" disabled="disabled">Disabled</option>
    </select>
```

*
*
*
*
*
*

```java
        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L77-L79)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L60-L61)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L77)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L62-L64)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L73-L76)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L74-L76)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.deselectByValue("eggs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L66)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.deselect_by_value('eggs')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L49)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.DeselectByValue("eggs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L65)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.deselect_by(:value, 'eggs')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L52)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await gravyElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L63)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.deselectByValue("eggs")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

# 5 -

```py
    wait = WebDriverWait(driver, timeout=2)
    wait.until(EC.visibility_of_element_located((By.ID, "revealed")))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_expected_conditions.py#L14-L15)

##### /examples/python/tests/support/test\_expected\_conditions.py

```py
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

# Expected Conditions API Documentation:
# https://www.selenium.dev/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html


def test_expected_condition(driver):
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html")
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(EC.visibility_of_element_located((By.ID, "revealed")))

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"
```

.NET stopped supporting Expected Conditions in Selenium 4 to minimize maintenance hassle and redundancy.

Ruby makes frequent use of blocks, procs and lambdas and does not need Expected Conditions classes

----
url: https://www.selenium.dev/ja/_print/documentation/legacy/selenium_2/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/legacy/selenium_2/).

# Selenium 2

Selenium 2 was a rewrite of Selenium 1 that was implemented with WebDriver code.

* 1: [RCからWebDriverへの移行](#pg-a933946e45b79ed277508ff2adf95523)
* 2: [リモートWebDriverサーバー](#pg-3cf3554f61b84dbd1b188df5fe81a963)

# 1 - RCからWebDriverへの移行

```java
Selenium selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.yoursite.com");
selenium.start();
```

これは次のように置き換える必要があります。

```java
WebDriver driver = new FirefoxDriver();
Selenium selenium = new WebDriverBackedSelenium(driver, "http://www.yoursite.com");
```

## 次のステップ

テストがエラーなしで実行されたら、次の段階は実際のテストコードを移行してWebDriver APIを使用することです。 コードがどれだけ適切に抽象化されているかによって、これは短いプロセスまたは長いプロセスになります。 どちらの場合でも、アプローチは同じであり、簡単に要約できます。 編集するときに新しいAPIを使用するようにコードを変更します。

基になるWebDriver実装をSeleniumインスタンスから抽出する必要がある場合は、WrapsDriverにキャストするだけです。

```java
WebDriver driver = ((WrapsDriver) selenium).getWrappedDriver();
```

これにより、通常どおりSeleniumインスタンスの受け渡しを続けることができますが、必要に応じてWebDriverインスタンスのラップを解除できます。

ある時点で、コードベースは主に新しいAPIを使用します。 この時点で、WebDriverを使用して関係を反転し、オンデマンドでSeleniumインスタンスをインスタンス化できます。

```java
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);
```

## 一般的な問題

幸いなことに、この移行を最初に行ったのはあなたではないので、他の人が経験した一般的な問題とその解決方法を以下に示します。

### クリックと入力がより完全に

Selenium RCテストの一般的なパターンは、以下のとおりです。

```java
selenium.type("name", "exciting tex");
selenium.keyDown("name", "t");
selenium.keyPress("name", "t");
selenium.keyUp("name", "t");
```

```java
Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(30));
WebElement element= wait.until(visibilityOfElementLocated(By.id("some_id")));
```

“visibilityOfElementLocated” は次のように実装されます。

```java
public ExpectedCondition<WebElement> visibilityOfElementLocated(final By locator) {
  return new ExpectedCondition<WebElement>() {
    public WebElement apply(WebDriver driver) {
      WebElement toReturn = driver.findElement(locator);
      if (toReturn.isDisplayed()) {
        return toReturn;
      }
      return null;
    }
  };
}
```

これは複雑に見えるかもしれませんが、ほとんどすべての定型コードです。 唯一の興味深い点は、 “apply” メソッドが “null” でもBoolean.FALSEでもないものを返すまで、 “ExpectedCondition” が繰り返し評価されることです。

もちろん、これらの “wait” 呼び出しをすべて追加すると、コードが混乱する可能性があります。 その場合で、ニーズが単純な場合は、暗黙的な待機の使用を検討してください。

```java
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
```

```java
String name = selenium.getEval(
    "selenium.browserbot.findElement('id=foo', browserbot.getCurrentWindow()).tagName");
```

このようになります。

```java
WebElement element = driver.findElement(By.id("foo"));
String name = (String) ((JavascriptExecutor) driver).executeScript(
    "return arguments[0].tagName", element);
```

渡された “element” 変数が、JS標準の “arguments” 配列の最初の項目としてどのように表示されるかに注目してください。

### Executing Javascript Doesn’t Return Anything

WebDriverのJavascriptExecutorは、すべてのJSをラップし、匿名式として評価します。 これは、 “return” キーワードを使用する必要があることを意味します。

```java
String title = selenium.getEval("browserbot.getCurrentWindow().document.title");
```

このようになります。

```java
((JavascriptExecutor) driver).executeScript("return document.title;");
```

# 2 - リモートWebDriverサーバー

サーバーは、テストするブラウザーがインストールされたマシンで常に実行されます。 サーバーは、コマンドラインから、またはコード設定を通じて使用できます。

## コマンドラインからサーバーを起動する

一旦、`selenium-server-standalone-{VERSION}.jar`をダウンロードしたら、テストしたいブラウザーのあるコンピューターに配置します。 次に、jarを含むディレクトリから、次のコマンドを実行します。

```shell
java -jar selenium-server-standalone-{VERSION}.jar
```

## サーバーを実行するにあたって考慮すること

呼び出し元は、`Selenium#stop()`または`WebDriver#quit`を呼び出して、各セッションを適切に終了すべきです。

selenium-serverは、進行中の各セッションのメモリ内ログを保持します。 これらのログは、`Selenium#stop()`または`WebDriver#quit`が呼び出されるとクリアされます。 これらのセッションの終了を忘れると、サーバーでメモリリークが発生する可能性があります。 非常に長時間実行されるセッションを維持する場合は、時々停止または終了する必要があります（または-Xmx jvmオプションでメモリを増やします）。

## タイムアウト (version 2.21以降)

サーバーには2つの異なるタイムアウトがあり、次のように設定できます。

```shell
java -jar selenium-server-standalone-{VERSION}.jar -timeout=20 -browserTimeout=60
```

```java
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.security.SslSocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;

import javax.servlet.Servlet;
import java.io.File;

import org.openqa.selenium.remote.server.DriverServlet;

public class AppServer {
  private Server server = new Server();

  public AppServer() throws Exception {
    WebAppContext context = new WebAppContext();
    context.setContextPath("");
    context.setWar(new File("."));
    server.addHandler(context);

    context.addServlet(DriverServlet.class, "/wd/*");

    SelectChannelConnector connector = new SelectChannelConnector();
    connector.setPort(3001);
    server.addConnector(connector);

    server.start();
  }
}
```

----
url: https://www.selenium.dev/documentation/webdriver/troubleshooting/upgrade_to_selenium_4/
----

# Upgrade to Selenium 4

```java
DesiredCapabilities caps = DesiredCapabilities.firefox();
caps.setCapability("platform", "Windows 10");
caps.setCapability("version", "92");
caps.setCapability("build", myTestBuild);
caps.setCapability("name", myTestName);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), caps);
```

```javascript
caps = {};
caps['browserName'] = 'Firefox';
caps['platform'] = 'Windows 10';
caps['version'] = '92';
caps['build'] = myTestBuild;
caps['name'] = myTestName;
```

```csharp
DesiredCapabilities caps = new DesiredCapabilities();
caps.SetCapability("browserName", "firefox");
caps.SetCapability("platform", "Windows 10");
caps.SetCapability("version", "92");
caps.SetCapability("build", myTestBuild);
caps.SetCapability("name", myTestName);
var driver = new RemoteWebDriver(new Uri(CloudURL), caps);
```

```rb
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L123-L130)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```python
caps = {}
caps['browserName'] = 'firefox'
caps['platform'] = 'Windows 10'
caps['version'] = '92'
caps['build'] = my_test_build
caps['name'] = my_test_name
driver = webdriver.Remote(cloud_url, desired_capabilities=caps)
```

```java
FirefoxOptions browserOptions = new FirefoxOptions();
browserOptions.setPlatformName("Windows 10");
browserOptions.setBrowserVersion("92");
Map<String, Object> cloudOptions = new HashMap<>();
cloudOptions.put("build", myTestBuild);
cloudOptions.put("name", myTestName);
browserOptions.setCapability("cloud:options", cloudOptions);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), browserOptions);
```

```javascript
capabilities = {
  browserName: 'firefox',
  browserVersion: '92',
  platformName: 'Windows 10',
  'cloud:options': {
     build: myTestBuild,
     name: myTestName,
  }
}
```

```csharp
var browserOptions = new FirefoxOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "92";
var cloudOptions = new Dictionary<string, object>();
cloudOptions.Add("build", myTestBuild);
cloudOptions.Add("name", myTestName);
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);
var driver = new RemoteWebDriver(new Uri(CloudURL), browserOptions);
```

```rb
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L38-L47)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```python
from selenium.webdriver.firefox.options import Options as FirefoxOptions
options = FirefoxOptions()
options.browser_version = '92'
options.platform_name = 'Windows 10'
cloud_options = {}
cloud_options['build'] = my_test_build
cloud_options['name'] = my_test_name
options.set_capability('cloud:options', cloud_options)
driver = webdriver.Remote(cloud_url, options=options)
```

### Find element(s) utility methods in Java

The utility methods to find elements in the Java bindings (`FindsBy` interfaces) have been removed as they were meant for internal use only. The following code samples explain this better.

Finding a single element with `findElement*`

Before

```java

driver.findElementByClassName("className");
driver.findElementByCssSelector(".className");
driver.findElementById("elementId");
driver.findElementByLinkText("linkText");
driver.findElementByName("elementName");
driver.findElementByPartialLinkText("partialText");
driver.findElementByTagName("elementTagName");
driver.findElementByXPath("xPath");
```

After

```java

driver.findElement(By.className("className"));
driver.findElement(By.cssSelector(".className"));
driver.findElement(By.id("elementId"));
driver.findElement(By.linkText("linkText"));
driver.findElement(By.name("elementName"));
driver.findElement(By.partialLinkText("partialText"));
driver.findElement(By.tagName("elementTagName"));
driver.findElement(By.xpath("xPath"));
```

Finding a multiple elements with `findElements*`

Before

```java

driver.findElementsByClassName("className");
driver.findElementsByCssSelector(".className");
driver.findElementsById("elementId");
driver.findElementsByLinkText("linkText");
driver.findElementsByName("elementName");
driver.findElementsByPartialLinkText("partialText");
driver.findElementsByTagName("elementTagName");
driver.findElementsByXPath("xPath");
```

After

```java

driver.findElements(By.className("className"));
driver.findElements(By.cssSelector(".className"));
driver.findElements(By.id("elementId"));
driver.findElements(By.linkText("linkText"));
driver.findElements(By.name("elementName"));
driver.findElements(By.partialLinkText("partialText"));
driver.findElements(By.tagName("elementTagName"));
driver.findElements(By.xpath("xPath"));
```

## Upgrading dependencies

Check the subsections below to install Selenium 4 and have your project dependencies upgraded.

### Java

The process of upgrading Selenium depends on which build tool is being used. We will cover the most common ones for Java, which are [Maven](https://maven.apache.org/) and [Gradle](https://gradle.org/). The minimum Java version required is still 8.

#### Maven

Before

```xml

<dependencies>
  <!-- more dependencies ... -->
  <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.141.59</version>
  </dependency>
  <!-- more dependencies ... -->
</dependencies>
```

After

```xml

<dependencies>
    <!-- more dependencies ... -->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.4.0</version>
    </dependency>
    <!-- more dependencies ... -->
</dependencies>
```

After making the change, you could execute `mvn clean compile` on the same directory where the `pom.xml` file is.

#### Gradle

Before

```jsonpath

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.141.59'
}
test {
    useJUnitPlatform()
}
```

After

```jsonpath

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '4.4.0'
}
test {
    useJUnitPlatform()
}
```

After making the change, you could execute `./gradlew clean build` on the same directory where the `build.gradle` file is.

To check all the Java releases, you can head to [MVNRepository](https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java).

### C\#

The place to get updates for Selenium 4 in C# is [NuGet](https://www.nuget.org/). Under the [`Selenium.WebDriver`](https://www.nuget.org/packages/Selenium.WebDriver/4.4.0) package you can get the instructions to update to the latest version. Inside of Visual Studio, through the NuGet Package Manager you can execute:

```shell
PM> Install-Package Selenium.WebDriver -Version 4.4.0
```

### Python

The most important change to use Python is the minimum required version. Selenium 4 will require a minimum Python 3.7 or higher. More details can be found at the [Python Package Index](https://pypi.org/project/selenium/4.4.3/). To upgrade from the command line, you can execute:

```shell
pip install selenium==4.4.3
```

### Ruby

The update details for Selenium 4 can be seen at the [selenium-webdriver](https://rubygems.org/gems/selenium-webdriver/versions/4.4.0) gem in RubyGems. To install the latest version, you can execute:

```shell
gem install selenium-webdriver
```

To add it to your Gemfile:

```shell
gem 'selenium-webdriver', '~> 4.4.0'
```

### JavaScript

The selenium-webdriver package can be found at the Node package manager, [npmjs](https://www.npmjs.com). Selenium 4 can be found [here](https://www.npmjs.com/package/selenium-webdriver/v/4.4.0). To install it, you could either execute:

```shell
npm install selenium-webdriver
```

Or, update your package.json and run` npm install`:

```json
{
  "name": "selenium-tests",
  "version": "1.0.0",
  "dependencies": {
    "selenium-webdriver": "^4.4.0"
  }
}
```

## Potential errors and deprecation messages

Here is a set of code examples that will help to overcome the deprecation messages you might encounter after upgrading to Selenium 4.

### Java

#### Waits and Timeout

The parameters received in Timeout have switched from expecting `(long time, TimeUnit unit)` to expect `(Duration duration)`.

Before

```java

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(2, TimeUnit.MINUTES);
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
```

After

```java

driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().timeouts().scriptTimeout(Duration.ofMinutes(2));
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
```

Waits are also expecting different parameters now. `WebDriverWait` is now expecting a `Duration` instead of a `long` for timeout in seconds and milliseconds. The `withTimeout` and `pollingEvery` utility methods from `FluentWait` have switched from expecting `(long time, TimeUnit unit)` to expect `(Duration duration)`.

Before

```java

new WebDriverWait(driver, 3)
.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(30, TimeUnit.SECONDS)
  .pollingEvery(5, TimeUnit.SECONDS)
  .ignoring(NoSuchElementException.class);
```

After

```java

new WebDriverWait(driver, Duration.ofSeconds(3))
  .until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

  Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(Duration.ofSeconds(30))
  .pollingEvery(Duration.ofSeconds(5))
  .ignoring(NoSuchElementException.class);
```

#### Merging capabilities is no longer changing the calling object

It was possible to merge a different set of capabilities into another set, and it was mutating the calling object. Now, the result of the merge operation needs to be assigned.

Before

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options.merge(capabilities);

// As a result, the `options` object was getting modified.
```

After

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options = options.merge(capabilities);

// The result of the `merge` call needs to be assigned to an object.
```

#### Firefox Legacy

Before GeckoDriver was around, the Selenium project had a driver implementation to automate Firefox (version <48). However, this implementation is not needed anymore as it does not work in recent versions of Firefox. To avoid major issues when upgrading to Selenium 4, the `setLegacy` option will be shown as deprecated. The recommendation is to stop using the old implementation and rely only on GeckoDriver. The following code will show the `setLegacy` line deprecated after upgrading.

```java
FirefoxOptions options = new FirefoxOptions();
options.setLegacy(true);
```

#### `BrowserType`

The `BrowserType` interface has been around for a long time, however it is getting deprecated in favour of the new `Browser` interface.

Before

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", BrowserType.FIREFOX);
```

After

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", Browser.FIREFOX);
```

### C\#

#### `AddAdditionalCapability` is deprecated

Instead of it, `AddAdditionalOption` is recommended. Here is an example showing this:

Before

```cs

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalCapability("cloud:options", cloudOptions, true);
```

After

```cs

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);
```

### Python

#### `executable_path has been deprecated, please pass in a Service object`

In Selenium 4, you’ll need to set the driver’s `executable_path` from a Service object to prevent deprecation warnings. (Or don’t set the path and instead make sure that the driver you need is on the System PATH.)

Before

```python

from selenium import webdriver
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(
    executable_path=CHROMEDRIVER_PATH, 
    options=options
)
```

After

```python

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
options = webdriver.ChromeOptions()
service = ChromeService(executable_path=CHROMEDRIVER_PATH)
driver = webdriver.Chrome(service=service, options=options)
```

## Summary

We went through the major changes to be taken into consideration when upgrading to Selenium 4. Covering the different aspects to cover when test code is prepared for the upgrade, including suggestions on how to prevent potential issues that can show up when using the new version of Selenium. To finalize, we also covered a set of possible issues that you can bump into after upgrading, and we shared potential fixes for those issues.

*This was originally posted at <https://saucelabs.com/resources/articles/how-to-upgrade-to-selenium-4>*

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/interactions/cookies/
----

# Trabalhando com cookies

```java

    WebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L30-L32)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L5-L9)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L32-L34)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L9-L11)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L18)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

  const {Browser, Builder} = require("selenium-webdriver");
  const assert = require('assert')
  
  
  describe('Cookies', function() {
    let driver;
  
    before(async function() {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('Create a cookie', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // set a cookie on the current domain
      await driver.manage().addCookie({ name: 'key', value: 'value' });
    });
  
    it('Create cookies with sameSite', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
      await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
      await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
    });
  
    it('Read cookie', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // set a cookie on the current domain
      await driver.manage().addCookie({ name: 'foo', value: 'bar' });
  
      // Get cookie details with named cookie 'foo'
      await driver.manage().getCookie('foo').then(function(cookie) {
        assert.equal(cookie.value, 'bar');
      });
    });
  
    it('Read all cookies', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // Add few cookies
      await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
      await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
  
      // Get all Available cookies
      await driver.manage().getCookies().then(function(cookies) {
        assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
      });
    });
  
    it('Delete a cookie', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // Add few cookies
      await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
      await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
  
      // Delete a cookie with name 'test1'
      await driver.manage().deleteCookie('test1');
  
      // Get all Available cookies
      await driver.manage().getCookies().then(function(cookies) {
        assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
      });
    });
  
    it('Delete all cookies', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // Add few cookies
      await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
      await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
  
      // Delete all cookies
      await driver.manage().deleteAllCookies();
    });
  });
  
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")

        // Adds the cookie into current browser context
        driver.manage().addCookie(Cookie("key", "value"))
    } finally {
        driver.quit()
    }
}
  
```

```java
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L38-L42)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L13-L20)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L40-L44)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L17-L21)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L35-L38)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("foo", "bar"))

        // Get cookie details with named cookie 'foo'
        val cookie = driver.manage().getCookieNamed("foo")
        println(cookie)
    } finally {
        driver.quit()
    }
}  
  
```

```java
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L52-L66)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L24-L32)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L51-L64)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L26-L31)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L49-L51)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        driver.manage().addCookie(Cookie("test2", "cookie2"))

        // Get All available cookies
        val cookies = driver.manage().cookies
        println(cookies)
    } finally {
        driver.quit()
    }
}  
  
```

```java
        }
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L74-L77)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L35-L43)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L70-L73)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L40-L43)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L61-L62)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        val cookie1 = Cookie("test2", "cookie2")
        driver.manage().addCookie(cookie1)

        // delete a cookie with name 'test1'
        driver.manage().deleteCookieNamed("test1")
        
        // delete cookie by passing cookie object of current browsing context.
        driver.manage().deleteCookie(cookie1)
    } finally {
        driver.quit()
    }
}  
  
```

```java
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L100-L105)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L47-L55)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L92-L97)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L49-L54)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L77-L78)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        driver.manage().addCookie(Cookie("test2", "cookie2"))

        // deletes all cookies
        driver.manage().deleteAllCookies()
    } finally {
        driver.quit()
    }
}  
  
```

```java

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L112-L121)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L59-L71)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SameSiteCookie {
  class SameSiteCookie {
    static void Main(string[] args) {
      IWebDriver driver = new ChromeDriver();
      try {
        driver.Navigate().GoToUrl("http://www.example.com");

        var cookie1Dictionary = new System.Collections.Generic.Dictionary<string, object>() {
          { "name", "test1" }, { "value", "cookie1" }, { "sameSite", "Strict" } };
        var cookie1 = Cookie.FromDictionary(cookie1Dictionary);

        var cookie2Dictionary = new System.Collections.Generic.Dictionary<string, object>() {
          { "name", "test2" }, { "value", "cookie2" }, { "sameSite", "Lax" } };
        var cookie2 = Cookie.FromDictionary(cookie2Dictionary);

        driver.Manage().Cookies.AddCookie(cookie1);
        driver.Manage().Cookies.AddCookie(cookie2);

        System.Console.WriteLine(cookie1.SameSite);
        System.Console.WriteLine(cookie2.SameSite);
      } finally {
        driver.Quit();
      }
    }
  }
}
  
```

```ruby
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://www.example.com'
  # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
  driver.manage.add_cookie(name: "foo", value: "bar", same_site: "Strict")
  driver.manage.add_cookie(name: "foo1", value: "bar", same_site: "Lax")
  puts driver.manage.cookie_named('foo')
  puts driver.manage.cookie_named('foo1')
ensure
  driver.quit
end
  
```

```js
  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L24-L26)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("http://www.example.com")
        val cookie = Cookie.Builder("key", "value").sameSite("Strict").build()
        val cookie1 = Cookie.Builder("key", "value").sameSite("Lax").build()
        driver.manage().addCookie(cookie)
        driver.manage().addCookie(cookie1)
        println(cookie.getSameSite())
        println(cookie1.getSameSite())
    } finally {
        driver.quit()
    }
}
  
```

----
url: https://www.selenium.dev/pt-br/_print/documentation/webdriver/bidi/w3c/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/webdriver/bidi/w3c/).

# BiDirectional API (W3C compliant)

* 1: [Browsing Context](#pg-c50f9db2c97c81cb3478cd3ec104d6f3)
* 2: [Browsing Context](#pg-401a042c11486d0fb137095eb1aa1c26)
* 3: [Network](#pg-c4e08ae86feb4b63bb2c74e686e6c073)
* 4: [Script](#pg-b29dffc7e5a4b83059589c9144b9cbd9)
* 5: [BiDirectional API (W3C compliant)](#pg-336ab9ccad6265251b8ae1f1680997c9)

**Page being translated from English to Portuguese. Do you speak Portuguese? Help us to translate it by sending us pull requests!

The following list of APIs will be growing as the [WebDriver BiDirectional Protocol](https://w3c.github.io/webdriver-bidi/) 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](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=\&template=feature.md).

# 1 - Browsing Context

```java
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L44-L47)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L33-L35)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

    @Test
    void testNavigateToAUrl() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L58-L61)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L48-L50)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L37-L41)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L25-L28)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L50-L55)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L40-L43)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        Assertions.assertNotNull(browsingContext.getId());
        Assertions.assertNotNull(info.getNavigationId());
        Assertions.assertTrue(info.getUrl().contains("/bidi/logEntryAdded.html"));
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L64-L69)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L55-L58)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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"));
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L72-L80)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L67)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L83-L92)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L79-L82)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        Assertions.assertTrue(info.getChildren().get(0).getUrl().contains("formPage.html"));
    }

    @Test
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L95-L108)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L103-L109)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    }

    @Test
    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());
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L111-L123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L103-L109)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window2.close();

        Assertions.assertThrows(BiDiException.class, window2::getTree);
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L126-L133)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.20.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.20.0.0)

```js
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L426-L431)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext tab2 = new BrowsingContext(driver, WindowType.TAB);

        tab2.close();

        Assertions.assertThrows(BiDiException.class, tab2::getTree);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L136-L153)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L115-L118)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L157-L161)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L192-L194)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```js
    await window1.activate()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L204)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L169-L173)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.reload(undefined, 'complete')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L351)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    @Test
    void testDismissUserPromptWithText() {
        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";
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L220-L228)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.handleUserPrompt(true, userText)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L301)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        driver.get("https://www.selenium.dev/selenium/web/coordinates_tests/simple_page.html");

        WebElement element = driver.findElement(By.id("box"));
        Rectangle elementRectangle = element.getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L248-L252)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const response = await browsingContext.captureScreenshot()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L362)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    }

    @Test
    void textCaptureElementScreenshot() {
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L259-L268)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L165-L169)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L275-L280)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const response = await browsingContext.captureElementScreenshot(elementId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L184)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L304-L307)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.setViewport(250, 300)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L335)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L317-L322)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    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'],
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L145-L157)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        wait.until(visibilityOfElementLocated(By.id("imageButton"))).submit();
        wait.until(titleIs("We Arrive Here"));

        browsingContext.back();
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L330-L336)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.back()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L396)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L342-L352)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.forward()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L420)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L359-L365)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.traverseHistory(-1)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L378)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L34-L41)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L23-L28)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L54-L63)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L53-L62)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L81-88)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L70-L78)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L97-104)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L113-123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L86-L97)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L113-123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L150-163)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L170-L181)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0.0)

```js
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L105-L113)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

[Add Example](/documentation/about/contributing/#creating-examples)

# 2 - Browsing Context

```java
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ActionsTest.java#L41-L44)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ActionsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Input;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.interactions.Actions;

class ActionsTest extends BaseTest {
    private Input input;

    private String windowHandle;

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        windowHandle = driver.getWindowHandle();
        input = new Input(driver);
    }

    @Test
    void canPerformInputActions() {
        driver.get("https://www.selenium.dev/selenium/web/formSelectionPage.html");

        List<WebElement> options = driver.findElements(By.tagName("option"));

        Actions actions = new Actions(driver);
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());

        WebElement showButton = driver.findElement(By.name("showselected"));
        showButton.click();

        WebElement resultElement = driver.findElement(By.id("result"));
        Assertions.assertTrue(resultElement.getText().contains("roquefort parmigiano cheddar"));
        }

    @Test
    void canPerformReleaseAction() {
        driver.get("https://www.selenium.dev/selenium/web/bidi/release_action.html");

        WebElement inputTextBox = driver.findElement(By.id("keys"));

        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);

        List<Map<String, Object>> events =
                (List<Map<String, Object>>)
                        ((JavascriptExecutor) driver).executeScript("return allEvents.events");
        Assertions.assertEquals("KeyB", events.get(0).get("code"));
        Assertions.assertEquals("KeyA", events.get(1).get("code"));
        }
    }
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/input.spec.js#L27-L29)

##### /examples/javascript/test/bidirectional/input.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, Key, Builder} = require("selenium-webdriver")
const Input = require('selenium-webdriver/bidi/input')

describe('Input module', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can perform input action', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/formSelectionPage.html')

    let options = await driver.findElements(By.tagName('option'))

    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)

    let showButton = await driver.findElement(By.name('showselected'))
    showButton.click()

    let resultElement = await driver.findElement(By.id('result'))
    await resultElement.getText().then(function (text) {
      assert(text.includes('oquefort parmigiano cheddar'), `text is: ${text}`)
    })
  })

  it('can execute release in browsing context', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/bidi/release_action.html')

    let inputTextBox = await driver.findElement(By.id('keys'))

    await driver.executeScript('arguments[0].focus()', inputTextBox)

    const actions = driver.actions().keyDown('a').keyDown('b').getSequences()

    await input.perform(browsingContextId, actions)

    await driver.executeScript('resetEvents()')

    await input.release(browsingContextId)

    const events = await driver.executeScript('return allEvents.events')

    assert.strictEqual(events[0].code, 'KeyB')
    assert.strictEqual(events[1].code, 'KeyA')
  })
})
```

```java
        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ActionsTest.java#L59-L65)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ActionsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Input;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.interactions.Actions;

class ActionsTest extends BaseTest {
    private Input input;

    private String windowHandle;

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        windowHandle = driver.getWindowHandle();
        input = new Input(driver);
    }

    @Test
    void canPerformInputActions() {
        driver.get("https://www.selenium.dev/selenium/web/formSelectionPage.html");

        List<WebElement> options = driver.findElements(By.tagName("option"));

        Actions actions = new Actions(driver);
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());

        WebElement showButton = driver.findElement(By.name("showselected"));
        showButton.click();

        WebElement resultElement = driver.findElement(By.id("result"));
        Assertions.assertTrue(resultElement.getText().contains("roquefort parmigiano cheddar"));
        }

    @Test
    void canPerformReleaseAction() {
        driver.get("https://www.selenium.dev/selenium/web/bidi/release_action.html");

        WebElement inputTextBox = driver.findElement(By.id("keys"));

        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);

        List<Map<String, Object>> events =
                (List<Map<String, Object>>)
                        ((JavascriptExecutor) driver).executeScript("return allEvents.events");
        Assertions.assertEquals("KeyB", events.get(0).get("code"));
        Assertions.assertEquals("KeyA", events.get(1).get("code"));
        }
    }
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await input.release(browsingContextId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/input.spec.js#L55)

##### /examples/javascript/test/bidirectional/input.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, Key, Builder} = require("selenium-webdriver")
const Input = require('selenium-webdriver/bidi/input')

describe('Input module', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can perform input action', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/formSelectionPage.html')

    let options = await driver.findElements(By.tagName('option'))

    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)

    let showButton = await driver.findElement(By.name('showselected'))
    showButton.click()

    let resultElement = await driver.findElement(By.id('result'))
    await resultElement.getText().then(function (text) {
      assert(text.includes('oquefort parmigiano cheddar'), `text is: ${text}`)
    })
  })

  it('can execute release in browsing context', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/bidi/release_action.html')

    let inputTextBox = await driver.findElement(By.id('keys'))

    await driver.executeScript('arguments[0].focus()', inputTextBox)

    const actions = driver.actions().keyDown('a').keyDown('b').getSequences()

    await input.perform(browsingContextId, actions)

    await driver.executeScript('resetEvents()')

    await input.release(browsingContextId)

    const events = await driver.executeScript('return allEvents.events')

    assert.strictEqual(events[0].code, 'KeyB')
    assert.strictEqual(events[1].code, 'KeyA')
  })
})
```

[Add Example](/documentation/about/contributing/#creating-examples)

# 3 - Network

```java
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L36-L38)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    assert.notEqual(intercept, null)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L29)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L46-L50)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L34-L35)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                    responseDetails ->
                            network.continueWithAuth(
                                    responseDetails.getRequest().getRequestId(),
                                    new UsernameAndPassword("admin", "admin")));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L57-L64)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L42-L46)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                            // Does not handle the alert
                            network.continueWithAuthNoCredentials(responseDetails.getRequest().getRequestId()));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L74-L80)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L56-L60)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                            network.cancelAuth(responseDetails.getRequest().getRequestId()));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L90-L96)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L71-L75)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
            }
    }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L104-L108)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L30-L35)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L23-L29)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L45-L51)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L82-L88)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L62-L68)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L96-L102)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L101-L106)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

# 4 - Script

```java
        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));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L52-L75)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L32-L53)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L201-L210)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L202-L204)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L219-L229)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L222-L227)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L239-L242)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L237-L239)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L280-L283)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L279-L283)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L293-L299)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L292-L299)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            script.disownBrowsingContextScript(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L322-L322)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    await manager.disownBrowsingContextScript(id, boxId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L330-L330)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            script.disownRealmScript(realmId, List.of(boxId));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L375-L375)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    await manager.disownRealmScript(realmId, boxId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L372-L372)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L391-L392)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L383-L385)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L401-402)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L393-L395)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L411-412)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L403-L405)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L422-423)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L416-L416)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L463-463)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L424-L426)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
                script.removePreloadScript(id);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L486-486)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    await manager.removePreloadScript(scriptId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L471-L471)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L37-L51)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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,
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L26-L43)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L58-L68)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L52-L65)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L75-L85)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.19](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.19.0)

```js
    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()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L73-L86)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

[Add Example](/documentation/about/contributing/#creating-examples)

# 5 - BiDirectional API (W3C compliant)

```java
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L33-L39)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/logInspector.spec.js#L23-37)

##### /examples/javascript/test/bidirectional/logInspector.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const LogInspector = require('selenium-webdriver/bidi/logInspector');
const {Builder} = require("selenium-webdriver");


describe('Log Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test listen to console log', async function () {
    let logEntry = null
    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)

    await inspector.close()
  })

  it('test listen to javascript error log', async function () {
    let logEntry = null
    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')

    await inspector.close()
  })

  it('test retrieve stack trace for a log', async function () {
    let logEntry = null
    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()

    const stackTrace = logEntry.stackTrace
    assert.notEqual(stackTrace, null)
    assert.equal(stackTrace.callFrames.length, 3)

    await inspector.close()
  })

  it('test listen to logs with multiple consumers', async function () {
    let logEntry1 = null
    let logEntry2 = null
    const inspector = await LogInspector(driver)
    await inspector.onJavascriptException(function (log) {
      logEntry1 = log
    })
    await inspector.onJavascriptException(function (log) {
      logEntry2 = log
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    await driver.findElement({id: 'jsException'}).click()

    assert.equal(logEntry1.text, 'Error: Not working')
    assert.equal(logEntry1.type, 'javascript')
    assert.equal(logEntry1.level, 'error')

    assert.equal(logEntry2.text, 'Error: Not working')
    assert.equal(logEntry2.type, 'javascript')
    assert.equal(logEntry2.level, 'error')

    await inspector.close()
  })
})
```

```java
            logInspector.onJavaScriptException(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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L73-L78)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/logInspector.spec.js#L44-54)

##### /examples/javascript/test/bidirectional/logInspector.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const LogInspector = require('selenium-webdriver/bidi/logInspector');
const {Builder} = require("selenium-webdriver");


describe('Log Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test listen to console log', async function () {
    let logEntry = null
    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)

    await inspector.close()
  })

  it('test listen to javascript error log', async function () {
    let logEntry = null
    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')

    await inspector.close()
  })

  it('test retrieve stack trace for a log', async function () {
    let logEntry = null
    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()

    const stackTrace = logEntry.stackTrace
    assert.notEqual(stackTrace, null)
    assert.equal(stackTrace.callFrames.length, 3)

    await inspector.close()
  })

  it('test listen to logs with multiple consumers', async function () {
    let logEntry1 = null
    let logEntry2 = null
    const inspector = await LogInspector(driver)
    await inspector.onJavascriptException(function (log) {
      logEntry1 = log
    })
    await inspector.onJavascriptException(function (log) {
      logEntry2 = log
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    await driver.findElement({id: 'jsException'}).click()

    assert.equal(logEntry1.text, 'Error: Not working')
    assert.equal(logEntry1.type, 'javascript')
    assert.equal(logEntry1.level, 'error')

    assert.equal(logEntry2.text, 'Error: Not working')
    assert.equal(logEntry2.type, 'javascript')
    assert.equal(logEntry2.level, 'error')

    await inspector.close()
  })
})
```

```java
            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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L55-L60)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

----
url: https://www.selenium.dev/documentation/webdriver/browsers/chrome/
----

# Chrome specific functionality

```java
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L36-L37)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L9-L10)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L30-L31)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L51-L55)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_argument("--start-maximized")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L18)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L39)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.args << '--start-maximized'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L17)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L9-L12)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L53)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.binary_location = chrome_bin
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L29)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L49)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.binary = chrome_location
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L29)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L41-L44)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
  @DisabledOnOs(OS.WINDOWS)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L64)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_extension(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L40)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L73-L84)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.add_extension(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L38)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L62-L66)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```py
    options.add_experimental_option("detach", True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L51)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

**Note**: This is already the default behavior in .NET.

```rb
      @driver = Selenium::WebDriver.for :chrome, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L49)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L29-L32)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L78)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L62)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L82)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      @driver = Selenium::WebDriver.for :chrome, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L57)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L19-L22)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L100-L101)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY`\
Property value: String representing path to log file

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L71)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L86)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      @driver = Selenium::WebDriver.for :chrome, service: service
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L71)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L114-L115)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L82)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

`$stdout` and `$stderr` are both valid values

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      expect {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L80)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L129-L130)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY`\
Property value: String representation of `ChromiumDriverLogLevel` enum

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L93)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      @driver = Selenium::WebDriver.for :chrome, service: service
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L91)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L147-L148)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows toggling these features by System Property:\
Property keys: `ChromeDriverService.CHROME_DRIVER_APPEND_LOG_PROPERTY` and `ChromeDriverService.CHROME_DRIVER_READABLE_TIMESTAMP`\
Property value: `"true"` or `"false"`

```py
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L104)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb

      @driver = Selenium::WebDriver.for :chrome, service: service
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L101-L102)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L166-L167)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows disabling build checks by System Property:\
Property key: `ChromeDriverService.CHROME_DRIVER_DISABLE_BUILD_CHECK`\
Property value: `"true"` or `"false"`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L115)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            service.DisableBuildCheck = true;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L155)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      @driver = Selenium::WebDriver.for :chrome, service: service
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L112)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L230-L235)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L170-L174)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L123-L128)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L204-L210)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L129-L135)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
        'offline' => false,
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L133)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L247)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    logs = driver.get_log("browser")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L186)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L145)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    options.setBrowserVersion("stable");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L189)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    driver.set_permissions('camera', 'denied')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L149)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L153-L154)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### DevTools

See the [Chrome DevTools](https://www.selenium.dev/documentation/webdriver/bidi/cdp/) section for more information about using Chrome DevTools

Last modified April 19, 2026: [\[dotnet\] fix: test (25b39a556d7)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/25b39a556d73f3c0aff65f33da011b33b8c4d202)

----
url: https://www.selenium.dev/zh-cn/documentation/about/
----

# 关于这个文档

这些文档，就像代码本身一样，100% 由 Selenium 社区中的志愿者维护。 许多人自成立以来一直在使用它，但更多人只是在短时间内使用它，并且已经花时间帮助改善新用户的入门体验。

如果文档有问题，我们想知道！ 沟通问题的最佳方式是访问 [https://github.com/seleniumhq/seleniumhq.github.io/issues](//github.com/seleniumhq/seleniumhq.github.io/issues) 并搜索问题是否已经提交。 如果没有，请随意打开一个！

社区的许多成员经常光顾 [Libera.chat](https://libera.chat/) 的 *#selenium* Libera 频道。 请随时来访并提出问题，如果您得到了您认为在这些文档中可能有用的帮助，请务必添加您的贡献！ 我们可以更新这些文档，但当我们从普通提交者之外获得贡献时，对每个人来说都容易得多。

***

##### [版权和归属](/zh-cn/documentation/about/copyright/)

Selenium工具集下的全部版权、贡献以及归属.

##### [为 Selenium 文档做贡献](/zh-cn/documentation/about/contributing/)

有关改进Selenium文档和代码示例的信息

##### [Style guide for Selenium documentation](/zh-cn/documentation/about/style/)

Conventions for contributions to the Selenium documentation and code examples

----
url: https://www.selenium.dev/documentation/test_practices/encouraged/page_object_models/
----

# Page object models

```java
/***
 * Tests login feature
 */
public class Login {

  public void testLogin() {
    // fill login data on sign-in page
    driver.findElement(By.name("user_name")).sendKeys("userName");
    driver.findElement(By.name("password")).sendKeys("my supersecret password");
    driver.findElement(By.name("sign-in")).click();

    // verify h1 tag is "Hello userName" after login
    driver.findElement(By.tagName("h1")).isDisplayed();
    assertThat(driver.findElement(By.tagName("h1")).getText(), is("Hello userName"));
  }
}
```

There are two problems with this approach.

* There is no separation between the test method and the AUT’s locators (IDs in this example); both are intertwined in a single method. If the AUT’s UI changes its identifiers, layout, or how a login is input and processed, the test itself must change.
* The ID-locators would be spread in multiple tests, in all tests that had to use this login page.

Applying the page object model, this example could be rewritten like this in the following example of a page object for a Sign-in page.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Sign-in page.
 */
public class SignInPage {
  protected WebDriver driver;

  // <input name="user_name" type="text" value="">
  private By usernameBy = By.name("user_name");
  // <input name="password" type="password" value="">
  private By passwordBy = By.name("password");
  // <input name="sign_in" type="submit" value="SignIn">
  private By signinBy = By.name("sign_in");

  public SignInPage(WebDriver driver){
    this.driver = driver;
     if (!driver.getTitle().equals("Sign In Page")) {
      throw new IllegalStateException("This is not Sign In Page," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Login as valid user
    *
    * @param userName
    * @param password
    * @return HomePage object
    */
  public HomePage loginValidUser(String userName, String password) {
    driver.findElement(usernameBy).sendKeys(userName);
    driver.findElement(passwordBy).sendKeys(password);
    driver.findElement(signinBy).click();
    return new HomePage(driver);
  }
}
```

and page object for a Home page could look like this.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Home Page
 */
public class HomePage {
  protected WebDriver driver;

  // <h1>Hello userName</h1>
  private By messageBy = By.tagName("h1");

  public HomePage(WebDriver driver){
    this.driver = driver;
    if (!driver.getTitle().equals("Home Page of logged in user")) {
      throw new IllegalStateException("This is not Home Page of logged in user," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Get message (h1 tag)
    *
    * @return String message text
    */
  public String getMessageText() {
    return driver.findElement(messageBy).getText();
  }

  public HomePage manageProfile() {
    // Page encapsulation to manage profile functionality
    return new HomePage(driver);
  }
  /* More methods offering the services represented by Home Page
  of Logged User. These methods in turn might return more Page Objects
  for example click on Compose mail button could return ComposeMail class object */
}
```

So now, the login test would use these two page objects as follows.

```java
/***
 * Tests login feature
 */
public class TestLogin {

  @Test
  public void testLogin() {
    SignInPage signInPage = new SignInPage(driver);
    HomePage homePage = signInPage.loginValidUser("userName", "password");
    assertThat(homePage.getMessageText(), is("Hello userName"));
  }

}
```

```html
<!-- Products Page -->
<div class="header_container">
    <span class="title">Products</span>
</div>

<div class="inventory_list">
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
</div>
```

Each product is a component of the Products page.

```html
<!-- Inventory Item -->
<div class="inventory_item">
    <div class="inventory_item_name">Backpack</div>
    <div class="pricebar">
        <div class="inventory_item_price">$29.99</div>
        <button id="add-to-cart-backpack">Add to cart</button>
    </div>
</div>
```

The Products page HAS-A list of products. This object relationship is called Composition. In simpler terms, something is *composed of* another thing.

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

// Page Object
public class ProductsPage extends BasePage {
    public ProductsPage(WebDriver driver) {
        super(driver);
        // No assertions, throws an exception if the element is not loaded
        new WebDriverWait(driver, Duration.ofSeconds(3))
            .until(d -> d.findElement(By.className​("header_container")));
    }

    // Returning a list of products is a service of the page
    public List<Product> getProducts() {
        return driver.findElements(By.className​("inventory_item"))
            .stream()
            .map(e -> new Product(e)) // Map WebElement to a product component
            .toList();
    }

    // Return a specific product using a boolean-valued function (predicate)
    // This is the behavioral Strategy Pattern from GoF
    public Product getProduct(Predicate<Product> condition) {
        return getProducts()
            .stream()
            .filter(condition) // Filter by product name or price
            .findFirst()
            .orElseThrow(() -> new RuntimeException("Product not found")); // Error thrown during actual test run
    }
}
```

The Product component object is used inside the Products page object.

```java
public abstract class BaseComponent {
    protected WebElement root;

    public BaseComponent(WebElement root) {
        this.root = root;
    }
}

// Page Component Object
public class Product extends BaseComponent {
    // The root element contains the entire component
    public Product(WebElement root) {
        super(root); // inventory_item
    }

    public String getName() {
        // Locating an element begins at the root of the component
        return root.findElement(By.className("inventory_item_name")).getText();
    }

    public BigDecimal getPrice() {
        return new BigDecimal(
                root.findElement(By.className("inventory_item_price"))
                    .getText()
                    .replace("$", "")
            ).setScale(2, RoundingMode.UNNECESSARY); // Sanitation and formatting
    }

    public void addToCart() {
        root.findElement(By.id("add-to-cart-backpack")).click();
    }
}
```

So now, the products test would use the page object and the page component object as follows.

```java
public class ProductsTest {
    @Test
    public void testProductInventory() {
        var productsPage = new ProductsPage(driver); // page object
        var products = productsPage.getProducts();
        assertEquals(6, products.size()); // expected, actual
    }
    
    @Test
    public void testProductPrices() {
        var productsPage = new ProductsPage(driver);

        // Pass a lambda expression (predicate) to filter the list of products
        // The predicate or "strategy" is the behavior passed as parameter
        var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); // page component object
        var bikeLight = productsPage.getProduct(p -> p.getName().equals("Bike Light"));

        assertEquals(new BigDecimal("29.99"), backpack.getPrice());
        assertEquals(new BigDecimal("9.99"), bikeLight.getPrice());
    }
}
```

```java
public class LoginPage {
    public HomePage loginAs(String username, String password) {
        // ... clever magic happens here
    }
    
    public LoginPage loginAsExpectingError(String username, String password) {
        //  ... failed login here, maybe because one or both of the username and password are wrong
    }
    
    public String getErrorMessage() {
        // So we can verify that the correct error is shown
    }
}
```

The code presented above shows an important point: the tests, not the Page Objects, should be responsible for making assertions about the state of a page. For example:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    inbox.assertMessageWithSubjectIsUnread("I like cheese");
    inbox.assertMessageWithSubjectIsNotUnread("I'm not fond of tofu");
}
```

could be re-written as:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    assertTrue(inbox.isMessageWithSubjectIsUnread("I like cheese"));
    assertFalse(inbox.isMessageWithSubjectIsUnread("I'm not fond of tofu"));
}
```

```java
public class LoginPage {
    private final WebDriver driver;

    public LoginPage(WebDriver driver) {
        this.driver = driver;

        // Check that we're on the right page.
        if (!"Login".equals(driver.getTitle())) {
            // Alternatively, we could navigate to the login page, perhaps logging out first
            throw new IllegalStateException("This is not the login page");
        }
    }

    // The login page contains several HTML elements that will be represented as WebElements.
    // The locators for these elements should only be defined once.
        By usernameLocator = By.id("username");
        By passwordLocator = By.id("passwd");
        By loginButtonLocator = By.id("login");

    // The login page allows the user to type their username into the username field
    public LoginPage typeUsername(String username) {
        // This is the only place that "knows" how to enter a username
        driver.findElement(usernameLocator).sendKeys(username);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to type their password into the password field
    public LoginPage typePassword(String password) {
        // This is the only place that "knows" how to enter a password
        driver.findElement(passwordLocator).sendKeys(password);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to submit the login form
    public HomePage submitLogin() {
        // This is the only place that submits the login form and expects the destination to be the home page.
        // A seperate method should be created for the instance of clicking login whilst expecting a login failure. 
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the login page ever
        // go somewhere else (for example, a legal disclaimer) then changing the method signature
        // for this method will mean that all tests that rely on this behaviour won't compile.
        return new HomePage(driver);	
    }

    // The login page allows the user to submit the login form knowing that an invalid username and / or password were entered
    public LoginPage submitLoginExpectingFailure() {
        // This is the only place that submits the login form and expects the destination to be the login page due to login failure.
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the user ever be navigated to the home page after submiting a login with credentials 
        // expected to fail login, the script will fail when it attempts to instantiate the LoginPage PageObject.
        return new LoginPage(driver);	
    }

    // Conceptually, the login page offers the user the service of being able to "log into"
    // the application using a user name and password. 
    public HomePage loginAs(String username, String password) {
        // The PageObject methods that enter username, password & submit login have already defined and should not be repeated here.
        typeUsername(username);
        typePassword(password);
        return submitLogin();
    }
}
```

Last modified October 30, 2025: [docs: improve consistency and readability of the guide (#2168) (708f32f0c58)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/708f32f0c58c2386be472aec8b74801183f6743a)

----
url: https://www.selenium.dev/pt-br/documentation/legacy/selenium_3/grid_components/
----

# Componentes

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/support_features/expected_conditions/
----

#

```py
    wait = WebDriverWait(driver, timeout=2)
    wait.until(EC.visibility_of_element_located((By.ID, "revealed")))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_expected_conditions.py#L14-L15)

##### /examples/python/tests/support/test\_expected\_conditions.py

```py
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

# Expected Conditions API Documentation:
# https://www.selenium.dev/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html


def test_expected_condition(driver):
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html")
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(EC.visibility_of_element_located((By.ID, "revealed")))

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"
```

.NET stopped supporting Expected Conditions in Selenium 4 to minimize maintenance hassle and redundancy.

Ruby makes frequent use of blocks, procs and lambdas and does not need Expected Conditions classes

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/encouraged/
----

# 指南和建议

Selenium项目的一些测试指南和建议.

关于"最佳实践"的注解：我们有意在本文档中避免使用"最佳实践"的说辞. 没有一种方法可以适用于所有情况. 我们更喜欢"指南和建议"的想法. 我们鼓励您通读这些内容, 并仔细地确定哪种方法适用于您的特定环境.

由于许多原因, 功能测试很难正确完成. 即便应用程序的状态, 复杂性, 依赖还不够让测试变得 足够复杂, 操作浏览器（特别是跨浏览器的兼容性测试）就已经使得写一个好的测试变成一种挑战.

Selenium提供了一些工具使得功能测试用户更简单的操作浏览器, 但是这些工具并不能帮助你来写一个好的 架构的测试套件. 这章我们会针对怎么来做web页面的功能测试的自动化给出一些忠告, 指南和建议.

这章记录了很多历年来成功的使用Selenium的用户的常用的软件设计模式.

***

##### [PO设计模式](/zh-cn/documentation/test_practices/encouraged/page_object_models/)

##### [领域特定语言](/zh-cn/documentation/test_practices/encouraged/domain_specific_language/)

##### [生成应用程序状态](/zh-cn/documentation/test_practices/encouraged/generating_application_state/)

##### [模拟外部服务](/zh-cn/documentation/test_practices/encouraged/mock_external_services/)

##### [改善报告](/zh-cn/documentation/test_practices/encouraged/improved_reporting/)

##### [避免共享状态](/zh-cn/documentation/test_practices/encouraged/avoid_sharing_state/)

##### [使用定位器的提示](/zh-cn/documentation/test_practices/encouraged/locators/)

何时使用哪些定位器以及如何在代码中最好地管理它们.

##### [测试的独立性](/zh-cn/documentation/test_practices/encouraged/test_independency/)

##### [考虑使用Fluent API](/zh-cn/documentation/test_practices/encouraged/consider_using_a_fluent_api/)

##### [每次测试都刷新浏览器](/zh-cn/documentation/test_practices/encouraged/fresh_browser_per_test/)

----
url: https://www.selenium.dev/pt-br/_print/documentation/grid/advanced_features/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/grid/advanced_features/).

# Características avançadas

Para obter todos os detalhes dos recursos avançados, entenda como funciona e como configurar crie o seu próprio, navegue pelas seções a seguir.

* 1: [Observabilidade](#pg-0559dcb12b1e3ebb50211585a83e0be8)
* 2: [Suporte a buscas em GraphQL](#pg-2c82ff996091dc1dd2f15b718d6b1ede)
* 3: [Rotas da Grid](#pg-d2d54c4f08eb016972465f2a03ead126)
* 4: [Personalizando um Nó](#pg-f1b80d80b2bcdc1e194f0d4fc033093e)
* 5: [External datastore](#pg-538b88406bce5817973473bd612380c3)

# 1 - Observabilidade

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar standalone --log-level FINE
```

2. Jaeger UI - OpenTelemetry fornece as APIs e SDKs para instrumentar rastreamentos no código. Enquanto o Jaeger é um sistema de rastreamento de backend que auxilia na coleta de dados de telemetria de rastreamento e oferece recursos de consulta, filtragem e visualização dos dados.

Instruções detalhadas sobre como visualizar rastreamentos usando a interface do Jaeger podem ser obtidas executando o seguinte comando:

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar info tracing
```

[Um exemplo muito bom e scripts para executar o servidor e enviar rastreamentos para o Jaeger](https://github.com/manoj9788/tracing-selenium-grid)

## Explorando logs de eventos

O rastreamento deve estar habilitado para o registro de eventos, mesmo que alguém não deseje exportar rastreamentos para visualizá-los.

**Por padrão, o rastreamento está habilitado. Não é necessário passar parâmetros adicionais para ver os logs no console.**

Todos os eventos dentro de um segmento são registrados no nível FINE. Eventos de erro são registrados no nível WARN..

| Campo               | Valor do Campo  | Descrição                                                                                                                                                                                                                    |
| ------------------- | --------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Hora do Evento      | eventId         | Carimbo de data/hora do registro do evento em nanossegundos desde a época.                                                                                                                                                   |
| ID de Rastreamento  | tracedId        | Cada rastreamento é identificado exclusivamente por um ID de rastreamento.                                                                                                                                                   |
| ID de Segmento      | spanId          | Cada segmento dentro de um rastreamento é identificado exclusivamente por um ID de segmento.                                                                                                                                 |
| Tipo de Segmento    | spanKind        | O tipo de segmento é uma propriedade do segmento que indica o tipo de segmento. Isso ajuda a entender a natureza da unidade de trabalho realizada pelo segmento.                                                             |
| Nome do Evento      | eventName       | Isso mapeia para a mensagem de registro.                                                                                                                                                                                     |
| Atributos do Evento | eventAttributes | Isso forma a essência dos registros de eventos, com base na operação executada, ele contém pares chave-valor formatados em JSON. Isso também inclui um atributo de classe do manipulador, para mostrar a classe do registro. |

Simples log

```
FINE [LoggingOptions$1.lambda$export$1] - {
  "traceId": "fc8aef1d44b3cc8bc09eb8e581c4a8eb",
  "spanId": "b7d3b9865d3ddd45",
  "spanKind": "INTERNAL",
  "eventTime": 1597819675128886121,
  "eventName": "Session request execution complete",
  "attributes": {
    "http.status_code": 200,
    "http.handler_class": "org.openqa.selenium.grid.router.HandleSession",
    "http.url": "\u002fsession\u002fdd35257f104bb43fdfb06242953f4c85",
    "http.method": "DELETE",
    "session.id": "dd35257f104bb43fdfb06242953f4c85"
  }
}
```

Além dos campos mencionados anteriormente, com base na [especificação do OpenTelemetry](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/exceptions.md) os registros de erro consistem nos seguintes campos: :

| Campo                   | Valor do Campo       | Descrição                                                                                                  |
| ----------------------- | -------------------- | ---------------------------------------------------------------------------------------------------------- |
| Tipo de Exceção         | exception.type       | O nome da classe da exceção.                                                                               |
| Mensagem da Exceção     | exception.message    | Motivo da exceção.                                                                                         |
| Rastreamento de Exceção | exception.stacktrace | Imprime a pilha de chamadas no momento em que a exceção foi lançada. Ajuda a entender a origem da exceção. |

Simples error log

```
WARN [LoggingOptions$1.lambda$export$1] - {
  "traceId": "7efa5ea57e02f89cdf8de586fe09f564",
  "spanId": "914df6bc9a1f6e2b",
  "spanKind": "INTERNAL",
  "eventTime": 1597820253450580272,
  "eventName": "exception",
  "attributes": {
    "exception.type": "org.openqa.selenium.ScriptTimeoutException",
    "exception.message": "Unable to execute request: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist ..." (full message will be printed),
    "exception.stacktrace": "org.openqa.selenium.ScriptTimeoutException: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist\nBuild info: version: '4.0.0-alpha-7', revision: 'Unknown'\nSystem info: host: 'XYZ-MacBook-Pro.local', ip: 'fe80:0:0:0:10d5:b63a:bdc6:1aff%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.7'\nDriver info: driver.version: unknown ...." (full stack will be printed),
    "http.handler_class": "org.openqa.selenium.grid.distributor.remote.RemoteDistributor",
    "http.url": "\u002fsession",
    "http.method": "POST"
  }
}
```

# 2 - Suporte a buscas em GraphQL

```shell
{
    session(id: "<session-id>") : {
        id,
        capabilities,
        startTime,
        uri,
        nodeId,
        nodeUri,
        sessionDurationMillis
        slot : {
            id,
            stereotype,
            lastStarted
        }
    }
    grid: {
        uri,
        totalSlots,
        nodeCount,
        maxSession,
        sessionCount,
        version,
        sessionQueueSize
    }
    sessionsInfo: {
        sessionQueueRequests,
        sessions: [
            {
                id,
                capabilities,
                startTime,
                uri,
                nodeId,
                nodeUri,
                sessionDurationMillis
                slot : {
                    id,
                    stereotype,
                    lastStarted
                }
            }
        ]
    }
    nodesInfo: {
        nodes : [
            {
                id,
                uri,
                status,
                maxSession,
                slotCount,
                sessions: [
                    {
                        id,
                        capabilities,
                        startTime,
                        uri,
                        nodeId,
                        nodeUri,
                        sessionDurationMillis
                        slot : {
                            id,
                            stereotype,
                            lastStarted
                        }
                    }
                ],
                sessionCount,
                stereotypes,
                version,
                osInfo: {
                    arch,
                    name,
                    version
                }
            }
        ]
    }
}
```

## Consultando GraphQL

O melhor jeito de consultar GraphQL é utilizando requisições `curl`. GraphQL permite que você busque apenas os dados que você quer, nada mais, anda menos.

Alguns exemplos de buscas em GraphQL estão abaixo. Você pode montar as queries como quiser.

### Buscando o número total de slots (`maxSession`) e slots usados (`sessionCount`) na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ grid { maxSession, sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

Geralmente na máquina local o `<LINK_TO_GRAPHQL_ENDPOINT>` será `http://localhost:4444/graphql`

### Buscando todos os detalhes da Sessão, Nó e Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { uri, maxSession, sessionCount }, nodesInfo { nodes { id, uri, status, sessions { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } }, slotCount, sessionCount }} }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando o número de sessões atual na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando a contagem máxima de sessões na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { maxSession } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando todos os detalhes de todas as sessões de todos os nós na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, capabilities, startTime, uri, nodeId, nodeId, sessionDurationMillis } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando informações dos slots de todas as sessões de cada Nó na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, slot { id, stereotype, lastStarted } } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando informação da sessão para uma sessão específica:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ session (id: \"<session-id>\") { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } } } "}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando os recursos de cada nó na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { stereotypes } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando o status de cada Nó na Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { status } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Buscando a URI de cada Nó e da Grid:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { uri } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the current requests in the New Session Queue:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessionQueueRequests } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the New Session Queue size :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionQueueSize } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

# 3 - Rotas da Grid

## Grid

### Status da Grid

O status da Grid fornece o estado atual da grid. Consiste em detalhes sobre cada nó registrado. Para cada nó, o status inclui informações sobre a disponibilidade, sessões e slots do nó.

```shell
curl --request GET 'http://localhost:4444/status'
```

### Deletar sessão

A exclusão da sessão encerra a sessão do WebDriver, fecha o driver e o remove do mapa de sessões ativas. Qualquer solicitação usando o id de sessão removido ou reutilizando a instância do driver gerará um erro.

```shell
curl --request DELETE 'http://localhost:4444/session/<session-id>'
```

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret> '
```

No modo totalmente distribuído, a URL é o endereço do servidor Router.

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

Se nenhum segredo de registro foi configurado durante a configuração da Grid, use

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET;'
```

### Drenar Nó

O comando de drenagem de nó é para desligamento normal de nó. A drenagem para o Node após a conclusão de todas as sessões em andamento. No entanto, ele não aceita novas solicitações de sessão.

No modo Standalone, a URL do distribuidor é o endereço do servidor Standalone.

No modo Hub-Node, a URL do Distribuidor é o endereço do servidor Hub.

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret> '
```

No modo totalmente distribuído, a URL é o endereço do servidor Router.

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

Se nenhum segredo de registro foi configurado durante a configuração da Grid, use

```shell
curl --request POST 'http://<Router-URL>/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET;'
```

## Nó

Os terminais nesta seção são aplicáveis ao modo Hub-Node e ao modo Grid totalmente distribuída, onde o Nó é executado de forma independente. A URL do Nó padrão é http\://localhost:5555 no caso de um Nó. No caso de vários Nós, use [Grid status](/pt-br/documentation/grid/advanced_features/endpoints/#grid-status) para obter todos os detalhes do Nó e localizar o endereço do Nó.

### Status

O status do Nó é essencialmente uma verificação de integridade do Nó. O distribuidor executa ping no status do Nó em intervalos regulares e atualiza o modelo de Grid de acordo. O status inclui informações sobre disponibilidade, sessões e slots.

```shell
curl --request GET 'http://localhost:5555/status'
```

### Drenagem

O Distribuidor passa o comando \[drain]\(# drain-node) para o Nó apropriado identificado pelo ID do Nó. Para drenar o Nó diretamente, use o comando curl listado abaixo. Ambos as rotas são válidas e produzem o mesmo resultado. Drenar termina as sessões em andamento antes de interromper o Nó.

```shell
curl --request POST 'http://localhost:5555/se/grid/node/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

Se nenhum segredo de registro foi configurado durante a configuração da Grid, use

```shell
curl --request POST 'http://<node-URL>/se/grid/node/drain' --header 'X-REGISTRATION-SECRET;'
```

### Checar dono da sessão

Para verificar se uma sessão pertence a um Nó, use o comando curl listado abaixo.

```shell
curl --request GET 'http://localhost:5555/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

Se nenhum segredo de registro foi configurado durante a configuração da Grid, use

```shell
curl --request GET 'http://<node-URL>/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

Ele retornará true se a sessão pertencer ao Nó, caso contrário, retornará false.

### Deletar sessão

A exclusão da sessão encerra a sessão do WebDriver, fecha o driver e o remove do mapa de sessões ativas. Qualquer solicitação usando o id de sessão removido ou reutilizando a instância do driver gerará um erro.

```shell
curl --request DELETE 'http://localhost:5555/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

Se nenhum segredo de registro foi configurado durante a configuração da Grid, use

```shell
curl --request DELETE 'http://<node-URL>/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

## Fila de Sessão

### Limpar a Fila de Sessão

A Fila de Sessão contém as novas solicitações de sessão. Para limpar a fila, use o comando curl listado abaixo. Limpar a fila rejeita todas as solicitações na fila. Para cada solicitação, o servidor retorna uma resposta de erro ao respectivo cliente. O resultado do comando clear é o número total de solicitações excluídas.

No modo Standalone, a URL Queue é o endereço do servidor Standalone.

No modo Hub-Node, a URL do enfileirador é o endereço do servidor Hub.

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

No modo totalmente distribuído, a URL do enfileirador é o endereço do servidor do Enfileirador de Sessões.

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET;'
```

### Obter novos pedidos da Fila de Sessão

Novos pedidos da Fila de Sessão contém os novos pedidos de sessão. Para obter os pedidos na Fila, utiliza o comando curl listado abaixo. É retornado o número total de pedidos na Fila.

No modo Standalone, a URL é a do servidor, em modo Grid, a URL será a do HUB.

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

No modo totalmente distribuido, a URL da Fila é a porta do servidor de Fila.

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

# 4 - Personalizando um Nó

```bash
java -jar custom_node-server.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

```bash
java -jar selenium-server-4.6.0.jar \
--ext custom_node-1.0-SNAPSHOT.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

Aqui está um exemplo que apenas imprime algumas mensagens no console sempre que houver uma atividade de interesse (sessão criada, sessão excluída, execução de um comando do webdriver, etc.) no Node.

Sample customized node

```java
package org.seleniumhq.samples;

import java.net.URI;
import java.util.UUID;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.NoSuchSessionException;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.grid.config.Config;
import org.openqa.selenium.grid.data.CreateSessionRequest;
import org.openqa.selenium.grid.data.CreateSessionResponse;
import org.openqa.selenium.grid.data.NodeId;
import org.openqa.selenium.grid.data.NodeStatus;
import org.openqa.selenium.grid.data.Session;
import org.openqa.selenium.grid.log.LoggingOptions;
import org.openqa.selenium.grid.node.HealthCheck;
import org.openqa.selenium.grid.node.Node;
import org.openqa.selenium.grid.node.local.LocalNodeFactory;
import org.openqa.selenium.grid.security.Secret;
import org.openqa.selenium.grid.security.SecretOptions;
import org.openqa.selenium.grid.server.BaseServerOptions;
import org.openqa.selenium.internal.Either;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
import org.openqa.selenium.remote.tracing.Tracer;

public class DecoratedLoggingNode extends Node {

  private Node node;

  protected DecoratedLoggingNode(Tracer tracer, NodeId nodeId, URI uri, Secret registrationSecret, Duration sessionTimeout) {
    super(tracer, nodeId, uri, registrationSecret, sessionTimeout);
  }

  public static Node create(Config config) {
    LoggingOptions loggingOptions = new LoggingOptions(config);
    BaseServerOptions serverOptions = new BaseServerOptions(config);
    URI uri = serverOptions.getExternalUri();
    SecretOptions secretOptions = new SecretOptions(config);
    NodeOptions nodeOptions = new NodeOptions(config);
    Duration sessionTimeout = nodeOptions.getSessionTimeout();

    // Refer to the foot notes for additional context on this line.
    Node node = LocalNodeFactory.create(config);

    DecoratedLoggingNode wrapper = new DecoratedLoggingNode(loggingOptions.getTracer(),
        node.getId(),
        uri,
        secretOptions.getRegistrationSecret(),
        sessionTimeout);
    wrapper.node = node;
    return wrapper;
  }

  @Override
  public Either<WebDriverException, CreateSessionResponse> newSession(
      CreateSessionRequest sessionRequest) {
    System.out.println("Before newSession()");
    try {
      return this.node.newSession(sessionRequest);
    } finally {
      System.out.println("After newSession()");
    }
  }

  @Override
  public HttpResponse executeWebDriverCommand(HttpRequest req) {
    try {
      System.out.println("Before executeWebDriverCommand(): " + req.getUri());
      return node.executeWebDriverCommand(req);
    } finally {
      System.out.println("After executeWebDriverCommand()");
    }
  }

  @Override
  public Session getSession(SessionId id) throws NoSuchSessionException {
    try {
      System.out.println("Before getSession()");
      return node.getSession(id);
    } finally {
      System.out.println("After getSession()");
    }
  }

  @Override
  public HttpResponse uploadFile(HttpRequest req, SessionId id) {
    try {
      System.out.println("Before uploadFile()");
      return node.uploadFile(req, id);
    } finally {
      System.out.println("After uploadFile()");
    }
  }

  @Override
  public void stop(SessionId id) throws NoSuchSessionException {
    try {
      System.out.println("Before stop()");
      node.stop(id);
    } finally {
      System.out.println("After stop()");
    }
  }

  @Override
  public boolean isSessionOwner(SessionId id) {
    try {
      System.out.println("Before isSessionOwner()");
      return node.isSessionOwner(id);
    } finally {
      System.out.println("After isSessionOwner()");
    }
  }

  @Override
  public boolean isSupporting(Capabilities capabilities) {
    try {
      System.out.println("Before isSupporting");
      return node.isSupporting(capabilities);
    } finally {
      System.out.println("After isSupporting()");
    }
  }

  @Override
  public NodeStatus getStatus() {
    try {
      System.out.println("Before getStatus()");
      return node.getStatus();
    } finally {
      System.out.println("After getStatus()");
    }
  }

  @Override
  public HealthCheck getHealthCheck() {
    try {
      System.out.println("Before getHealthCheck()");
      return node.getHealthCheck();
    } finally {
      System.out.println("After getHealthCheck()");
    }
  }

  @Override
  public void drain() {
    try {
      System.out.println("Before drain()");
      node.drain();
    } finally {
      System.out.println("After drain()");
    }

  }

  @Override
  public boolean isReady() {
    try {
      System.out.println("Before isReady()");
      return node.isReady();
    } finally {
      System.out.println("After isReady()");
    }
  }
}
```

***Notas de Rodapé:***

No exemplo acima, a linha `Node node = LocalNodeFactory.create(config);` cria explicitamente um `LocalNode`.

Basicamente, existem 2 tipos de implementações *visíveis para o usuário* de `org.openqa.selenium.grid.node.Node` disponíveis.

Essas classes são bons pontos de partida para aprender como criar um Node personalizado e também para compreender os detalhes internos de um Node.

* `org.openqa.selenium.grid.node.local.LocalNode` - Usado para representar um Node de execução contínua e é a implementação padrão que é usada quando você inicia um `node`.

  * Pode ser criado chamando `LocalNodeFactory.create(config);`, onde:

    * `LocalNodeFactory` pertence a `org.openqa.selenium.grid.node.local`
    * `Config` pertence a `org.openqa.selenium.grid.config`

* `org.openqa.selenium.grid.node.k8s.OneShotNode` - Esta é uma implementação de referência especial em que o Node encerra-se graciosamente após atender a uma sessão de teste. Esta classe atualmente não está disponível como parte de nenhum artefato Maven pré-construído.

  * Você pode consultar o código-fonte [aqui](https://github.com/SeleniumHQ/selenium/blob/trunk/java/src/org/openqa/selenium/grid/node/k8s/OneShotNode.java) para entender seus detalhes internos.

  * Para construí-lo localmente, consulte [aqui](https://github.com/SeleniumHQ/selenium/blob/trunk/deploys/k8s/README.md).

  * Pode ser criado chamando `OneShotNode.create(config)`, onde:

    * `OneShotNode` pertence a `org.openqa.selenium.grid.node.k8s`
    * `Config` pertence a `org.openqa.selenium.grid.config`

# 5 - External datastore

```sql
CREATE TABLE IF NOT EXISTS sessions_map(
    session_ids varchar(256),
    session_caps text,
    session_uri varchar(256),
    session_stereotype text,
    session_start varchar(256)
 );
```

* In the same directory as the `init.sql`, create a file named `docker-compose.yml` with its contents as below:

```yaml
version: '3.8'
services:
  db:
    image: postgres:9.6-bullseye
    restart: always
    environment:
      - POSTGRES_USER=seluser
      - POSTGRES_PASSWORD=seluser
      - POSTGRES_DB=selenium_sessions
    ports:
      - "5432:5432"
    volumes:
    - ./init.sql:/docker-entrypoint-initdb.d/init.sql
```

We can now start our database container by running:

```bash
docker-compose up -d
```

*Our database name is `selenium_sessions` with its username and password set to `seluser`*

If you are working with an already running PostGreSQL DB instance, then you just need to create a database named `selenium_sessions` and the table `sessions_map` using the above mentioned SQL statement.

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
implementation = "org.openqa.selenium.grid.sessionmap.jdbc.JdbcBackedSessionMap"
jdbc-url = "jdbc:postgresql://localhost:5432/selenium_sessions"
jdbc-user = "seluser"
jdbc-password = "seluser"
```

*Note:* If you plan to use an existing PostGreSQL DB instance, then replace `localhost:5432` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed Grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Sessions Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

```yaml
version: '3.8'
services:
  redis:
    image: redis:bullseye
    restart: always
    ports:
      - "6379:6379"
```

We can now start our Redis container by running:

```bash
docker-compose up -d
```

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
scheme = "redis"
implementation = "org.openqa.selenium.grid.sessionmap.redis.RedisBackedSessionMap"
hostname = "localhost"
port = 6379
```

*Note:* If you plan to use an existing Redis Cache instance, then replace `localhost` and `6379` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Session Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

* At this point the current directory should contain the following files:

  * `docker-compose.yml`
  * `sessions.toml`
  * `distributed.sh`

* You can now spawn the Grid by running `distributed.sh` shell script and quickly run a test. You will notice that the Grid now stores session information into the Redis instance. You can perhaps make use of a Redis GUI such as [TablePlus](https://tableplus.com/) to see them (Make sure that you have setup a debug point in your test, because the values will get deleted as soon as the test runs to completion).

In the line which spawns a `SessionMap` on a machine:

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/browsers/chrome/
----

# Chrome 特定功能

特定于 Google Chrome 浏览器的功能和特性.

默认情况下，Selenium 4与Chrome v75及更高版本兼容. 但是请注意Chrome浏览器的版本与chromedriver的主版本需要匹配.

## Options

所有浏览器的通用功能请看这 [Options page](https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/options/).

Chrome浏览器的特有功能可以在谷歌的页面找到: [Capabilities & ChromeOptions](https://chromedriver.chromium.org/capabilities)

基于默认选项的Chrome浏览器会话看起来是这样:

*
*
*
*
*
*

```java
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L36-L37)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L9-L10)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L30-L31)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L51-L55)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

下面是一些不同功能的常见示例:

### 参数

`args` 参数用于启动浏览器时要使用的命令行开关列表. 有两个很好的资源可以用于研究这些参数:

* [Chrome Flags for Tooling](https://github.com/GoogleChrome/chrome-launcher/blob/main/docs/chrome-flags-for-tools.md)
* [List of Chromium Command Line Switches](https://peter.sh/experiments/chromium-command-line-switches/)

常用的参数包括 `--start-maximized`, `--headless=new` 以及 `--user-data-dir=...`

向选项添加参数:

*
*
*
*
*
*

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_argument("--start-maximized")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L18)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L39)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.args << '--start-maximized'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L17)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L9-L12)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

### 从指定位置启动浏览器

`binary` 参数接收一个使用浏览器的备用路径,通过这个参数你可以使用chromedriver 去驱动各种基于Chromium 内核的浏览器.

添加一个浏览器地址到选项中:

*
*
*
*
*
*

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L53)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.binary_location = chrome_bin
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L29)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L49)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.add_argument("--user-data-dir=#{user_data_dir}")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L25)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L41-L44)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

### 添加扩展程序

`extensions` 参数接受crx文件. 至于解压的目录, 请使用 `load-extension` 参数代替, 正如 [这篇文章](https://chromedriver.chromium.org/extensions) 所示.

添加一个扩展程序到选项中:

*
*
*
*
*
*

```java
  @DisabledOnOs(OS.WINDOWS)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L64)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_extension(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L40)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L73-L84)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
    it 'add extensions' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L34)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L62-L66)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

### 保持浏览器的打开状态

将 `detach` 参数设置为true将在驱动过程结束后保持浏览器的打开状态.

添加一个布尔值到选项中:

```py
    options.add_experimental_option("detach", True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L51)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

**Note**: This is already the default behavior in .NET.

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L45)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L29-L32)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

### 排除的参数

Chrome 添加了各种参数，如果你不希望添加某些参数，可以将其传入 `excludeSwitches`. 一个常见的例子是重新打开弹出窗口阻止程序. 默认参数的完整列表可以参考 [Chromium 源码](https://source.chromium.org/chromium/chromium/src/+/main:chrome/test/chromedriver/chrome_launcher.cc)

设置排除参数至选项中:

*
*
*
*
*
*

```java
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L78)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L62)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L82)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L53)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L19-L22)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

## 服务

创建默认 Service 对象的示例, 以及用于设置驱动程序位置和端口 可以参考 [驱动服务](https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/service/) 页面.

### 日志输出

获取驱动程序日志有助于调试问题. 使用 Service 类, 可以指明日志的路径. 除非用户将其定向到某个位置, 否则将忽略日志记录输出.

#### 文件输出

更改日志记录输出以保存到特定文件:

*
*
*
*
*
*

```java
    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L100-L101)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Java 还允许通过系统属性设置文件输出:\
属性键: `ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY`\
属性值: 表示日志文件路径的字符串

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L71)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L86)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service = Selenium::WebDriver::Service.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L67)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

#### 命令行输出

更改日志记录输出以在控制台中显示为标准输出:

```java

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L114-L115)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Java 还允许通过系统属性设置控制台输出;\
属性键: `ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY`\
属性值: `DriverService.LOG_STDOUT` 或 `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L82)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

`$stdout` and `$stderr` are both valid values

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service = Selenium::WebDriver::Service.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L76)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### 日志级别

共有六种日志级别: `ALL`, `DEBUG`, `INFO`, `WARNING`, `SEVERE`, 以及 `OFF`. 注意 `--verbose` 等效于 `--log-level=ALL` 以及 `--silent` 等效于 `--log-level=OFF`, 因此, 此示例只是通用地设置日志级别:

```java
    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L129-L130)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Java 还允许通过系统属性设置日志级别:\
属性键: `ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY`\
属性值: `ChromiumDriverLogLevel` 枚举的字面值

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L93)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L87)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### 日志文件功能

有 2 个功能仅在写入文件时可用:

* 追加日志
* 可读时间戳

要使用它们, 您还需要显式指定日志路径和日志级别. 日志输出将由驱动程序管理, 而不是由进程管理, 因此可能会看到细微的差异.

```java

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L147-L148)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Java 还允许通过系统属性切换这些功能:\
属性键: `ChromeDriverService.CHROME_DRIVER_APPEND_LOG_PROPERTY` 以及 `ChromeDriverService.CHROME_DRIVER_READABLE_TIMESTAMP`\
属性值: `"true"` 或 `"false"`

```py
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L104)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service = Selenium::WebDriver::Service.chrome(args: args)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L97-L98)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### 禁用构建检查

Chromedriver 和 Chrome 浏览器版本应该匹配, 如果它们不匹配, 驱动程序将出错. 如果您停用构建检查功能, 则可以强制将驱动程序与任何版本的 Chrome 一起使用. 请注意, 这是一项不受支持的功能, 并且不会调查 bug.

```java

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L166-L167)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Java 还允许通过系统属性禁用构建检查:\
属性键: `ChromeDriverService.CHROME_DRIVER_DISABLE_BUILD_CHECK`\
属性值: `"true"` 或 `"false"`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L115)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            service.DisableBuildCheck = true;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L155)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L108)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## 特殊功能

### Casting

你可以驱动 Chrome Cast 设备，包括共享选项卡

*
*
*
*
*
*

```java
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L230-L235)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L170-L174)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L119-L124)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### 网络条件

您可以模拟各种网络条件.

以下示例适用于本地 webdrivers. 针对远程 webdrivers, 请参考 [Remote WebDriver](https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/remote_webdriver/) 页面.

*
*
*
*
*
*

```java
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L204-L210)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L129-L135)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
    it 'gets and sets network conditions' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L129)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L247)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    logs = driver.get_log("browser")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L186)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver = Selenium::WebDriver.for :chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L141)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    options.setBrowserVersion("stable");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L189)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    driver.set_permissions('camera', 'denied')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L149)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L149-L150)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### DevTools

详见 [Chrome DevTools](https://www.selenium.dev/zh-cn/documentation/webdriver/bidi/cdp/) 部分以获取有关使用Chrome DevTools的更多信息

最后修改 April 19, 2026: [\[dotnet\] fix: test (25b39a556d7)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/25b39a556d73f3c0aff65f33da011b33b8c4d202)

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/design_strategies/
----

# Design patterns and development strategies

```java
package com.example.webdriver;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class EditIssue {

  private final WebDriver driver;

  public EditIssue(WebDriver driver) {
    this.driver = driver;
  }

  public void setTitle(String title) {
    WebElement field = driver.findElement(By.id("issue_title")));
    clearAndType(field, title);
  }

  public void setBody(String body) {
    WebElement field = driver.findElement(By.id("issue_body"));
    clearAndType(field, body);
  }

  public void setHowToReproduce(String howToReproduce) {
    WebElement field = driver.findElement(By.id("issue_form_repro-command"));
    clearAndType(field, howToReproduce);
  }

  public void setLogOutput(String logOutput) {
    WebElement field = driver.findElement(By.id("issue_form_logs"));
    clearAndType(field, logOutput);
  }

  public void setOperatingSystem(String operatingSystem) {
    WebElement field = driver.findElement(By.id("issue_form_operating-system"));
    clearAndType(field, operatingSystem);
  }

  public void setSeleniumVersion(String seleniumVersion) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-version"));
    clearAndType(field, logOutput);
  }

  public void setBrowserVersion(String browserVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-versions"));
    clearAndType(field, browserVersion);
  }

  public void setDriverVersion(String driverVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-driver-versions"));
    clearAndType(field, driverVersion);
  }

  public void setUsingGrid(String usingGrid) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-grid-version"));
    clearAndType(field, usingGrid);
  }

  public IssueList submit() {
    driver.findElement(By.cssSelector("button[type='submit']")).click();
    return new IssueList(driver);
  }

  private void clearAndType(WebElement field, String text) {
    field.clear();
    field.sendKeys(text);
  }
}
```

In order to turn this into a LoadableComponent, all we need to do is to set that as the base type:

```java
public class EditIssue extends LoadableComponent<EditIssue> {
  // rest of class ignored for now
}
```

This signature looks a little unusual, but it all means is that this class represents a LoadableComponent that loads the EditIssue page.

By extending this base class, we need to implement two new methods:

```java
  @Override
  protected void load() {
    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();
    assertTrue("Not on the issue entry page: " + url, url.endsWith("/new"));
  }
```

The `load` method is used to navigate to the page, whilst the `isLoaded` method is used to determine whether we are on the right page. Although the method looks like it should return a boolean, instead it performs a series of assertions using JUnit’s Assert class. There can be as few or as many assertions as you like. By using these assertions it’s possible to give users of the class clear information that can be used to debug tests.

With a little rework, our PageObject looks like:

```java
package com.example.webdriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

import static junit.framework.Assert.assertTrue;

public class EditIssue extends LoadableComponent<EditIssue> {

  private final WebDriver driver;
  
  // By default the PageFactory will locate elements with the same name or id
  // as the field. Since the issue_title element has an id attribute of "issue_title"
  // we don't need any additional annotations.
  private WebElement issue_title;
  
  // But we'd prefer a different name in our code than "issue_body", so we use the
  // FindBy annotation to tell the PageFactory how to locate the element.
  @FindBy(id = "issue_body") private WebElement body;
  
  public EditIssue(WebDriver driver) {
    this.driver = driver;
    
    // This call sets the WebElement fields.
    PageFactory.initElements(driver, this);
  }

  @Override
  protected void load() {
    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();
    assertTrue("Not on the issue entry page: " + url, url.endsWith("/new"));
  }

  public void setHowToReproduce(String howToReproduce) {
    WebElement field = driver.findElement(By.id("issue_form_repro-command"));
    clearAndType(field, howToReproduce);
  }

  public void setLogOutput(String logOutput) {
    WebElement field = driver.findElement(By.id("issue_form_logs"));
    clearAndType(field, logOutput);
  }

  public void setOperatingSystem(String operatingSystem) {
    WebElement field = driver.findElement(By.id("issue_form_operating-system"));
    clearAndType(field, operatingSystem);
  }

  public void setSeleniumVersion(String seleniumVersion) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-version"));
    clearAndType(field, logOutput);
  }

  public void setBrowserVersion(String browserVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-versions"));
    clearAndType(field, browserVersion);
  }

  public void setDriverVersion(String driverVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-driver-versions"));
    clearAndType(field, driverVersion);
  }

  public void setUsingGrid(String usingGrid) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-grid-version"));
    clearAndType(field, usingGrid);
  }

  public IssueList submit() {
    driver.findElement(By.cssSelector("button[type='submit']")).click();
    return new IssueList(driver);
  }

  private void clearAndType(WebElement field, String text) {
    field.clear();
    field.sendKeys(text);
  }
}
```

That doesn’t seem to have bought us much, right? One thing it has done is encapsulate the information about how to navigate to the page into the page itself, meaning that this information’s not scattered through the code base. It also means that we can do this in our tests:

```java
EditIssue page = new EditIssue(driver).get();
```

This call will cause the driver to navigate to the page if that’s necessary.

### Nested Components

LoadableComponents start to become more useful when they are used in conjunction with other LoadableComponents. Using our example, we could view the “edit issue” page as a component within a project’s website (after all, we access it via a tab on that site). You also need to be logged in to file an issue. We could model this as a tree of nested components:

```
 + ProjectPage
 +---+ SecuredPage
     +---+ EditIssue
```

What would this look like in code? For a start, each logical component would have its own class. The “load” method in each of them would “get” the parent. The end result, in addition to the EditIssue class above is:

ProjectPage.java:

```java
package com.example.webdriver;

import org.openqa.selenium.WebDriver;

import static org.junit.Assert.assertTrue;

public class ProjectPage extends LoadableComponent<ProjectPage> {

  private final WebDriver driver;
  private final String projectName;

  public ProjectPage(WebDriver driver, String projectName) {
    this.driver = driver;
    this.projectName = projectName;
  }

  @Override
  protected void load() {
    driver.get("http://" + projectName + ".googlecode.com/");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();

    assertTrue(url.contains(projectName));
  }
}
```

and SecuredPage.java:

```java
package com.example.webdriver;

import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import static org.junit.Assert.fail;

public class SecuredPage extends LoadableComponent<SecuredPage> {

  private final WebDriver driver;
  private final LoadableComponent<?> parent;
  private final String username;
  private final String password;

  public SecuredPage(WebDriver driver, LoadableComponent<?> parent, String username, String password) {
    this.driver = driver;
    this.parent = parent;
    this.username = username;
    this.password = password;
  }

  @Override
  protected void load() {
    parent.get();

    String originalUrl = driver.getCurrentUrl();

    // Sign in
    driver.get("https://www.google.com/accounts/ServiceLogin?service=code");
    driver.findElement(By.name("Email")).sendKeys(username);
    WebElement passwordField = driver.findElement(By.name("Passwd"));
    passwordField.sendKeys(password);
    passwordField.submit();

    // Now return to the original URL
    driver.get(originalUrl);
  }

  @Override
  protected void isLoaded() throws Error {
    // If you're signed in, you have the option of picking a different login.
    // Let's check for the presence of that.

    try {
      WebElement div = driver.findElement(By.id("multilogin-dropdown"));
    } catch (NoSuchElementException e) {
      fail("Cannot locate user name link");
    }
  }
}
```

The “load” method in EditIssue now looks like:

```java
  @Override
  protected void load() {
    securedPage.get();

    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }
```

This shows that the components are all “nested” within each other. A call to `get()` in EditIssue will cause all its dependencies to load too. The example usage:

```java
public class FooTest {
  private EditIssue editIssue;

  @Before
  public void prepareComponents() {
    WebDriver driver = new FirefoxDriver();

    ProjectPage project = new ProjectPage(driver, "selenium");
    SecuredPage securedPage = new SecuredPage(driver, project, "example", "top secret");
    editIssue = new EditIssue(driver, securedPage);
  }

  @Test
  public void demonstrateNestedLoadableComponents() {
    editIssue.get();

    editIssue.title.sendKeys('Title');
    editIssue.body.sendKeys('What Happened');
    editIssue.setHowToReproduce('How to Reproduce');
    editIssue.setLogOutput('Log Output');
    editIssue.setOperatingSystem('Operating System');
    editIssue.setSeleniumVersion('Selenium Version');
    editIssue.setBrowserVersion('Browser Version');
    editIssue.setDriverVersion('Driver Version');
    editIssue.setUsingGrid('I Am Using Grid');
  }
}
```

If you’re using a library such as [Guiceberry](https://github.com/zorzella/guiceberry) in your tests, the preamble of setting up the PageObjects can be omitted leading to nice, clear, readable tests.

## Bot Pattern

(previously located: <https://github.com/SeleniumHQ/selenium/wiki/Bot-Style-Tests>)

Although PageObjects are a useful way of reducing duplication in your tests, it’s not always a pattern that teams feel comfortable following. An alternative approach is to follow a more “command-like” style of testing.

A “bot” is an action-oriented abstraction over the raw Selenium APIs. This means that if you find that commands aren’t doing the Right Thing for your app, it’s easy to change them. As an example:

```java
public class ActionBot {
  private final WebDriver driver;

  public ActionBot(WebDriver driver) {
    this.driver = driver;
  }

  public void click(By locator) {
    driver.findElement(locator).click();
  }

  public void submit(By locator) {
    driver.findElement(locator).submit();
  }

  /** 
   * Type something into an input field. WebDriver doesn't normally clear these
   * before typing, so this method does that first. It also sends a return key
   * to move the focus out of the element.
   */
  public void type(By locator, String text) { 
    WebElement element = driver.findElement(locator);
    element.clear();
    element.sendKeys(text + "\n");
  }
}
```

```py
import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L6-L26)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L28-L65)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L67-L80)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L82-L172)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L174-L240)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

Última modificação May 6, 2025: [\[docs\]: fix build issues \[deploy site\] (7615cca5ebc)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/7615cca5ebc3a7681e9ec9e6cdb4b1ddd681ef00)

----
url: https://www.selenium.dev/zh-cn/_print/documentation/legacy/selenium_2/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/legacy/selenium_2/).

# Selenium 2

Selenium 2 是以实现了WebDriver代码重写的Selenium 1.

* 1: [从RC迁移到WebDriver](#pg-23e90ee960cb2d855aefe8e77f95e70b)
* 2: [远程WebDriver服务器](#pg-4385b6f362b0596ebcd161689f59adf4)

# 1 - 从RC迁移到WebDriver

```java
Selenium selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.yoursite.com");
selenium.start();
```

应该这样替换:

```java
WebDriver driver = new FirefoxDriver();
Selenium selenium = new WebDriverBackedSelenium(driver, "http://www.yoursite.com");
```

## 下一步

一旦测试成功执行, 下一步就是迁移实际的测试代码以使用WebDriver API. 根据代码的抽象程度, 这可能是一个短暂的过程, 也可能是一个漫长的过程. 在这两种情况下, 方法都是相同的, 可以简单地总结一下：修改代码以在使用新API时进行编辑.

如果您需要从Selenium实例中提取基础WebDriver实现, 则只需将其强制转换为WrapsDriver:

```java
WebDriver driver = ((WrapsDriver) selenium).getWrappedDriver();
```

这使您可以继续正常传递Selenium实例, 但可以根据需要解包WebDriver实例.

有时, 您的代码库将主要使用较新的API. 此时, 您可以翻转关系, 使用WebDriver并按需实例化Selenium实例:

```java
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);
```

## 常见问题

幸运的是, 您不是第一个进行此迁移的人, 因此这里有其他人已经看到的一些常见问题以及如何解决它们.

### 单击和键入更加完整

Selenium RC测试中的常见模式如下所示:

```java
selenium.type("name", "exciting tex");
selenium.keyDown("name", "t");
selenium.keyPress("name", "t");
selenium.keyUp("name", "t");
```

```java
Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(30));
WebElement element= wait.until(visibilityOfElementLocated(By.id("some_id")));
```

其中"visibilityOfElementLocated"实现为:

```java
public ExpectedCondition<WebElement> visibilityOfElementLocated(final By locator) {
  return new ExpectedCondition<WebElement>() {
    public WebElement apply(WebDriver driver) {
      WebElement toReturn = driver.findElement(locator);
      if (toReturn.isDisplayed()) {
        return toReturn;
      }
      return null;
    }
  };
}
```

这看起来很复杂, 但这几乎是所有样板代码. 唯一有趣的一点是, 将反复评估"ExpectedCondition", 直到"apply"方法返回的结果既不是"null" 也不是Boolean.FALSE.

当然, 添加所有这些"等待"调用可能会使您的代码混乱. 如果是这样, 并且您的需求很简单, 请考虑使用隐式等待:

```java
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
```

```java
String name = selenium.getEval(
    "selenium.browserbot.findElement('id=foo', browserbot.getCurrentWindow()).tagName");
```

变成:

```java
WebElement element = driver.findElement(By.id("foo"));
String name = (String) ((JavascriptExecutor) driver).executeScript(
    "return arguments[0].tagName", element);
```

请注意, 传入的"element"变量如何显示为JS标准"arguments"数组中的第一项.

### 执行JavaScript不会返回任何内容

WebDriver的JavascriptExecutor将包装所有JS并将其评估为匿名表达式. 这意味着您需要使用"return"关键字:

```java
String title = selenium.getEval("browserbot.getCurrentWindow().document.title");
```

变成:

```java
((JavascriptExecutor) driver).executeScript("return document.title;");
```

# 2 - 远程WebDriver服务器

服务器将始终在安装了待测浏览器的机器上运行. 可以从命令行或通过代码配置来使用服务器.

## 从命令行启动服务器

下载 `selenium-server-standalone-{VERSION}.jar` 后, 将其传到具有待测浏览器的电脑上. 然后, 切换到包含此jar文件的目录中, 运行以下命令:

```shell
java -jar selenium-server-standalone-{VERSION}.jar
```

## 运行服务器的注意事项

调用者应调用 `Selenium#stop()` 或 `WebDriver#quit` 以结束每次会话.

Selenium服务器在内存中保留每个运行会话的日志, 这些日志将在调用 `Selenium#stop()` 或 `WebDriver#quit` 时清除. 如果您忘记终止这些会话, 则可能会造成服务器内存泄漏. 如果您保持运行时间非常长的会话, 则可能需要不时执行停止或退出的操作 (或使用-Xmx jvm选项增加内存) .

## 超时 (自2.21版本)

服务器有两种不同的超时, 可以按如下设置:

```shell
java -jar selenium-server-standalone-{VERSION}.jar -timeout=20 -browserTimeout=60
```

```java
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.security.SslSocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;

import javax.servlet.Servlet;
import java.io.File;

import org.openqa.selenium.remote.server.DriverServlet;

public class AppServer {
  private Server server = new Server();

  public AppServer() throws Exception {
    WebAppContext context = new WebAppContext();
    context.setContextPath("");
    context.setWar(new File("."));
    server.addHandler(context);

    context.addServlet(DriverServlet.class, "/wd/*");

    SelectChannelConnector connector = new SelectChannelConnector();
    connector.setPort(3001);
    server.addConnector(connector);

    server.start();
  }
}
```

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/support_features/select_lists/
----

# Trabalhando com elementos select

```html
<select name="selectomatic">
    <option selected="selected" id="non_multi_option" value="one">One</option>
    <option value="two">Two</option>
    <option value="four">Four</option>
    <option value="still learning how to count, apparently">Still learning how to count, apparently</option>
</select>
```

### Multiple select

This select list allows selecting and deselecting more than one option at a time. This only applies to `<select>` elements with the `multiple` attribute.

```html
<select name="multi" id="multi" multiple="multiple">
    <option selected="selected" value="eggs">Eggs</option>
    <option value="ham">Ham</option>
    <option selected="selected" value="sausages">Sausages</option>
    <option value="onion gravy">Onion gravy</option>
</select>
```

```java
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L23-L24)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L9-L10)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L23-L24)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L13-L14)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js

  it('Select an option', async function () {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L18-L19)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L20-L21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        List<WebElement> optionList = select.getOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L51)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    option_list = select.options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L37)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            IList<IWebElement> optionList = select.Options;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L52)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    option_list = select.options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L40)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L45)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val optionList = select.getOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L48)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L54)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    selected_option_list = select.all_selected_options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L40)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L56)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    selected_option_list = select.selected_options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L43)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L51)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val selectedOptionList = select.getAllSelectedOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L51)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByVisibleText("Four");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L30)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_visible_text('Four')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L16)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByText("Four");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L30)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:text, 'Four')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L20)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L25)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByVisibleText("Four")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L27)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByValue("two");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L33)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_value('two')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L19)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByValue("two");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L33)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:value, 'two')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L23)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await fourElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L28)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByValue("two")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L30)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByIndex(3);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L36)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_index(3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L22)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByIndex(3);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L36)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:index, 3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L26)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await twoElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L31)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByIndex(3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L33)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

### Disabled options

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

Options with a `disabled` attribute may not be selected.

```html
    <select name="single_disabled">
      <option id="sinlge_disabled_1" value="enabled">Enabled</option>
      <option id="sinlge_disabled_2" value="disabled" disabled="disabled">Disabled</option>
    </select>
```

*
*
*
*
*
*

```java
        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L77-L79)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L60-L61)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L77)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L62-L64)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L73-L76)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L74-L76)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.deselectByValue("eggs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L66)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.deselect_by_value('eggs')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L49)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.DeselectByValue("eggs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L65)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.deselect_by(:value, 'eggs')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L52)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await gravyElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L63)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.deselectByValue("eggs")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

----
url: https://www.selenium.dev/ja/documentation/about/copyright/
----

# 著作権と帰属

| Software                            | Version  | License                                                     |
| ----------------------------------- | -------- | ----------------------------------------------------------- |
| [Hugo](/ja/)                        | v0.110.0 | [Apache 2.0](//gohugo.io/about/license/)                    |
| [Docsy](//github.com/google/docsy/) | —        | [Apache 2.0](//github.com/google/docsy/blob/master/LICENSE) |

## ライセンス

Seleniumプロジェクトから作成されたすべてのコードとドキュメントは、 Apache 2.0ライセンスに基づいてライセンスされており、 [Software Freedom Conservancy](/ja/) に著作権があります。

ライセンスは便宜上ここに含まれていますが、 [Apache FoundationのWebサイト](//apache.org/licenses/LICENSE-2.0.html)でも見つけることができます。

```markdown
                                 Apache License
                           Version 2.0, 2004年1月
                        http://www.apache.org/licenses/

   使用、複製、および頒布に関する条項

   1. 定義 　

      「ライセンス」とは、このドキュメントの第1項から第9項までで定義している、
      使用、複製、および頒布に関する条項を指します。

      「ライセンサー」とは、著作権所有者、あるいは著作権所有者が
      ライセンス付与対象として認めた者を指します。

      「法人」とは、行為者と、行為者を管理するか行為者により管理されるか
      行為者共通の管理下にある他のすべての者とから成る連合体を指します。
      この定義における「管理」とは、
      (i) 契約またはその他により、直接または間接的にこの法人の指揮・経営を行う権限、または
      (ii) この法人の50%以上の株式の所有権 または
      (iii) 受益所有権を有することを指します。

      「あなた」とは、本ライセンスにより付与される権利を行使する個人または法人を指します。

      「ソース」形式とは、ソフトウェアのソースコード、ドキュメントソース、
      設定ファイルといった、変更を加えるのに好都合な形式を指します。

      「オブジェクト」形式とは、コンパイルされたオブジェクトコード、生成されたドキュメント、
      他のメディアへの変換物といった、ソース形式の機械的な変換により生じる形式を指します。

      「成果物」とは、ソース形式であるとオブジェクト形式であるとを問わず、
      製作物に挿入または添付される（後出の付録に例がある）著作権表示で示された著作物で、
      本ライセンスに基づいて利用が許されるものを指します。

      「派生成果物」とは、編集上の改訂、注解、推敲など、
      成果物を基にしていて全体としてオリジナル著作物と呼べるような製作物全般を指します。
      本ライセンスでは、成果物や派生成果物から分離できる製作物や、
      成果物や派生成果物のインタフェースへの単なるリンク（または名前によるバインド）を、
      派生成果物に含めません。

      「コントリビューション」とは、成果物のオリジナルバージョンならびに成果物
      または派生成果物への変更や追加も含めて、著作権所有者あるいは著作権所有者が認めた
      個人または法人による成果物への組み込みを意図してライセンサーに提出される
      著作物全般を指します。
      この定義における「提出」とは、成果物を論じたり改良するためにライセンサー
      またはその代理者により管理される電子的メーリングリスト、ソースコード管理システム、
      問題追跡システムといった、電子的方法、口頭、または書面で、
      ライセンサーまたはその代理者に情報を送ることを指します。
      ただし、著作権所有者が書面で「コントリビューションでない」と明示したものは除きます。

      「コントリビューター」とは、ライセンサーおよびその代理を務める個人または法人で、
      自分のコントリビューションがライセンサーに受領されて成果物に組み込まれた者を指します。

   2. 著作権ライセンスの付与  
      本ライセンスの条項に従って、各コントリビューターはあなたに対し、
      ソース形式であれオブジェクト形式であれ、成果物および派生成果物を複製したり、
      派生成果物を作成したり、公に表示したり、公に実行したり、サブライセンスしたり、
      頒布したりする、無期限で世界規模で非独占的で使用料無料で取り消し不能な
      著作権ライセンスを付与します。

   3. 特許ライセンスの付与  
      本ライセンスの条項に従って、各コントリビューターはあなたに対し、
      成果物を作成したり、使用したり、販売したり、販売用に提供したり、
      インポートしたり、その他の方法で移転したりする、
      無期限で世界規模で非独占的で使用料無料で取り消し不能な
      （この項で明記したものは除く）特許ライセンスを付与します。
      ただし、このようなライセンスは、コントリビューターによって
      ライセンス可能な特許申請のうち、当該コントリビューターのコントリビューションを
      単独または該当する成果物と組み合わせて用いることで必然的に侵害されるものにのみ
      適用されます。
      あなたが誰かに対し、交差請求や反訴を含めて、
      成果物あるいは成果物に組み込まれたコントリビューションが
      直接または間接的な特許侵害に当たるとして特許訴訟を起こした場合、
      本ライセンスに基づいてあなたに付与された特許ライセンスは、
      そうした訴訟が正式に起こされた時点で終了するものとします。

   4. 再頒布  
      あなたは、ソース形式であれオブジェクト形式であれ、変更の有無に関わらず、
      以下の条件をすべて満たす限りにおいて、成果物またはその派生成果物のコピーを
      複製したり頒布したりすることができます。

      (a) 成果物または派生成果物の他の受領者に本ライセンスのコピーも渡すこと。

      (b) 変更を加えたファイルについては、あなたが変更したということが
      よくわかるような告知を入れること。

      (c) ソース形式の派生成果物を頒布する場合は、ソース形式の成果物に含まれている著作権、
      特許、商標、および帰属についての告知を、派生成果物のどこにも関係しないものは除いて、
      すべて派生成果物に入れること。

      (d) 成果物の一部として「NOTICE」に相当するテキストファイルが含まれている場合は、
      そうしたNOTICEファイルに含まれている帰属告知のコピーを、
      派生成果物のどこにも関係しないものは除いて、頒布する派生成果物に入れること。
      その際、次のうちの少なくとも1箇所に挿入すること。
      (i) 派生成果物の一部として頒布するNOTICEテキストファイル、
      (ii) ソース形式またはドキュメント（派生成果物と共にドキュメントを頒布する場合）、
      (iii) 派生成果物によって生成される表示
      （こうした第三者告知を盛り込むことが標準的なやり方になっている場合）。
      NOTICEファイルの内容はあくまで情報伝達用であって、
      本ライセンスを修正するものであってはなりません。
      あなたは頒布する派生成果物に自分の帰属告知を
      （成果物からのNOTICEテキストに並べて、またはその付録として）追加できますが、
      これはそうした追加の帰属告知が本ライセンスの修正と
      解釈されるおそれがない場合に限られます。

      あなたは自分の修正物に自らの著作権表示を追加することができ、
      自分の修正物の使用、複製、または頒布について、あるいはそうした派生成果物の全体について、
      付加的なライセンス条項または異なるライセンス条項を設けることができます。
      ただし、これは成果物についてのあなたの使用、複製、および頒布が、
      それ以外の点で本ライセンスの条項に従っている場合に限られます。

   5. コントリビューションの提出  
      特に断りがない限り、あなたが成果物への組み込みを意図してライセンサーに
      提出したコントリビューションは、付加的な条項がなければ、
      本ライセンスの条項に従うものとします。
      上述の規定にかかわらず、そうしたコントリビューションに関してあなたがライセンサーと
      結んだかもしれない別のライセンス契約の条項を、ここで無効にしたり
      修正したりすることはありません。

   6. 商標  
      本ライセンスでは、成果物の出所を記述したりNOTICEファイルの内容を複製するときに
      必要になる妥当で慣習的な使い方は別として、ライセンサーの商号、商標、サービスマーク、
      または製品名の使用権を付与しません。

   7. 保証の否認  
      適用される法律または書面での同意によって命じられない限り、
      ライセンサーは成果物を（そしてコントリビューターは各自のコントリビューションを）
      「現状のまま」提供するものとし、明示黙示を問わず、タイトル、非侵害性、
      商業的な使用可能性、および特定の目的に対する適合性を含め、
      いかなる保証も条件も提供しません。
      あなたは成果物の使用や再頒布の適切性を自分で判断する責任を持つと共に、
      本ライセンスにより付与される権利を行使することに伴うすべてのリスクを負うことになります。

   8. 責任の制限  
      いかなる条件および法理論においても、不法行為（過失を含む）、契約、
      またはその他いかなる場合でも、適用される法律または書面での同意によって命じられない限り、
      コントリビューターは本ライセンスまたは成果物の使い方に関連して生じる直接損害、
      間接損害、偶発的な損害、特別損害、懲罰的損害、または結果損害を含め、
      営業権の損失、業務の停止、コンピューター障害または誤作動、
      その他の商業上の損害や損失など、いかなる損害に対しても、
      たとえそうした損害の可能性をたとえ知らされていたとしても、
      あなたに責任を負わないものとします。

   9. 保証または追加的責任の引き受け  
      成果物またはその派生成果物を再頒布する際、あなたはサポート、保証、損害補償、
      またはその他の責任や、本ライセンスに矛盾しない権利を提示し、
      これを有料にすることができます。
      ただし、そうした責任を引き受ける場合、あなたはそれを自分自身のためにだけ
      自己責任として行えるのであって、他のコントリビューターのために行うことはできません。
      また、あなたはそうした保証や追加的責任のせいで他のコントリビューターに
      責任が降りかかったり賠償要求が出されたとしても、それらのコントリビューターに
      損害が及ぶのを防ぐと共に各コントリビューターの損害を補償することに同意しなければなりません。

   使用、複製、および頒布に関する条項の終わり

   付録： Apache Licenseの適用の仕方

      あなたの製作物にApache Licenseを適用するときは、次の定型文を添付してください。
      ただし、"[]"で囲まれている部分は、あなた自身の識別情報に置き換えてください
      （その際、角括弧は取り除きます）。
      また、この文言を該当するファイル形式に合ったコメント構文で囲んでください。
      さらに、第三者アーカイブ内での識別を容易にするため、
      ファイル名またはクラス名ならびに趣旨説明が著作権表示と同じ「印刷ページ」に
      現れるようにすることをお勧めします。

   Copyright [yyyy] [著作権所有者の名前]

   Apache License Version 2.0（「本ライセンス」）に基づいてライセンスされます。
   あなたがこのファイルを使用するためには、本ライセンスに従わなければなりません。
   本ライセンスのコピーは下記の場所から入手できます。

       http://www.apache.org/licenses/LICENSE-2.0

   適用される法律または書面での同意によって命じられない限り、
   本ライセンスに基づいて頒布されるソフトウェアは、明示黙示を問わず、
   いかなる保証も条件もなしに「現状のまま」頒布されます。
   本ライセンスでの権利と制限を規定した文言については、本ライセンスを参照してください。
```

最終更新 October 3, 2023: [Update hugo as required (#1491) (aa734862bf2)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/aa734862bf2ec42a6d06f000ff490bd5cb852003)

----
url: https://www.selenium.dev/ja/documentation/webdriver/bidi/cdp/script/
----

```java
    ScriptKey key = ((JavascriptExecutor) driver).pin("return arguments;");
    List<Object> arguments =
        (List<Object>) ((JavascriptExecutor) driver).executeScript(key, 1, true, element);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/ScriptTest.java#L32-L34)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/ScriptTest.java

```java
package dev.selenium.bidi.cdp;

import static org.openqa.selenium.devtools.events.CdpEventTypes.domMutation;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.HasLogEvents;
import org.openqa.selenium.support.ui.WebDriverWait;

public class ScriptTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void pinScript() {
    driver.get("https://www.selenium.dev/selenium/web/xhtmlTest.html");
    WebElement element = driver.findElement(By.id("id1"));

    ScriptKey key = ((JavascriptExecutor) driver).pin("return arguments;");
    List<Object> arguments =
        (List<Object>) ((JavascriptExecutor) driver).executeScript(key, 1, true, element);

    Assertions.assertEquals(List.of(1L, true, element), arguments);
  }

  @Test
  public void mutatedElements() {
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    CopyOnWriteArrayList<WebElement> mutations = new CopyOnWriteArrayList<>();

    ((HasLogEvents) driver).onLogEvent(domMutation(e -> mutations.add(e.getElement())));

    driver.findElement(By.id("reveal")).click();

    wait.until(_d -> !mutations.isEmpty());
    Assertions.assertEquals(mutations.get(0), driver.findElement(By.id("revealed")));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs#L21-L22)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs

```cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class ScriptTest : BaseChromeTest
    {
        [TestMethod]
        public async Task PinScript()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/xhtmlTest.html";
            var element = driver.FindElement(By.Id("id1"));

            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);

            var expected = new List<object>
            {
                1L,
                true,
                element
            };
            CollectionAssert.AreEqual(expected, (ICollection)arguments);
        }

        [TestMethod]
        public async Task MutatedElements()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            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();

            driver.FindElement(By.Id("reveal")).Click();
            
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !mutations.IsNullOrEmpty());
            await monitor.DisableDomMutationMonitoring();
            monitor.StopEventMonitoring();

            var revealed = driver.FindElement(By.Id("revealed")); 
            Assert.AreEqual(revealed, mutations[0]);
        }
    }
}
```

```rb
    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/script_spec.rb#L12-L13)

##### /examples/ruby/spec/bidi/cdp/script\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Script' do
  let(:driver) { start_session }

  it 'pins script' do
    driver.get('https://www.selenium.dev/selenium/web/xhtmlTest.html')
    element = driver.find_element(id: 'id1')

    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)

    expect(arguments).to eq([1, true, element])
  end

  it 'gets mutated elements' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'

    mutations = []
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }

    driver.find_element(id: 'reveal').click
    Selenium::WebDriver::Wait.new(timeout: 30).until { mutations.any? }

    expect(mutations).to include(driver.find_element(id: 'revealed'))
  end
end
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).mutation_events() as event:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_script.py#L10-L11)

##### /examples/python/tests/bidi/cdp/test\_script.py

```py
import pytest
import trio
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

@pytest.mark.trio
async def test_mutation(driver):
    async with driver.bidi_connection() as session:
        async with Log(driver, session).mutation_events() as event:
            await trio.to_thread.run_sync(lambda: driver.get('https://www.selenium.dev/selenium/web/dynamic.html'))
            await trio.to_thread.run_sync(lambda: WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "reveal"))))
            await trio.to_thread.run_sync(lambda: driver.find_element(By.ID, "reveal").click())

    assert event["element"] == driver.find_element(By.ID, "revealed")
```

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs#L39-L46)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs

```cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class ScriptTest : BaseChromeTest
    {
        [TestMethod]
        public async Task PinScript()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/xhtmlTest.html";
            var element = driver.FindElement(By.Id("id1"));

            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);

            var expected = new List<object>
            {
                1L,
                true,
                element
            };
            CollectionAssert.AreEqual(expected, (ICollection)arguments);
        }

        [TestMethod]
        public async Task MutatedElements()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            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();

            driver.FindElement(By.Id("reveal")).Click();
            
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !mutations.IsNullOrEmpty());
            await monitor.DisableDomMutationMonitoring();
            monitor.StopEventMonitoring();

            var revealed = driver.FindElement(By.Id("revealed")); 
            Assert.AreEqual(revealed, mutations[0]);
        }
    }
}
```

```rb
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/script_spec.rb#L22)

##### /examples/ruby/spec/bidi/cdp/script\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Script' do
  let(:driver) { start_session }

  it 'pins script' do
    driver.get('https://www.selenium.dev/selenium/web/xhtmlTest.html')
    element = driver.find_element(id: 'id1')

    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)

    expect(arguments).to eq([1, true, element])
  end

  it 'gets mutated elements' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'

    mutations = []
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }

    driver.find_element(id: 'reveal').click
    Selenium::WebDriver::Wait.new(timeout: 30).until { mutations.any? }

    expect(mutations).to include(driver.find_element(id: 'revealed'))
  end
end
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Add Example](/documentation/about/contributing/#creating-examples)

最終更新 November 5, 2024: [Add examples for Drivers HTTP Client in Java and Python (#2041) (2ce6752bfc8)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/2ce6752bfc8a0d1643519fbbe6934f903e33d097)

----
url: https://www.selenium.dev/documentation/webdriver/troubleshooting/logging/
----

# Logging Selenium commands

```java
    public void logging() throws IOException {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Java Logging is not exactly straightforward, and if you are just looking for an easy way to look at the important Selenium logs, take a look at the [Selenium Logger project](https://github.com/titusfortner/selenium-logger#selenium-logger)

Python logs are typically created per module. You can match all submodules by referencing the top level module. So to work with all loggers in selenium module, you can do this:

```py
    logger = logging.getLogger('selenium')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L5)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

You must also create and add a log handler (`StreamHandler`, `FileHandler`, etc).

To save logs to a file, you can do this:

```py
log_path = '/path/to/log'
handler = logging.FileHandler(log_path)
logger.addHandler(handler)
```

To display logs in the console, you can do this:

```py
handler = logging.StreamHandler()
logger.addHandler(handler)
```

.NET logger is managed with a static class, so all access to logging is managed simply by referencing `Log` from the `OpenQA.Selenium.Internal.Logging` namespace.

If you want to see as much debugging as possible in all the classes, you can turn on debugging globally in Ruby by setting `$DEBUG = true`.

For more fine-tuned control, Ruby Selenium created its own Logger class to wrap the default `Logger` class. This implementation provides some interesting additional features. Obtain the logger directly from the `#logger`class method on the `Selenium::WebDriver` module:

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
    logger = Selenium::WebDriver.logger
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L11)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

```javascript
const logging = require('selenium-webdriver/lib/logging')
logger = logging.getLogger('webdriver')
```

```java
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L32-L35)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Python has 6 logger levels: `CRITICAL`, `ERROR`, `WARNING`, `INFO`, `DEBUG`, and `NOTSET`. The default is `WARNING`

To change the level of the logger:

```py
    logger.setLevel(logging.DEBUG)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L7)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

Things get complicated when you use PyTest, though. By default, PyTest hides logging unless the test fails. You need to set 3 things to get PyTest to display logs on passing tests.

To always output logs with PyTest you need to run with additional arguments. First, `-s` to prevent PyTest from capturing the console. Second, `-p no:logging`, which allows you to override the default PyTest logging settings so logs can be displayed regardless of errors.

So you need to set these flags in your IDE, or run PyTest on command line like:

```bash
pytest -s -p no:logging
```

Finally, since you turned off logging in the arguments above, you now need to add configuration to turn it back on:

```py
logging.basicConfig(level=logging.WARN)
```

.NET has 6 logger levels: `Error`, `Warn`, `Info`, `Debug`, `Trace` and `None`. The default level is `Warn`.

To change the level of the logger:

```cs
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L18)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

Ruby logger has 5 logger levels: `:debug`, `:info`, `:warn`, `:error`, `:fatal`. The default is `:info`.

To change the level of the logger:

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
    logger.level = :debug
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L13)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

JavaScript has 9 logger levels: `OFF`, `SEVERE`, `WARNING`, `INFO`, `DEBUG`, `FINE`, `FINER`, `FINEST`, `ALL`. The default is `OFF`.

To change the level of the logger:

```javascript
logger.setLevel(logging.Level.INFO)
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
WARNING: this is a warning
```

Python logs actionable content at logger level — `WARNING` Details about deprecations are logged at this level.

Example:

```text
WARNING  selenium:test_logging.py:23 this is a warning
```

.NET logs actionable content at logger level `Warn`.

Example:

```text
11:04:40.986 WARN LoggingTest: this is a warning
```

Ruby logs actionable content at logger level — `:warn`. Details about deprecations are logged at this level.

For example:

```text
2023-05-08 20:53:13 WARN Selenium [:example_id] this is a warning 
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
INFO: this is useful information
```

Python logs useful information at logger level — `INFO`

Example:

```text
INFO     selenium:test_logging.py:22 this is useful information
```

.NET logs useful information at logger level `Info`.

Example:

```text
11:04:40.986 INFO LoggingTest: this is useful information
```

Ruby logs useful information at logger level — `:info`.

Example:

```text
2023-05-08 20:53:13 INFO Selenium [:example_id] this is useful information 
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
FINE: this is detailed debug information
```

Python logs debugging details at logger level — `DEBUG`

Example:

```text
DEBUG    selenium:test_logging.py:24 this is detailed debug information
```

.NET logs most debug content at logger level `Debug`.

Example:

```text
11:04:40.986 DEBUG LoggingTest: this is detailed debug information
```

Ruby only provides one level for debugging, so all details are at logger level — `:debug`.

Example:

```text
2023-05-08 20:53:13 DEBUG Selenium [:example_id] this is detailed debug information 
```

```java

      Path output = artifactsDir().resolve("selenium.xml");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L37-L38)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

By default all logs are sent to `sys.stderr`. To direct output somewhere else, you need to add a handler with either a `StreamHandler` or a `FileHandler`:

```py
    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L9-L10)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

By default all logs are sent to `System.Console.Error` output. To direct output somewhere else, you need to add a handler with a `FileLogHandler`:

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L20)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

By default, logs are sent to the console in `stdout`.\
To store the logs in a file:

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
    logger.output = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L15)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

JavaScript does not currently support sending output to a file.

To send logs to console output:

```javascript
logging.installConsoleHandler()
```

```java
        logger.addHandler(handler);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L40-L41)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Because logging is managed by module, instead of working with just "selenium", you can specify different levels for different modules:

```py
    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L12-L13)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

.NET logging is managed on a per class level, set the level you want to use on a per-class basis:

```cs

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

Ruby’s logger allows you to opt in (“allow”) or opt out (“ignore”) of log messages based on their IDs. Everything that Selenium logs includes an ID. You can also turn on or off all deprecation notices by using `:deprecations`.

These methods accept one or more symbols or an array of symbols:

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
    logger.ignore(:jwp_caps, :logger_info)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#17)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

or

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
    logger.allow(%i[selenium_manager example_id])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L18)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

Last modified August 13, 2025: [\[dotnet\] Change default internal log level to Warn (#2409) (22fad037ea6)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/22fad037ea6c457abc65c64d37d6c299bde40a4d)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/support_features/colors/
----

# Trabalhando com cores

```java
import org.openqa.selenium.support.Color;
  
```

```python
from selenium.webdriver.support.color import Color
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
include Selenium::WebDriver::Support
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
import org.openqa.selenium.support.Color
```

```java
private final Color HEX_COLOUR = Color.fromString("#2F7ED8");
private final Color RGB_COLOUR = Color.fromString("rgb(255, 255, 255)");
private final Color RGB_COLOUR = Color.fromString("rgb(40%, 20%, 40%)");
private final Color RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)");
private final Color RGBA_COLOUR = Color.fromString("rgba(40%, 20%, 40%, 0.5)");
private final Color HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)");
private final Color HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)");
  
```

```python
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
  
```

```javascript
// Essa funcionalidade não está implementada - Nos ajude enviando um PR implementando essa funcionalidade
  
```

```kotlin
private val HEX_COLOUR = Color.fromString("#2F7ED8")
private val RGB_COLOUR = Color.fromString("rgb(255, 255, 255)")
private val RGB_COLOUR_PERCENT = Color.fromString("rgb(40%, 20%, 40%)")
private val RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)")
private val RGBA_COLOUR_PERCENT = Color.fromString("rgba(40%, 20%, 40%, 0.5)")
private val HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)")
private val HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)")
  
```

```java
private final Color BLACK = Color.fromString("black");
private final Color CHOCOLATE = Color.fromString("chocolate");
private final Color HOTPINK = Color.fromString("hotpink");
  
```

```python
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
  
```

```javascript
// Essa funcionalidade não está implementada - Nos ajude enviando um PR implementando essa funcionalidade
  
```

```kotlin
private val BLACK = Color.fromString("black")
private val CHOCOLATE = Color.fromString("chocolate")
private val HOTPINK = Color.fromString("hotpink")
  
```

```java
private final Color TRANSPARENT = Color.fromString("transparent");
  
```

```python
TRANSPARENT = Color.from_string('transparent')
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
TRANSPARENT = Color.from_string('transparent')
  
```

```javascript
// Essa funcionalidade não está implementada - Nos ajude enviando um PR implementando essa funcionalidade
  
```

```kotlin
private val TRANSPARENT = Color.fromString("transparent")
  
```

```java
Color loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"));

Color loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"));
  
```

```python
login_button_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('color'))

login_button_background_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('background-color'))
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
login_button_colour = Color.from_string(driver.find_element(id: 'login').css_value('color'))

login_button_background_colour = Color.from_string(driver.find_element(id: 'login').css_value('background-color'))
  
```

```javascript
// Essa funcionalidade não está implementada - Nos ajude enviando um PR implementando essa funcionalidade
  
```

```kotlin
val loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"))

val loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"))
  
```

```java
assert loginButtonBackgroundColour.equals(HOTPINK);
  
```

```python
assert login_button_background_colour == HOTPINK
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
assert(login_button_background_colour == HOTPINK)
  
```

```javascript
// Essa funcionalidade não está implementada - Nos ajude enviando um PR implementando essa funcionalidade
  
```

```kotlin
assert(loginButtonBackgroundColour.equals(HOTPINK))
  
```

```java
assert loginButtonBackgroundColour.asHex().equals("#ff69b4");
assert loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)");
assert loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)");
  
```

```python
assert login_button_background_colour.hex == '#ff69b4'
assert login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)'
assert login_button_background_colour.rgb == 'rgb(255, 105, 180)'
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
assert(login_button_background_colour.hex == '#ff69b4')
assert(login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)')
assert(login_button_background_colour.rgb == 'rgb(255, 105, 180)')
  
```

```javascript
// Essa funcionalidade não está implementada - Nos ajude enviando um PR implementando essa funcionalidade
  
```

```kotlin
assert(loginButtonBackgroundColour.asHex().equals("#ff69b4"))
assert(loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)"))
assert(loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)"))
  
```

As cores não são mais um problema.

Última modificação August 3, 2023: [update wait documentation (#1358)\[deploy site\] (d1af4fe2409)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/d1af4fe2409e2101eaabf23f4e5716428e0bdd56)

----
url: https://www.selenium.dev/ja/_print/documentation/ie_driver_server/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/ie_driver_server/).

# IE Driver サーバー

Internet Explorer Driverは、WebDriverの仕様を実装するスタンドアロンサーバーです。

* 1: [Internet Explorer Driver Internals](#pg-b15bb615b8783ef0142b053c9b6e4cc6)

| Switch                         | 意味                                                                                    |
| ------------------------------ | ------------------------------------------------------------------------------------- |
| –port=`<portNumber>`           | IEドライバーのHTTPサーバーが言語バインディングからのコマンドをリッスンするポートを指定します。 デフォルトは5555です。                      |
| –host=`<hostAdapterIPAddress>` | IEドライバーのHTTPサーバーが言語バインディングからのコマンドをリッスンするホストアダプターのIPアドレスを指定します。 デフォルトは127.0.0.1です。     |
| –log-level=`<logLevel>`        | ロギングメッセージを出力するレベルを指定します。 有効な値は、FATAL、ERROR、WARN、INFO、DEBUG、およびTRACEです。 デフォルトはFATALです。 |
| –log-file=`<logFile>`          | ログファイルのフルパスとファイル名を指定します。 デフォルトはstdoutです。                                              |
| –extract-path=`<path>`         | サーバーが使用するサポートファイルの抽出に使用されるディレクトリへのフルパスを指定します。 指定しない場合、デフォルトでTEMPディレクトリになります。          |
| –silent                        | サーバーの起動時に診断出力を抑制します。                                                                  |

## 重要なシステムプロパティ

次のシステムプロパティ（Javaコードで `System.getProperty()` を使用して読み取り、 `System.setProperty()` または “`-DpropertyName=value`” コマンドラインフラグを使用して設定）は、 `InternetExplorerDriver` によって利用されます。

| **プロパティ**                         | **意味**                                                                                |
| --------------------------------- | ------------------------------------------------------------------------------------- |
| `webdriver.ie.driver`             | IEドライバーバイナリの場所                                                                        |
| `webdriver.ie.driver.host`        | IEドライバーがリッスンするホストアダプターのIPアドレスを指定します。                                                  |
| `webdriver.ie.driver.loglevel`    | ロギングメッセージを出力するレベルを指定します。 有効な値は、FATAL、ERROR、WARN、INFO、DEBUG、およびTRACEです。 デフォルトはFATALです。 |
| `webdriver.ie.driver.logfile`     | ログファイルのフルパスとファイル名を指定します。                                                              |
| `webdriver.ie.driver.silent`      | IEドライバーの起動時に診断出力を抑制します。                                                               |
| `webdriver.ie.driver.extractpath` | サーバーが使用するサポートファイルの抽出に使用されるディレクトリへのフルパスを指定します。 指定しない場合、デフォルトでTEMPディレクトリになります。          |

----
url: https://www.selenium.dev/documentation/legacy/desired_capabilities/
----

# Legacy Selenium Desired Capabilities

These capabilities worked with the legacy JSON Wire Protocol

This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/DesiredCapabilities)\
See [JSON Wire Protocol](https://www.selenium.dev/documentation/legacy/json_wire_protocol/#capabilities-json-object) for common capabilities.

## Remote Driver Specific

| **Key**                          | **Type** | **Description**                                                                                                                    |
| -------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| webdriver.remote.sessionid       | string   | WebDriver session ID for the session. Readonly and only returned if the server implements a server-side webdriver-backed selenium. |
| webdriver.remote.quietExceptions | boolean  | Disable automatic screenshot capture on exceptions. This is False by default.                                                      |

## Grid Specific

| **Key**          | **Type** | **Description**                                              |
| ---------------- | -------- | ------------------------------------------------------------ |
| path             | string   | Path to route request to, or maybe listen on.                |
| seleniumProtocol | string   | Which protocol to use. Accepted values: WebDriver, Selenium. |
| maxInstances     | integer  | Maximum number of instances to allow to connect to grid      |
| environment      | string   | Possible duplicate of browserName? See RegistrationRequest   |

## Selenium RC Specific

| Key                      | Type              | Description                                                                                                                   |
| ------------------------ | ----------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| proxy\_pac               | boolean           | Legacy proxy mechanism. Do not use.                                                                                           |
| commandLineFlags         | string            | Flags to pass to browser command line.                                                                                        |
| executablePath           | string            | Path to browser executable.                                                                                                   |
| timeoutInSeconds         | long integer      | Timeout to wait for the browser to launch, in seconds.                                                                        |
| onlyProxySeleniumTraffic | boolean           | Whether to only proxy selenium traffic. See browserlaunchers.Proxies                                                          |
| avoidProxy               | boolean           | ??? See browserlaunchers.Proxies                                                                                              |
| proxyEverything          | boolean           | ??? See browserlaunchers.Proxies                                                                                              |
| proxyRequired            | boolean           | ??? See browserlaunchers.Proxies                                                                                              |
| browserSideLog           | boolean           | ??? See AbstractBrowserLauncher.                                                                                              |
| optionsSet               | boolean           | ??? See BrowserOptions.                                                                                                       |
| singleWindow             | boolean           | Whether to enable single window mode.                                                                                         |
| dontInjectRegex          | javascript RegExp | Regular expression that proxy injection mode can use to know when to bypss injection. Ignored if not in proxy injection mode. |
| userJSInjection          | boolean           | ??? Whether to inject user JS. Ignored if not in proxy injection mode.                                                        |
| userExtensions           | string            | Path to a JavaScript file that will be loaded into selenium.                                                                  |

## Selenese-Backed-WebDriver specific

| Key                 | Type   | Description                                           |
| ------------------- | ------ | ----------------------------------------------------- |
| selenium.server.url | string | URL of Selenium server to use, to back this WebDriver |

## Firefox specific

| Key                     | Type    | Description                            |
| ----------------------- | ------- | -------------------------------------- |
| captureNetworkTraffic   | boolean | Whether to capture network traffic.    |
| addCustomRequestHeaders | boolean | Whether to add custom request headers. |
| trustAllSSLCertificates | boolean | Whether to trust all SSL certificates. |
| changeMaxConnections    | boolean | ??? See FirefoxChromeLauncher.         |
| firefoxProfileTemplate  | string  | ??? See FirefoxChromeLauncher.         |
| profile                 | string  | ??? See FirefoxChromeLauncher          |

### FirefoxProfile settings

Preferences accepted by the FirefoxProfile with special meaning, in the WebDriver API:

| **Key**                              | **Type** | **Description**                                                                                                                                                                                       |
| ------------------------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| webdriver\_accept\_untrusted\_certs  | boolean  | Whether to trust all SSL certificates. TODO: Maybe in some way different to the acceptSslCerts or trustAllSSLCertificates capabilities.                                                               |
| webdriver\_assume\_untrusted\_issuer | boolean  | Whether to trust all SSL certificate issuers. TODO: Maybe in some way different to the acceptSslCerts or trustAllSSLCertificates capabilities.                                                        |
| webdriver.log.driver                 | string   | Level at which to log FirefoxDriver logging statements to a temporary file, so that they can be retrieved by a getLogs command. Available options; DEBUG, INFO, WARNING, ERROR, OFF. Defaults to OFF. |
| webdriver.log.file                   | string   | Path to file to which to copy firefoxdriver logging output. Defaults to no file (like /dev/null).                                                                                                     |
| webdriver.load.strategy              | string   | Experimental API. Defines different strategies for how long to wait until a page is loaded. Values: unstable, conservative. Defaults to conservative.                                                 |
| webdriver\_firefox\_port             | integer  | Port to listen on for WebDriver commands. Defaults to 7055.                                                                                                                                           |

## IE specific

| Key                 | Type    | Description                                                                                                                                                  |
| ------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| killProcessesByName | boolean | Whether to try to kill processes by name, instead (or addition) to killing processes we happen to have handles to.                                           |
| honorSystemProxy    | boolean | Whether to honor the system proxy.                                                                                                                           |
| ensureCleanSession  | boolean | Whether to make sure the session has no cookies or temporary internet files on Windows. I believe this is passed to the IEDriver as well, but ignored by it. |

## Safari specific

| Key                | Type    | Description                                                                                                                              |
| ------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| honorSystemProxy   | boolean | Whether to honour the system proxy.                                                                                                      |
| ensureCleanSession | boolean | Whether to make sure the session has no cookies, cache entries. And that any registry and proxy settings are restored after the session. |

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/overview/
----

# 测试自动化概述

```java
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
User user = UserFactory.createCommonUser(); //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
AccountPage accountPage = loginAs(user.getEmail(), user.getPassword());
  
```

```python
# Create a user who has read-only permissions--they can configure a unicorn,
# but they do not have payment information set up, nor do they have
# administrative privileges. At the time the user is created, its email
# address and password are randomly generated--you don't even need to
# know them.
user = user_factory.create_common_user() #This method is defined elsewhere.

# Log in as this user.
# Logging in on this site takes you to your personal "My Account" page, so the
# AccountPage object is returned by the loginAs method, allowing you to then
# perform actions from the AccountPage.
account_page = login_as(user.get_email(), user.get_password())
  
```

```csharp
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
User user = UserFactory.CreateCommonUser(); //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
AccountPage accountPage = LoginAs(user.Email, user.Password);
  
```

```ruby
# Create a user who has read-only permissions--they can configure a unicorn,
# but they do not have payment information set up, nor do they have
# administrative privileges. At the time the user is created, its email
# address and password are randomly generated--you don't even need to
# know them.
user = UserFactory.create_common_user #This method is defined elsewhere.

# Log in as this user.
# Logging in on this site takes you to your personal "My Account" page, so the
# AccountPage object is returned by the loginAs method, allowing you to then
# perform actions from the AccountPage.
account_page = login_as(user.email, user.password)
  
```

```javascript
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
var user = userFactory.createCommonUser(); //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
var accountPage = loginAs(user.email, user.password);
  
```

```kotlin
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
val user = UserFactory.createCommonUser() //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
val accountPage = loginAs(user.getEmail(), user.getPassword())
  
```

```java
// The Unicorn is a top-level Object--it has attributes, which are set here.
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
Unicorn sparkles = new Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS);

// Since we're already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.
AddUnicornPage addUnicornPage = accountPage.addUnicorn();

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
UnicornConfirmationPage unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles);
  
```

```python
# The Unicorn is a top-level Object--it has attributes, which are set here.
# This only stores the values; it does not fill out any web forms or interact
# with the browser in any way.
sparkles = Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

# Since we're already "on" the account page, we have to use it to get to the
# actual place where you configure unicorns. Calling the "Add Unicorn" method
# takes us there.
add_unicorn_page = account_page.add_unicorn()

# Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
# its createUnicorn() method. This method will take Sparkles' attributes,
# fill out the form, and click submit.
unicorn_confirmation_page = add_unicorn_page.create_unicorn(sparkles)
  
```

```csharp
// The Unicorn is a top-level Object--it has attributes, which are set here. 
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
Unicorn sparkles = new Unicorn("Sparkles", UnicornColors.Purple, UnicornAccessories.Sunglasses, UnicornAdornments.StarTattoos);

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.
AddUnicornPage addUnicornPage = accountPage.AddUnicorn();

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
UnicornConfirmationPage unicornConfirmationPage = addUnicornPage.CreateUnicorn(sparkles);
  
```

```ruby
# The Unicorn is a top-level Object--it has attributes, which are set here.
# This only stores the values; it does not fill out any web forms or interact
# with the browser in any way.
sparkles = Unicorn.new('Sparkles', UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

# Since we're already "on" the account page, we have to use it to get to the
# actual place where you configure unicorns. Calling the "Add Unicorn" method
# takes us there.
add_unicorn_page = account_page.add_unicorn

# Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
# its createUnicorn() method. This method will take Sparkles' attributes,
# fill out the form, and click submit.
unicorn_confirmation_page = add_unicorn_page.create_unicorn(sparkles)
  
```

```javascript
// The Unicorn is a top-level Object--it has attributes, which are set here.
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
var sparkles = new Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS);

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.

var addUnicornPage = accountPage.addUnicorn();

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
var unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles);

  
```

```kotlin
// The Unicorn is a top-level Object--it has attributes, which are set here. 
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
val sparkles = Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.
val addUnicornPage = accountPage.addUnicorn()

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles)

  
```

```java
// The exists() method from UnicornConfirmationPage will take the Sparkles
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
Assert.assertTrue("Sparkles should have been created, with all attributes intact", unicornConfirmationPage.exists(sparkles));
  
```

```python
# The exists() method from UnicornConfirmationPage will take the Sparkles
# object--a specification of the attributes you want to see, and compare
# them with the fields on the page.
assert unicorn_confirmation_page.exists(sparkles), "Sparkles should have been created, with all attributes intact"
  
```

```csharp
// The exists() method from UnicornConfirmationPage will take the Sparkles 
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
Assert.True(unicornConfirmationPage.Exists(sparkles), "Sparkles should have been created, with all attributes intact");
  
```

```ruby
# The exists() method from UnicornConfirmationPage will take the Sparkles
# object--a specification of the attributes you want to see, and compare
# them with the fields on the page.
expect(unicorn_confirmation_page.exists?(sparkles)).to be, 'Sparkles should have been created, with all attributes intact'
  
```

```javascript
// The exists() method from UnicornConfirmationPage will take the Sparkles
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
assert(unicornConfirmationPage.exists(sparkles), "Sparkles should have been created, with all attributes intact");

  
```

```kotlin
// The exists() method from UnicornConfirmationPage will take the Sparkles 
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
assertTrue("Sparkles should have been created, with all attributes intact", unicornConfirmationPage.exists(sparkles))
  
```

请注意，测试人员在这段代码中除了谈论独角兽之外还没有做任何事情 — 没有按钮、定位器和浏览器控件。 这种对应用程序建模的方法允许您保持这些测试级别的命令不变， 即使 Larry 下周决定不再喜欢 Ruby-on-Rails， 并决定用最新的带有 Fortran 前端的 Haskell 绑定重新实现整个站点。

为了符合站点的重新设计，您的页面对象需要进行一些小的维护，但是这些测试将保持不变。 采用这一基本设计，您将希望继续使用尽可能少的面向浏览器的步骤来完成您的工作流。 您的下一个工作流程将包括在购物车中添加独角兽。 您可能需要多次迭代此测试，以确保购物车正确地保持其状态： 在开始之前，购物车中是否有多个独角兽? 购物车能装多少? 如果您创建多个具有相同名称或特性，它会崩溃吗? 它将只保留现有的一个还是添加另一个?

每次通过工作流时，您都希望尽量避免创建帐户、以用户身份登录和配置独角兽。 理想情况下，您将能够创建一个帐户，并通过 API 或数据库预先配置独角兽。 然后，您只需作为用户登录，找到 Sparkles，并将它添加到购物车中。

### 是否自动化?

自动化总是有优势吗? 什么时候应该决定去自动化测试用例?

自动化测试用例并不总是有利的. 有时候手动测试可能更合适. 例如，如果应用程序的用户界面，在不久的将来会发生很大变化，那么任何自动化都可能需要重写. 此外，有时根本没有足够的时间来构建自动化测试. 从短期来看，手动测试可能更有效. 如果应用程序的截止日期非常紧迫，当前没有可用的自动化测试，并且必须在特定时间范围内完成，那么手动测试是最好的解决方案.

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/encouraged/domain_specific_language/
----

# 领域特定语言

```java
/**
 * Takes a username and password, fills out the fields, and clicks "login".
 * @return An instance of the AccountPage
 */
public AccountPage loginAsUser(String username, String password) {
  WebElement loginField = driver.findElement(By.id("loginField"));
  loginField.clear();
  loginField.sendKeys(username);

  // Fill out the password field. The locator we're using is "By.id", and we should
  // have it defined elsewhere in the class.
  WebElement passwordField = driver.findElement(By.id("password"));
  passwordField.clear();
  passwordField.sendKeys(password);

  // Click the login button, which happens to have the id "submit".
  driver.findElement(By.id("submit")).click();

  // Create and return a new instance of the AccountPage (via the built-in Selenium
  // PageFactory).
  return PageFactory.newInstance(AccountPage.class);
}
```

此方法完全从测试代码中抽象出输入字段, 按钮, 单击甚至页面的概念. 使用这种方法, 测试人员要做的就是调用此方法. 这给您带来了维护方面的优势: 如果登录字段曾经更改过, 则只需更改此方法-而非您的测试.

```java
public void loginTest() {
    loginAsUser("cbrown", "cl0wn3");

    // Now that we're logged in, do some other stuff--since we used a DSL to support
    // our testers, it's as easy as choosing from available methods.
    do.something();
    do.somethingElse();
    Assert.assertTrue("Something should have been done!", something.wasDone());

    // Note that we still haven't referred to a button or web control anywhere in this
    // script...
}
```

郑重强调: 您的主要目标之一应该是编写一个API, 该API允许您的测试解决 **当前的问题, 而不是UI的问题**. 用户界面是用户的次要问题–用户并不关心用户界面, 他们只是想完成工作. 您的测试脚本应该像用户希望做的事情以及他们想知道的事情的完整清单那样易于阅读. 测试不应该考虑UI如何要求您去做.

\***AUT**: 待测系统

----
url: https://www.selenium.dev/ja/documentation/test_practices/discouraged/performance_testing/
----

# パフォーマンステスト

通常、SeleniumとWebDriverを使用したパフォーマンステストはお勧めしません。 それができないからではなく、ジョブに最適化されておらず、良い結果が得られないからです。

ユーザーのコンテキストでパフォーマンステストを行うのが理想的なように思えるかもしれませんが、WebDriverテストスイートは、外部および内部の脆弱性の多くのポイントにさらされます。 たとえば、ブラウザの起動速度、HTTPサーバーの速度、JavaScriptまたはCSSをホストするサードパーティサーバーの応答、およびWebDriver実装自体の計測ペナルティ。 これらのポイントが変わることで、結果が変わります。 Webサイトのパフォーマンスと外部リソースのパフォーマンスの違いを区別することは困難です。また、ブラウザでWebDriverを使用すること、特にスクリプトを挿入する場合のパフォーマンスの低下を把握することも困難です。

他の潜在的な魅力は “時間の節約” です。 機能テストとパフォーマンステストを同時に実行します。 ただし、機能テストとパフォーマンステストには反対の目的があります。 機能をテストするために、テスターは忍耐強くロードを待つ必要があるかもしれませんが、これはパフォーマンステスト結果を曖昧にし、その逆もまた同様です。

Webサイトのパフォーマンスを改善するには、改善すべき点を知るために、環境の違いに関係なく全体的なパフォーマンスを分析し、貧弱なコードプラクティス、個々のリソース（例えば、CSSまたはJavaScript）のパフォーマンスの内訳を特定できる必要があります。 このジョブを実行できるパフォーマンステストツールが既にあり、それらは改善を提案できるレポートと分析を提供します。

使用する（オープンソース）パッケージの例は次のとおりです。: [JMeter](/ja/)

----
url: https://www.selenium.dev/documentation/legacy/json_wire_protocol/
----

# JSON Wire Protocol Specification

| **Key** | **Type** | **Description**                                                                                                                    |
| ------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| ELEMENT | string   | The opaque ID assigned to the element by the server. This ID should be used in all subsequent commands issued against the element. |

### Capabilities JSON Object

Not all server implementations will support every WebDriver feature. Therefore, the client and server should use JSON objects with the properties listed below when describing which features a session supports.

| **Key**                  | **Type**     | **Description**                                                                                                                                                                                                                                          |
| ------------------------ | ------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| browserName              | string       | The name of the browser being used; should be one of `{android, chrome, firefox, htmlunit, internet explorer, iPhone, iPad, opera, safari}`.                                                                                                             |
| version                  | string       | The browser version, or the empty string if unknown.                                                                                                                                                                                                     |
| platform                 | string       | A key specifying which platform the browser is running on. This value should be one of `{WINDOWS\|XP\|VISTA\|MAC\|LINUX\|UNIX}`. When requesting a new session, the client may specify `ANY` to indicate any available platform may be used.             |
| javascriptEnabled        | boolean      | Whether the session supports executing user supplied JavaScript in the context of the current page.                                                                                                                                                      |
| takesScreenshot          | boolean      | Whether the session supports taking screenshots of the current page.                                                                                                                                                                                     |
| handlesAlerts            | boolean      | Whether the session can interact with modal popups, such as `window.alert` and `window.confirm`.                                                                                                                                                         |
| databaseEnabled          | boolean      | Whether the session can interact database storage.                                                                                                                                                                                                       |
| locationContextEnabled   | boolean      | Whether the session can set and query the browser's location context.                                                                                                                                                                                    |
| applicationCacheEnabled  | boolean      | Whether the session can interact with the application cache.                                                                                                                                                                                             |
| browserConnectionEnabled | boolean      | Whether the session can query for the browser's connectivity and disable it if desired.                                                                                                                                                                  |
| cssSelectorsEnabled      | boolean      | Whether the session supports CSS selectors when searching for elements.                                                                                                                                                                                  |
| webStorageEnabled        | boolean      | Whether the session supports interactions with [storage objects](http://www.w3.org/TR/2009/WD-webstorage-20091029/).                                                                                                                                     |
| rotatable                | boolean      | Whether the session can rotate the current page's current layout between portrait and landscape orientations (only applies to mobile platforms).                                                                                                         |
| acceptSslCerts           | boolean      | Whether the session should accept all SSL certs by default.                                                                                                                                                                                              |
| nativeEvents             | boolean      | Whether the session is capable of generating native events when simulating user input.                                                                                                                                                                   |
| proxy                    | proxy object | Details of any proxy to use. If no proxy is specified, whatever the system's current or default state is used. The format is specified under Proxy JSON Object.                                                                                          |
| unexpectedAlertBehaviour | string       | What the browser should do with an unhandled alert before throwing out the UnhandledAlertException. Possible values are "accept", "dismiss" and "ignore"                                                                                                 |
| elementScrollBehavior    | integer      | Allows the user to specify whether elements are scrolled into the viewport for interaction to align with the top (0) or bottom (1) of the viewport. The default value is to align with the top of the viewport. Supported in IE and Firefox (since 2.36) |

### Desired Capabilities

A Capabilities JSON Object sent by the client describing the capabilities a new session created by the server should possess. Any omitted keys implicitly indicate the corresponding capability is irrelevant. More at [DesiredCapabilities](DesiredCapabilities.md).

### Actual Capabilities

A Capabilities JSON Object returned by the server describing what features a session actually supports. Any omitted keys implicitly indicate the corresponding capability is not supported.

### Cookie JSON Object

A JSON object describing a Cookie.

| **Key**  | **Type** | **Description**                                                                                |
| -------- | -------- | ---------------------------------------------------------------------------------------------- |
| name     | string   | The name of the cookie.                                                                        |
| value    | string   | The cookie value.                                                                              |
| path     | string   | (Optional) The cookie path.1                                                                   |
| domain   | string   | (Optional) The domain the cookie is visible to.1                                               |
| secure   | boolean  | (Optional) Whether the cookie is a secure cookie.1                                             |
| httpOnly | boolean  | (Optional) Whether the cookie is an httpOnly cookie.1                                          |
| expiry   | number   | (Optional) When the cookie expires, specified in seconds since midnight, January 1, 1970 UTC.1 |

1 When returning Cookie objects, the server should only omit an optional field if it is incapable of providing the information.

### Log Entry JSON Object

A JSON object describing a log entry.

| **Key**   | **Type** | **Description**                                                                     |
| --------- | -------- | ----------------------------------------------------------------------------------- |
| timestamp | number   | The timestamp of the entry.                                                         |
| level     | string   | The log level of the entry, for example, "INFO" (see [log levels](#Log_Levels.md)). |
| message   | string   | The log message.                                                                    |

### Log Levels

Log levels in order, with finest level on top and coarsest level at the bottom.

| **Level** | **Description**                                                           |
| --------- | ------------------------------------------------------------------------- |
| ALL       | All log messages. Used for fetching of logs and configuration of logging. |
| DEBUG     | Messages for debugging.                                                   |
| INFO      | Messages with user information.                                           |
| WARNING   | Messages corresponding to non-critical problems.                          |
| SEVERE    | Messages corresponding to critical errors.                                |
| OFF       | No log messages. Used for configuration of logging.                       |

### Log Type

The table below lists common log types. Other log types, for instance, for performance logging may also be available.

| **Log Type** | **Description**          |
| ------------ | ------------------------ |
| client       | Logs from the client.    |
| driver       | Logs from the webdriver. |
| browser      | Logs from the browser.   |
| server       | Logs from the server.    |

### Proxy JSON Object

A JSON object describing a Proxy configuration.

| **Key**                                   | **Type** | **Description**                                                                                                                                                                                                                                                                                                                                                |
| ----------------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| proxyType                                 | string   | (Required) The type of proxy being used. Possible values are: **direct** - A direct connection - no proxy in use, **manual** - Manual proxy settings configured, e.g. setting a proxy for HTTP, a proxy for FTP, etc, **pac** - Proxy autoconfiguration from a URL, **autodetect** - Proxy autodetection, probably with WPAD, **system** - Use system settings |
| proxyAutoconfigUrl                        | string   | (Required if proxyType == **pac**, Ignored otherwise) Specifies the URL to be used for proxy autoconfiguration. Expected format example: <http://hostname.com:1234/pacfile>                                                                                                                                                                                    |
| ftpProxy, httpProxy, sslProxy, socksProxy | string   | (Optional, Ignored if proxyType != **manual**) Specifies the proxies to be used for FTP, HTTP, HTTPS and SOCKS requests respectively. Behaviour is undefined if a request is made, where the proxy for the particular protocol is undefined, if proxyType is **manual**. Expected format example: hostname.com:1234                                            |
| socksUsername                             | string   | (Optional, Ignored if proxyType != **manual** and socksProxy is not set) Specifies SOCKS proxy username.                                                                                                                                                                                                                                                       |
| socksPassword                             | string   | (Optional, Ignored if proxyType != **manual** and socksProxy is not set) Specifies SOCKS proxy password.                                                                                                                                                                                                                                                       |
| noProxy                                   | string   | (Optional, Ignored if proxyType != **manual**) Specifies proxy bypass addresses. Format is driver specific.                                                                                                                                                                                                                                                    |

## Messages

### Commands

WebDriver command messages should conform to the [HTTP/1.1 request specification](http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5). Although the server may be extended to respond to other content-types, the wire protocol dictates that all commands accept a content-type of `application/json;charset=UTF-8`. Likewise, the message bodies for POST and PUT request must use an `application/json;charset=UTF-8` content-type.

Each command in the WebDriver service will be mapped to an HTTP method at a specific path. Path segments prefixed with a colon (:) indicate that segment is a variable used to further identify the underlying resource. For example, consider an arbitrary resource mapped as:

```
GET /favorite/color/:name
```

Given this mapping, the server should respond to GET requests sent to “/favorite/color/Jack” and “/favorite/color/Jill”, with the variable `:name` set to “Jack” and “Jill”, respectively.

### Responses

Command responses shall be sent as [HTTP/1.1 response messages](http://www.w3.org/Protocols/rfc2616/rfc2616-sec6.html#sec6). If the remote server must return a 4xx response, the response body shall have a Content-Type of text/plain and the message body shall be a descriptive message of the bad request. For all other cases, if a response includes a message body, it must have a Content-Type of application/json;charset=UTF-8 and will be a JSON object with the following properties:

| **Key**   | **Type** | **Description**                                                                                          |
| --------- | -------- | -------------------------------------------------------------------------------------------------------- |
| sessionId | string   | null                                                                                                     |
| status    | number   | A status code summarizing the result of the command. A non-zero value indicates that the command failed. |
| value     | `*`      | The response JSON value.                                                                                 |

#### Response Status Codes

The wire protocol will inherit its status codes from those used by the InternetExplorerDriver:

| **Code** | **Summary**                  | **Detail**                                                                                                                              |
| -------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------- |
| 0        | `Success`                    | The command executed successfully.                                                                                                      |
| 6        | `NoSuchDriver`               | A session is either terminated or not started                                                                                           |
| 7        | `NoSuchElement`              | An element could not be located on the page using the given search parameters.                                                          |
| 8        | `NoSuchFrame`                | A request to switch to a frame could not be satisfied because the frame could not be found.                                             |
| 9        | `UnknownCommand`             | The requested resource could not be found, or a request was received using an HTTP method that is not supported by the mapped resource. |
| 10       | `StaleElementReference`      | An element command failed because the referenced element is no longer attached to the DOM.                                              |
| 11       | `ElementNotVisible`          | An element command could not be completed because the element is not visible on the page.                                               |
| 12       | `InvalidElementState`        | An element command could not be completed because the element is in an invalid state (e.g. attempting to click a disabled element).     |
| 13       | `UnknownError`               | An unknown server-side error occurred while processing the command.                                                                     |
| 15       | `ElementIsNotSelectable`     | An attempt was made to select an element that cannot be selected.                                                                       |
| 17       | `JavaScriptError`            | An error occurred while executing user supplied JavaScript.                                                                             |
| 19       | `XPathLookupError`           | An error occurred while searching for an element by XPath.                                                                              |
| 21       | `Timeout`                    | An operation did not complete before its timeout expired.                                                                               |
| 23       | `NoSuchWindow`               | A request to switch to a different window could not be satisfied because the window could not be found.                                 |
| 24       | `InvalidCookieDomain`        | An illegal attempt was made to set a cookie under a different domain than the current page.                                             |
| 25       | `UnableToSetCookie`          | A request to set a cookie’s value could not be satisfied.                                                                               |
| 26       | `UnexpectedAlertOpen`        | A modal dialog was open, blocking this operation                                                                                        |
| 27       | `NoAlertOpenError`           | An attempt was made to operate on a modal dialog when one was not open.                                                                 |
| 28       | `ScriptTimeout`              | A script did not complete before its timeout expired.                                                                                   |
| 29       | `InvalidElementCoordinates`  | The coordinates provided to an interactions operation are invalid.                                                                      |
| 30       | `IMENotAvailable`            | IME was not available.                                                                                                                  |
| 31       | `IMEEngineActivationFailed`  | An IME engine could not be started.                                                                                                     |
| 32       | `InvalidSelector`            | Argument was an invalid selector (e.g. XPath/CSS).                                                                                      |
| 33       | `SessionNotCreatedException` | A new session could not be created.                                                                                                     |
| 34       | `MoveTargetOutOfBounds`      | Target provided for a move action is out of bounds.                                                                                     |

| Key        | Type   | Description                                                                                                                                                                                                        |
| ---------- | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| message    | string | A descriptive message for the command failure.                                                                                                                                                                     |
| screen     | string | (Optional) If included, a screenshot of the current page as a base64 encoded string.                                                                                                                               |
| class      | string | (Optional) If included, specifies the fully qualified class name for the exception that was thrown when the command failed.                                                                                        |
| stackTrace | array  | (Optional) If included, specifies an array of JSON objects describing the stack trace for the exception that was thrown when the command failed. The zeroeth element of the array represents the top of the stack. |

Each JSON object in the stackTrace array must contain the following properties:

| **Key**    | **Type** | **Description**                                                                                                                                                                                                                      |
| ---------- | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| fileName   | string   | The name of the source file containing the line represented by this frame.                                                                                                                                                           |
| className  | string   | The fully qualified class name for the class active in this frame. If the class name cannot be determined, or is not applicable for the language the server is implemented in, then this property should be set to the empty string. |
| methodName | string   | The name of the method active in this frame, or the empty string if unknown/not applicable.                                                                                                                                          |
| lineNumber | number   | The line number in the original source file for the frame, or 0 if unknown.                                                                                                                                                          |

## Resource Mapping

Resources in the WebDriver REST service are mapped to individual URL patterns. Each resource may respond to one or more HTTP request methods. If a resource responds to a GET request, then it should also respond to HEAD requests. All resources should respond to OPTIONS requests with an `Allow` header field, whose value is a list of all methods that resource responds to.

If a resource is mapped to a URL containing a variable path segment name, that path segment should be used to further route the request. Variable path segments are indicated in the resource mapping by a colon-prefix. For example, consider the following:

```
/favorite/color/:person
```

| **HTTP Method** | **Path**                                                                                                                                  | **Summary**                                                                                                                                                           |
| --------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| GET             | [/status](/documentation/legacy/json_wire_protocol/#status)                                                                               | Query the server’s current status.                                                                                                                                    |
| POST            | [/session](/documentation/legacy/json_wire_protocol/#session)                                                                             | Create a new session.                                                                                                                                                 |
| GET             | [/sessions](/documentation/legacy/json_wire_protocol/#sessions)                                                                           | Returns a list of the currently active sessions.                                                                                                                      |
| GET             | [/session/:sessionId](/documentation/legacy/json_wire_protocol/#sessionsessionid)                                                         | Retrieve the capabilities of the specified session.                                                                                                                   |
| DELETE          | [/session/:sessionId](/documentation/legacy/json_wire_protocol/#sessionsessionid)                                                         | Delete the session.                                                                                                                                                   |
| POST            | [/session/:sessionId/timeouts](/documentation/legacy/json_wire_protocol/#sessionsessionidtimeouts)                                        | Configure the amount of time that a particular type of operation can execute for before they are aborted and a                                                        |
| POST            | [/session/:sessionId/timeouts/async\_script](/documentation/legacy/json_wire_protocol/#sessionsessionidtimeoutsasync_script)              | Set the amount of time, in milliseconds, that asynchronous scripts executed by `/session/:sessionId/execute_async` are permitted to run before they are aborted and a |
| POST            | [/session/:sessionId/timeouts/implicit\_wait](/documentation/legacy/json_wire_protocol/#sessionsessionidtimeoutsimplicit_wait)            | Set the amount of time the driver should wait when searching for elements.                                                                                            |
| GET             | [/session/:sessionId/window\_handle](/documentation/legacy/json_wire_protocol/#sessionsessionidwindow_handle)                             | Retrieve the current window handle.                                                                                                                                   |
| GET             | [/session/:sessionId/window\_handles](/documentation/legacy/json_wire_protocol/#sessionsessionidwindow_handles)                           | Retrieve the list of all window handles available to the session.                                                                                                     |
| GET             | [/session/:sessionId/url](/documentation/legacy/json_wire_protocol/#sessionsessionidurl)                                                  | Retrieve the URL of the current page.                                                                                                                                 |
| POST            | [/session/:sessionId/url](/documentation/legacy/json_wire_protocol/#sessionsessionidurl)                                                  | Navigate to a new URL.                                                                                                                                                |
| POST            | [/session/:sessionId/forward](/documentation/legacy/json_wire_protocol/#sessionsessionidforward)                                          | Navigate forwards in the browser history, if possible.                                                                                                                |
| POST            | [/session/:sessionId/back](/documentation/legacy/json_wire_protocol/#sessionsessionidback)                                                | Navigate backwards in the browser history, if possible.                                                                                                               |
| POST            | [/session/:sessionId/refresh](/documentation/legacy/json_wire_protocol/#sessionsessionidrefresh)                                          | Refresh the current page.                                                                                                                                             |
| POST            | [/session/:sessionId/execute](/documentation/legacy/json_wire_protocol/#sessionsessionidexecute)                                          | Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame.                                                            |
| POST            | [/session/:sessionId/execute\_async](/documentation/legacy/json_wire_protocol/#sessionsessionidexecute_async)                             | Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame.                                                            |
| GET             | [/session/:sessionId/screenshot](/documentation/legacy/json_wire_protocol/#sessionsessionidscreenshot)                                    | Take a screenshot of the current page.                                                                                                                                |
| GET             | [/session/:sessionId/ime/available\_engines](/documentation/legacy/json_wire_protocol/#sessionsessionidimeavailable_engines)              | List all available engines on the machine.                                                                                                                            |
| GET             | [/session/:sessionId/ime/active\_engine](/documentation/legacy/json_wire_protocol/#sessionsessionidimeactive_engine)                      | Get the name of the active IME engine.                                                                                                                                |
| GET             | [/session/:sessionId/ime/activated](/documentation/legacy/json_wire_protocol/#sessionsessionidimeactivated)                               | Indicates whether IME input is active at the moment (not if it’s available.                                                                                           |
| POST            | [/session/:sessionId/ime/deactivate](/documentation/legacy/json_wire_protocol/#sessionsessionidimedeactivate)                             | De-activates the currently-active IME engine.                                                                                                                         |
| POST            | [/session/:sessionId/ime/activate](/documentation/legacy/json_wire_protocol/#sessionsessionidimeactivate)                                 | Make an engines that is available (appears on the listreturned by getAvailableEngines) active.                                                                        |
| POST            | [/session/:sessionId/frame](/documentation/legacy/json_wire_protocol/#sessionsessionidframe)                                              | Change focus to another frame on the page.                                                                                                                            |
| POST            | [/session/:sessionId/frame/parent](/documentation/legacy/json_wire_protocol/#sessionsessionidframeparent)                                 | Change focus to the parent context.                                                                                                                                   |
| POST            | [/session/:sessionId/window](/documentation/legacy/json_wire_protocol/#sessionsessionidwindow)                                            | Change focus to another window.                                                                                                                                       |
| DELETE          | [/session/:sessionId/window](/documentation/legacy/json_wire_protocol/#sessionsessionidwindow)                                            | Close the current window.                                                                                                                                             |
| POST            | [/session/:sessionId/window/:windowHandle/size](/documentation/legacy/json_wire_protocol/#sessionsessionidwindowwindowhandlesize)         | Change the size of the specified window.                                                                                                                              |
| GET             | [/session/:sessionId/window/:windowHandle/size](/documentation/legacy/json_wire_protocol/#sessionsessionidwindowwindowhandlesize)         | Get the size of the specified window.                                                                                                                                 |
| POST            | [/session/:sessionId/window/:windowHandle/position](/documentation/legacy/json_wire_protocol/#sessionsessionidwindowwindowhandleposition) | Change the position of the specified window.                                                                                                                          |
| GET             | [/session/:sessionId/window/:windowHandle/position](/documentation/legacy/json_wire_protocol/#sessionsessionidwindowwindowhandleposition) | Get the position of the specified window.                                                                                                                             |
| POST            | [/session/:sessionId/window/:windowHandle/maximize](/documentation/legacy/json_wire_protocol/#sessionsessionidwindowwindowhandlemaximize) | Maximize the specified window if not already maximized.                                                                                                               |
| GET             | [/session/:sessionId/cookie](/documentation/legacy/json_wire_protocol/#sessionsessionidcookie)                                            | Retrieve all cookies visible to the current page.                                                                                                                     |
| POST            | [/session/:sessionId/cookie](/documentation/legacy/json_wire_protocol/#sessionsessionidcookie)                                            | Set a cookie.                                                                                                                                                         |
| DELETE          | [/session/:sessionId/cookie](/documentation/legacy/json_wire_protocol/#sessionsessionidcookie)                                            | Delete all cookies visible to the current page.                                                                                                                       |
| DELETE          | [/session/:sessionId/cookie/:name](/documentation/legacy/json_wire_protocol/#sessionsessionidcookiename)                                  | Delete the cookie with the given name.                                                                                                                                |
| GET             | [/session/:sessionId/source](/documentation/legacy/json_wire_protocol/#sessionsessionidsource)                                            | Get the current page source.                                                                                                                                          |
| GET             | [/session/:sessionId/title](/documentation/legacy/json_wire_protocol/#sessionsessionidtitle)                                              | Get the current page title.                                                                                                                                           |
| POST            | [/session/:sessionId/element](/documentation/legacy/json_wire_protocol/#sessionsessionidelement)                                          | Search for an element on the page, starting from the document root.                                                                                                   |
| POST            | [/session/:sessionId/elements](/documentation/legacy/json_wire_protocol/#sessionsessionidelements)                                        | Search for multiple elements on the page, starting from the document root.                                                                                            |
| POST            | [/session/:sessionId/element/active](/documentation/legacy/json_wire_protocol/#sessionsessionidelementactive)                             | Get the element on the page that currently has focus.                                                                                                                 |
| GET             | [/session/:sessionId/element/:id](/documentation/legacy/json_wire_protocol/#sessionsessionidelementid)                                    | Describe the identified element.                                                                                                                                      |
| POST            | [/session/:sessionId/element/:id/element](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidelement)                     | Search for an element on the page, starting from the identified element.                                                                                              |
| POST            | [/session/:sessionId/element/:id/elements](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidelements)                   | Search for multiple elements on the page, starting from the identified element.                                                                                       |
| POST            | [/session/:sessionId/element/:id/click](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidclick)                         | Click on an element.                                                                                                                                                  |
| POST            | [/session/:sessionId/element/:id/submit](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidsubmit)                       | Submit a `FORM` element.                                                                                                                                              |
| GET             | [/session/:sessionId/element/:id/text](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidtext)                           | Returns the visible text for the element.                                                                                                                             |
| POST            | [/session/:sessionId/element/:id/value](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidvalue)                         | Send a sequence of key strokes to an element.                                                                                                                         |
| POST            | [/session/:sessionId/keys](/documentation/legacy/json_wire_protocol/#sessionsessionidkeys)                                                | Send a sequence of key strokes to the active element.                                                                                                                 |
| GET             | [/session/:sessionId/element/:id/name](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidname)                           | Query for an element’s tag name.                                                                                                                                      |
| POST            | [/session/:sessionId/element/:id/clear](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidclear)                         | Clear a `TEXTAREA` or `text INPUT` element’s value.                                                                                                                   |
| GET             | [/session/:sessionId/element/:id/selected](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidselected)                   | Determine if an `OPTION` element, or an `INPUT` element of type `checkbox` or `radiobutton` is currently selected.                                                    |
| GET             | [/session/:sessionId/element/:id/enabled](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidenabled)                     | Determine if an element is currently enabled.                                                                                                                         |
| GET             | [/session/:sessionId/element/:id/attribute/:name](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidattribute/:name)     | Get the value of an element’s attribute.                                                                                                                              |
| GET             | [/session/:sessionId/element/:id/equals/:other](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidequals/:other)         | Test if two element IDs refer to the same DOM element.                                                                                                                |
| GET             | [/session/:sessionId/element/:id/displayed](/documentation/legacy/json_wire_protocol/#sessionsessionidelementiddisplayed)                 | Determine if an element is currently displayed.                                                                                                                       |
| GET             | [/session/:sessionId/element/:id/location](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidlocation)                   | Determine an element’s location on the page.                                                                                                                          |
| GET             | [/session/:sessionId/element/:id/location\_in\_view](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidlocation_in_view) | Determine an element’s location on the screen once it has been scrolled into view.                                                                                    |
| GET             | [/session/:sessionId/element/:id/size](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidsize)                           | Determine an element’s size in pixels.                                                                                                                                |
| GET             | [/session/:sessionId/element/:id/css/:propertyName](/documentation/legacy/json_wire_protocol/#sessionsessionidelementidcss/:propertyName) | Query the value of an element’s computed CSS property.                                                                                                                |
| GET             | [/session/:sessionId/orientation](/documentation/legacy/json_wire_protocol/#sessionsessionidorientation)                                  | Get the current browser orientation.                                                                                                                                  |
| POST            | [/session/:sessionId/orientation](/documentation/legacy/json_wire_protocol/#sessionsessionidorientation)                                  | Set the browser orientation.                                                                                                                                          |
| GET             | [/session/:sessionId/alert\_text](/documentation/legacy/json_wire_protocol/#sessionsessionidalert_text)                                   | Gets the text of the currently displayed JavaScript `alert()`, `confirm()`, or `prompt()` dialog.                                                                     |
| POST            | [/session/:sessionId/alert\_text](/documentation/legacy/json_wire_protocol/#sessionsessionidalert_text)                                   | Sends keystrokes to a JavaScript `prompt()` dialog.                                                                                                                   |
| POST            | [/session/:sessionId/accept\_alert](/documentation/legacy/json_wire_protocol/#sessionsessionidaccept_alert)                               | Accepts the currently displayed alert dialog.                                                                                                                         |
| POST            | [/session/:sessionId/dismiss\_alert](/documentation/legacy/json_wire_protocol/#sessionsessioniddismiss_alert)                             | Dismisses the currently displayed alert dialog.                                                                                                                       |
| POST            | [/session/:sessionId/moveto](/documentation/legacy/json_wire_protocol/#sessionsessionidmoveto)                                            | Move the mouse by an offset of the specificed element.                                                                                                                |
| POST            | [/session/:sessionId/click](/documentation/legacy/json_wire_protocol/#sessionsessionidclick)                                              | Click any mouse button (at the coordinates set by the last moveto command).                                                                                           |
| POST            | [/session/:sessionId/buttondown](/documentation/legacy/json_wire_protocol/#sessionsessionidbuttondown)                                    | Click and hold the left mouse button (at the coordinates set by the last moveto command).                                                                             |
| POST            | [/session/:sessionId/buttonup](/documentation/legacy/json_wire_protocol/#sessionsessionidbuttonup)                                        | Releases the mouse button previously held (where the mouse is currently at).                                                                                          |
| POST            | [/session/:sessionId/doubleclick](/documentation/legacy/json_wire_protocol/#sessionsessioniddoubleclick)                                  | Double-clicks at the current mouse coordinates (set by moveto).                                                                                                       |
| POST            | [/session/:sessionId/touch/click](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchclick)                                   | Single tap on the touch enabled device.                                                                                                                               |
| POST            | [/session/:sessionId/touch/down](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchdown)                                     | Finger down on the screen.                                                                                                                                            |
| POST            | [/session/:sessionId/touch/up](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchup)                                         | Finger up on the screen.                                                                                                                                              |
| POST            | [session/:sessionId/touch/move](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchmove)                                      | Finger move on the screen.                                                                                                                                            |
| POST            | [session/:sessionId/touch/scroll](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchscroll)                                  | Scroll on the touch screen using finger based motion events.                                                                                                          |
| POST            | [session/:sessionId/touch/scroll](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchscroll)                                  | Scroll on the touch screen using finger based motion events.                                                                                                          |
| POST            | [session/:sessionId/touch/doubleclick](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchdoubleclick)                        | Double tap on the touch screen using finger motion events.                                                                                                            |
| POST            | [session/:sessionId/touch/longclick](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchlongclick)                            | Long press on the touch screen using finger motion events.                                                                                                            |
| POST            | [session/:sessionId/touch/flick](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchflick)                                    | Flick on the touch screen using finger motion events.                                                                                                                 |
| POST            | [session/:sessionId/touch/flick](/documentation/legacy/json_wire_protocol/#sessionsessionidtouchflick)                                    | Flick on the touch screen using finger motion events.                                                                                                                 |
| GET             | [/session/:sessionId/location](/documentation/legacy/json_wire_protocol/#sessionsessionidlocation)                                        | Get the current geo location.                                                                                                                                         |
| POST            | [/session/:sessionId/location](/documentation/legacy/json_wire_protocol/#sessionsessionidlocation)                                        | Set the current geo location.                                                                                                                                         |
| GET             | [/session/:sessionId/local\_storage](/documentation/legacy/json_wire_protocol/#sessionsessionidlocal_storage)                             | Get all keys of the storage.                                                                                                                                          |
| POST            | [/session/:sessionId/local\_storage](/documentation/legacy/json_wire_protocol/#sessionsessionidlocal_storage)                             | Set the storage item for the given key.                                                                                                                               |
| DELETE          | [/session/:sessionId/local\_storage](/documentation/legacy/json_wire_protocol/#sessionsessionidlocal_storage)                             | Clear the storage.                                                                                                                                                    |
| GET             | [/session/:sessionId/local\_storage/key/:key](/documentation/legacy/json_wire_protocol/#sessionsessionidlocal_storagekeykey)              | Get the storage item for the given key.                                                                                                                               |
| DELETE          | [/session/:sessionId/local\_storage/key/:key](/documentation/legacy/json_wire_protocol/#sessionsessionidlocal_storagekeykey)              | Remove the storage item for the given key.                                                                                                                            |
| GET             | [/session/:sessionId/local\_storage/size](/documentation/legacy/json_wire_protocol/#sessionsessionidlocal_storagesize)                    | Get the number of items in the storage.                                                                                                                               |
| GET             | [/session/:sessionId/session\_storage](/documentation/legacy/json_wire_protocol/#sessionsessionidsession_storage)                         | Get all keys of the storage.                                                                                                                                          |
| POST            | [/session/:sessionId/session\_storage](/documentation/legacy/json_wire_protocol/#sessionsessionidsession_storage)                         | Set the storage item for the given key.                                                                                                                               |
| DELETE          | [/session/:sessionId/session\_storage](/documentation/legacy/json_wire_protocol/#sessionsessionidsession_storage)                         | Clear the storage.                                                                                                                                                    |
| GET             | [/session/:sessionId/session\_storage/key/:key](/documentation/legacy/json_wire_protocol/#sessionsessionidsession_storagekeykey)          | Get the storage item for the given key.                                                                                                                               |
| DELETE          | [/session/:sessionId/session\_storage/key/:key](/documentation/legacy/json_wire_protocol/#sessionsessionidsession_storagekeykey)          | Remove the storage item for the given key.                                                                                                                            |
| GET             | [/session/:sessionId/session\_storage/size](/documentation/legacy/json_wire_protocol/#sessionsessionidsession_storagesize)                | Get the number of items in the storage.                                                                                                                               |
| POST            | [/session/:sessionId/log](/documentation/legacy/json_wire_protocol/#sessionsessionidlog)                                                  | Get the log for a given log type.                                                                                                                                     |
| GET             | [/session/:sessionId/log/types](/documentation/legacy/json_wire_protocol/#sessionsessionidlogtypes)                                       | Get available log types.                                                                                                                                              |
| GET             | [/session/:sessionId/application\_cache/status](/documentation/legacy/json_wire_protocol/#sessionsessionidapplication_cachestatus)        | Get the status of the html5 application cache.                                                                                                                        |

### Command Detail

#### /status

* * #### GET /status

  * * * Query the server's current status. The server should respond with a general "HTTP 200 OK" response if it is alive and accepting commands. The response body should be a JSON object describing the state of the server. All server implementations should return two basic objects describing the server's current platform and when the server was built. All fields are optional; if omitted, the client should assume the value is uknown. Furthermore, server implementations may include additional fields not listed here.

        | **Key**        | **Type** | **Description**                                                                               |
        | -------------- | -------- | --------------------------------------------------------------------------------------------- |
        | build          | object   |                                                                                               |
        | build.version  | string   | A generic release label (i.e. "2.0rc3")                                                       |
        | build.revision | string   | The revision of the local source control client from which the server was built               |
        | build.time     | string   | A timestamp from when the server was built.                                                   |
        | os             | object   |                                                                                               |
        | os.arch        | string   | The current system architecture.                                                              |
        | os.name        | string   | The name of the operating system the server is currently running on: "windows", "linux", etc. |
        | os.version     | string   | The operating system version.                                                                 |

      * * **Returns:**

          `{object}` An object describing the general status of the server.

***

#### /session

* * #### POST /session

  * * * Create a new session. The server should attempt to create a session that most closely matches the desired and required capabilities. Required capabilities have higher priority than desired capabilities and must be set for the session to be created.

      * * **JSON Parameters:**

          * `desiredCapabilities` - `{object}` An object describing the session's [desired capabilities](#Desired_Capabilities.md).
          * `requiredCapabilities` - `{object}` An object describing the session's [required capabilities](#Desired_Capabilities.md) (Optional).

      * * **Returns:**

          `{object}` An object describing the session's [capabilities](#Actual_Capabilities.md).

      * * **Potential Errors:**

          `SessionNotCreatedException` - If a required capability could not be set.

***

#### /sessions

* * #### GET /sessions

  * * * Returns a list of the currently active sessions. Each session will be returned as a list of JSON objects with the following keys:

        | **Key**      | **Type** | **Description**                                                             |
        | ------------ | -------- | --------------------------------------------------------------------------- |
        | id           | string   | The session ID.                                                             |
        | capabilities | object   | An object describing the session's [capabilities](#Actual_Capabilities.md). |

      * * **Returns:**

          `{Array.<Object>}` A list of the currently active sessions.

***

#### /session/:sessionId

* * #### GET /session/:sessionId

  * * * Retrieve the capabilities of the specified session.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{object}` An object describing the session's [capabilities](#Actual_Capabilities.md).

- - #### DELETE /session/:sessionId

  - * * Delete the session.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

***

#### /session/:sessionId/timeouts

* * #### POST /session/:sessionId/timeouts

  * * * Configure the amount of time that a particular type of operation can execute for before they are aborted and a |Timeout| error is returned to the client.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `type` - `{string}` The type of operation to set the timeout for. Valid values are: "script" for script timeouts, "implicit" for modifying the implicit wait timeout and "page load" for setting a page load timeout.
          * `ms` - `{number}` The amount of time, in milliseconds, that time-limited commands are permitted to run.

***

#### /session/:sessionId/timeouts/async\_script

* * #### POST /session/:sessionId/timeouts/async\_script

  * * * Set the amount of time, in milliseconds, that asynchronous scripts executed by `/session/:sessionId/execute_async` are permitted to run before they are aborted and a |Timeout| error is returned to the client.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `ms` - `{number}` The amount of time, in milliseconds, that time-limited commands are permitted to run.

***

#### /session/:sessionId/timeouts/implicit\_wait

* * #### POST /session/:sessionId/timeouts/implicit\_wait

  * * * Set the amount of time the driver should wait when searching for elements. When\
        searching for a single element, the driver should poll the page until an element is found or\
        the timeout expires, whichever occurs first. When searching for multiple elements, the driver\
        should poll the page until at least one element is found or the timeout expires, at which point\
        it should return an empty list.\
        \
        If this command is never sent, the driver should default to an implicit wait of 0ms.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `ms` - `{number}` The amount of time to wait, in milliseconds. This value has a lower bound of 0.

***

#### /session/:sessionId/window\_handle

* * #### GET /session/:sessionId/window\_handle

  * * * Retrieve the current window handle.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{string}` The current window handle.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/window\_handles

* * #### GET /session/:sessionId/window\_handles

  * * * Retrieve the list of all window handles available to the session.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{Array.<string>}` A list of window handles.

***

#### /session/:sessionId/url

* * #### GET /session/:sessionId/url

  * * * Retrieve the URL of the current page.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{string}` The current URL.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

- - #### POST /session/:sessionId/url

  - * * Navigate to a new URL.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `url` - `{string}` The URL to navigate to.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/forward

* * #### POST /session/:sessionId/forward

  * * * Navigate forwards in the browser history, if possible.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/back

* * #### POST /session/:sessionId/back

  * * * Navigate backwards in the browser history, if possible.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/refresh

* * #### POST /session/:sessionId/refresh

  * * * Refresh the current page.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/execute

* * #### POST /session/:sessionId/execute

  * * * Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. The executed script is assumed to be synchronous and the result of evaluating the script is returned to the client.\
        \
        The `script` argument defines the script to execute in the form of a function body. The value returned by that function will be returned to the client. The function will be invoked with the provided `args` array and the values may be accessed via the `arguments` object in the order specified.\
        \
        Arguments may be any JSON-primitive, array, or JSON object. JSON objects that define a [WebElement reference](#WebElement_JSON_Object.md) will be converted to the corresponding DOM element. Likewise, any WebElements in the script result will be returned to the client as [WebElement JSON objects](#WebElement_JSON_Object.md).

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `script` - `{string}` The script to execute.
          * `args` - `{Array.<*>}` The script arguments.

      * * **Returns:**

          `{*}` The script result.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If one of the script arguments is a WebElement that is not attached to the page's DOM.
          * `JavaScriptError` - If the script throws an Error.

***

#### /session/:sessionId/execute\_async

* * #### POST /session/:sessionId/execute\_async

  * * * Inject a snippet of JavaScript into the page for execution in the context of the currently selected frame. The executed script is assumed to be asynchronous and must signal that is done by invoking the provided callback, which is always provided as the final argument to the function. The value to this callback will be returned to the client.\
        \
        Asynchronous script commands may not span page loads. If an `unload` event is fired while waiting for a script result, an error should be returned to the client.\
        \
        The `script` argument defines the script to execute in teh form of a function body. The function will be invoked with the provided `args` array and the values may be accessed via the `arguments` object in the order specified. The final argument will always be a callback function that must be invoked to signal that the script has finished.\
        \
        Arguments may be any JSON-primitive, array, or JSON object. JSON objects that define a [WebElement reference](#WebElement_JSON_Object.md) will be converted to the corresponding DOM element. Likewise, any WebElements in the script result will be returned to the client as [WebElement JSON objects](#WebElement_JSON_Object.md).

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `script` - `{string}` The script to execute.
          * `args` - `{Array.<*>}` The script arguments.

      * * **Returns:**

          `{*}` The script result.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If one of the script arguments is a WebElement that is not attached to the page's DOM.
          * `Timeout` - If the script callback is not invoked before the timeout expires. Timeouts are controlled by the `/session/:sessionId/timeout/async_script` command.
          * `JavaScriptError` - If the script throws an Error or if an `unload` event is fired while waiting for the script to finish.

***

#### /session/:sessionId/screenshot

* * #### GET /session/:sessionId/screenshot

  * * * Take a screenshot of the current page.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{string}` The screenshot as a base64 encoded PNG.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/ime/available\_engines

* * #### GET /session/:sessionId/ime/available\_engines

  * * * List all available engines on the machine. To use an engine, it has to be present in this list.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{Array.<string>}` A list of available engines

      * * **Potential Errors:**

          `ImeNotAvailableException` - If the host does not support IME

***

#### /session/:sessionId/ime/active\_engine

* * #### GET /session/:sessionId/ime/active\_engine

  * * * Get the name of the active IME engine. The name string is platform specific.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{string}` The name of the active IME engine.

      * * **Potential Errors:**

          `ImeNotAvailableException` - If the host does not support IME

***

#### /session/:sessionId/ime/activated

* * #### GET /session/:sessionId/ime/activated

  * * * Indicates whether IME input is active at the moment (not if it's available.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{boolean}` true if IME input is available and currently active, false otherwise

      * * **Potential Errors:**

          `ImeNotAvailableException` - If the host does not support IME

***

#### /session/:sessionId/ime/deactivate

* * #### POST /session/:sessionId/ime/deactivate

  * * * De-activates the currently-active IME engine.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `ImeNotAvailableException` - If the host does not support IME

***

#### /session/:sessionId/ime/activate

* * #### POST /session/:sessionId/ime/activate

  * * * Make an engines that is available (appears on the list\
        returned by getAvailableEngines) active. After this call, the engine will\
        be added to the list of engines loaded in the IME daemon and the input sent\
        using sendKeys will be converted by the active engine.\
        Note that this is a platform-independent method of activating IME\
        (the platform-specific way being using keyboard shortcuts

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `engine` - `{string}` Name of the engine to activate.

      * * **Potential Errors:**

          * `ImeActivationFailedException` - If the engine is not available or if the activation fails for other reasons.
          * `ImeNotAvailableException` - If the host does not support IME

***

#### /session/:sessionId/frame

* * #### POST /session/:sessionId/frame

  * * * Change focus to another frame on the page. If the frame `id` is `null`, the server\
        should switch to the page's default content.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `id` - `{string|number|null|WebElement JSON Object}` Identifier for the frame to change focus to.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `NoSuchFrame` - If the frame specified by `id` cannot be found.

***

#### /session/:sessionId/frame/parent

* * #### POST /session/:sessionId/frame/parent

  * * * Change focus to the parent context. If the current context is the top level browsing context, the context remains unchanged.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

***

#### /session/:sessionId/window

* * #### POST /session/:sessionId/window

  * * * Change focus to another window. The window to change focus to may be specified by its\
        server assigned window handle, or by the value of its `name` attribute.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `name` - `{string}` The window to change focus to.

      * * **Potential Errors:**

          `NoSuchWindow` - If the window specified by `name` cannot be found.

- - #### DELETE /session/:sessionId/window

  - * * Close the current window.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window is already closed

***

#### /session/:sessionId/window/:windowHandle/size

* * #### POST /session/:sessionId/window/:windowHandle/size

  * * * Change the size of the specified window. If the :windowHandle URL parameter is "current", the currently active window will be resized.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `width` - `{number}` The new window width.
          * `height` - `{number}` The new window height.

- - #### GET /session/:sessionId/window/:windowHandle/size

  - * * Get the size of the specified window. If the :windowHandle URL parameter is "current", the size of the currently active window will be returned.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{width: number, height: number}` The size of the window.

      * * **Potential Errors:**

          `NoSuchWindow` - If the specified window cannot be found.

***

#### /session/:sessionId/window/:windowHandle/position

* * #### POST /session/:sessionId/window/:windowHandle/position

  * * * Change the position of the specified window. If the :windowHandle URL parameter is "current", the currently active window will be moved.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `x` - `{number}` The X coordinate to position the window at, relative to the upper left corner of the screen.
          * `y` - `{number}` The Y coordinate to position the window at, relative to the upper left corner of the screen.

      * * **Potential Errors:**

          `NoSuchWindow` - If the specified window cannot be found.

- - #### GET /session/:sessionId/window/:windowHandle/position

  - * * Get the position of the specified window. If the :windowHandle URL parameter is "current", the position of the currently active window will be returned.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{x: number, y: number}` The X and Y coordinates for the window, relative to the upper left corner of the screen.

      * * **Potential Errors:**

          `NoSuchWindow` - If the specified window cannot be found.

***

#### /session/:sessionId/window/:windowHandle/maximize

* * #### POST /session/:sessionId/window/:windowHandle/maximize

  * * * Maximize the specified window if not already maximized. If the :windowHandle URL parameter is "current", the currently active window will be maximized.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `NoSuchWindow` - If the specified window cannot be found.

***

#### /session/:sessionId/cookie

* * #### GET /session/:sessionId/cookie

  * * * Retrieve all cookies visible to the current page.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{Array.<object>}` A list of [cookies](#Cookie_JSON_Object.md).

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

- - #### POST /session/:sessionId/cookie

  - * * Set a cookie. If the [cookie](#Cookie_JSON_Object.md) path is not specified, it should be set to `"/"`. Likewise, if the domain is omitted, it should default to the current page's domain.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `cookie` - `{object}` A [JSON object](#Cookie_JSON_Object.md) defining the cookie to add.

* * #### DELETE /session/:sessionId/cookie

  * * * Delete all cookies visible to the current page.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          * `InvalidCookieDomain` - If the cookie's `domain` is not visible from the current page.
          * `NoSuchWindow` - If the currently selected window has been closed.
          * `UnableToSetCookie` - If attempting to set a cookie on a page that does not support cookies (e.g. pages with mime-type `text/plain`).

***

#### /session/:sessionId/cookie/:name

* * #### DELETE /session/:sessionId/cookie/:name

  * * * Delete the cookie with the given name. This command should be a no-op if there is no\
        such cookie visible to the current page.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:name` - The name of the cookie to delete.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/source

* * #### GET /session/:sessionId/source

  * * * Get the current page source.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{string}` The current page source.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/title

* * #### GET /session/:sessionId/title

  * * * Get the current page title.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{string}` The current page title.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/element

* * #### POST /session/:sessionId/element

  * * * Search for an element on the page, starting from the document root. The located element will be returned as a WebElement JSON object. The table below lists the locator strategies that each server should support. Each locator must return the first matching element located in the DOM.

        | **Strategy**      | **Description**                                                                                        |
        | ----------------- | ------------------------------------------------------------------------------------------------------ |
        | class name        | Returns an element whose class name contains the search value; compound class names are not permitted. |
        | css selector      | Returns an element matching a CSS selector.                                                            |
        | id                | Returns an element whose ID attribute matches the search value.                                        |
        | name              | Returns an element whose NAME attribute matches the search value.                                      |
        | link text         | Returns an anchor element whose visible text matches the search value.                                 |
        | partial link text | Returns an anchor element whose visible text partially matches the search value.                       |
        | tag name          | Returns an element whose tag name matches the search value.                                            |
        | xpath             | Returns an element matching an XPath expression.                                                       |

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `using` - `{string}` The locator strategy to use.
          * `value` - `{string}` The The search target.

      * * **Returns:**

          `{ELEMENT:string}` A WebElement JSON object for the located element.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `NoSuchElement` - If the element cannot be found.
          * `XPathLookupError` - If using XPath and the input expression is invalid.

***

#### /session/:sessionId/elements

* * #### POST /session/:sessionId/elements

  * * * Search for multiple elements on the page, starting from the document root. The located elements will be returned as a WebElement JSON objects. The table below lists the locator strategies that each server should support. Elements should be returned in the order located in the DOM.

        | **Strategy**      | **Description**                                                                                          |
        | ----------------- | -------------------------------------------------------------------------------------------------------- |
        | class name        | Returns all elements whose class name contains the search value; compound class names are not permitted. |
        | css selector      | Returns all elements matching a CSS selector.                                                            |
        | id                | Returns all elements whose ID attribute matches the search value.                                        |
        | name              | Returns all elements whose NAME attribute matches the search value.                                      |
        | link text         | Returns all anchor elements whose visible text matches the search value.                                 |
        | partial link text | Returns all anchor elements whose visible text partially matches the search value.                       |
        | tag name          | Returns all elements whose tag name matches the search value.                                            |
        | xpath             | Returns all elements matching an XPath expression.                                                       |

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `using` - `{string}` The locator strategy to use.
          * `value` - `{string}` The The search target.

      * * **Returns:**

          `{Array.<{ELEMENT:string}>}` A list of WebElement JSON objects for the located elements.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `XPathLookupError` - If using XPath and the input expression is invalid.

***

#### /session/:sessionId/element/active

* * #### POST /session/:sessionId/element/active

  * * * Get the element on the page that currently has focus. The element will be returned as a WebElement JSON object.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{ELEMENT:string}` A WebElement JSON object for the active element.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/element/:id

* * #### GET /session/:sessionId/element/:id

  * * * Describe the identified element.\
        \
        **Note:** This command is reserved for future use; its return type is currently undefined.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/element

* * #### POST /session/:sessionId/element/:id/element

  * * * Search for an element on the page, starting from the identified element. The located element will be returned as a WebElement JSON object. The table below lists the locator strategies that each server should support. Each locator must return the first matching element located in the DOM.

        | **Strategy**      | **Description**                                                                                                                                                                                                                                                                                             |
        | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
        | class name        | Returns an element whose class name contains the search value; compound class names are not permitted.                                                                                                                                                                                                      |
        | css selector      | Returns an element matching a CSS selector.                                                                                                                                                                                                                                                                 |
        | id                | Returns an element whose ID attribute matches the search value.                                                                                                                                                                                                                                             |
        | name              | Returns an element whose NAME attribute matches the search value.                                                                                                                                                                                                                                           |
        | link text         | Returns an anchor element whose visible text matches the search value.                                                                                                                                                                                                                                      |
        | partial link text | Returns an anchor element whose visible text partially matches the search value.                                                                                                                                                                                                                            |
        | tag name          | Returns an element whose tag name matches the search value.                                                                                                                                                                                                                                                 |
        | xpath             | Returns an element matching an XPath expression. The provided XPath expression must be applied to the server "as is"; if the expression is not relative to the element root, the server should not modify it. Consequently, an XPath query may return elements not contained in the root element's subtree. |

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **JSON Parameters:**

          * `using` - `{string}` The locator strategy to use.
          * `value` - `{string}` The The search target.

      * * **Returns:**

          `{ELEMENT:string}` A WebElement JSON object for the located element.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.
          * `NoSuchElement` - If the element cannot be found.
          * `XPathLookupError` - If using XPath and the input expression is invalid.

***

#### /session/:sessionId/element/:id/elements

* * #### POST /session/:sessionId/element/:id/elements

  * * * Search for multiple elements on the page, starting from the identified element. The located elements will be returned as a WebElement JSON objects. The table below lists the locator strategies that each server should support. Elements should be returned in the order located in the DOM.

        | **Strategy**      | **Description**                                                                                                                                                                                                                                                                                               |
        | ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
        | class name        | Returns all elements whose class name contains the search value; compound class names are not permitted.                                                                                                                                                                                                      |
        | css selector      | Returns all elements matching a CSS selector.                                                                                                                                                                                                                                                                 |
        | id                | Returns all elements whose ID attribute matches the search value.                                                                                                                                                                                                                                             |
        | name              | Returns all elements whose NAME attribute matches the search value.                                                                                                                                                                                                                                           |
        | link text         | Returns all anchor elements whose visible text matches the search value.                                                                                                                                                                                                                                      |
        | partial link text | Returns all anchor elements whose visible text partially matches the search value.                                                                                                                                                                                                                            |
        | tag name          | Returns all elements whose tag name matches the search value.                                                                                                                                                                                                                                                 |
        | xpath             | Returns all elements matching an XPath expression. The provided XPath expression must be applied to the server "as is"; if the expression is not relative to the element root, the server should not modify it. Consequently, an XPath query may return elements not contained in the root element's subtree. |

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **JSON Parameters:**

          * `using` - `{string}` The locator strategy to use.
          * `value` - `{string}` The The search target.

      * * **Returns:**

          `{Array.<{ELEMENT:string}>}` A list of WebElement JSON objects for the located elements.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.
          * `XPathLookupError` - If using XPath and the input expression is invalid.

***

#### /session/:sessionId/element/:id/click

* * #### POST /session/:sessionId/element/:id/click

  * * * Click on an element.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.
          * `ElementNotVisible` - If the referenced element is not visible on the page (either is hidden by CSS, has 0-width, or has 0-height)

***

#### /session/:sessionId/element/:id/submit

* * #### POST /session/:sessionId/element/:id/submit

  * * * Submit a `FORM` element. The submit command may also be applied to any element that is a descendant of a `FORM` element.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/text

* * #### GET /session/:sessionId/element/:id/text

  * * * Returns the visible text for the element.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/value

* * #### POST /session/:sessionId/element/:id/value

  * * * Send a sequence of key strokes to an element.\
        \
        Any UTF-8 character may be specified, however, if the server does not support native key events, it should simulate key strokes for a standard US keyboard layout. The Unicode [Private Use Area](http://unicode.org/faq/casemap_charprop.html#8) code points, 0xE000-0xF8FF, are used to represent pressable, non-text keys (see table below).

        |                                                                                                                                                                                                                                        |                                                                                                                                                                                                                                                             |                                                                                                                                                                                                             |                                                                                                                      |                                                                                                                                                                                                        |
        | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
        | Key	CodeNULL	U+E000&#xA;Cancel	U+E001&#xA;Help	U+E002&#xA;Back space	U+E003&#xA;Tab	U+E004&#xA;Clear	U+E005&#xA;Return1	U+E006&#xA;Enter1	U+E007&#xA;Shift	U+E008&#xA;Control	U+E009&#xA;Alt	U+E00A&#xA;Pause	U+E00B&#xA;Escape	U+E00C | Key	CodeSpace	U+E00D&#xA;Pageup	U+E00E&#xA;Pagedown	U+E00F&#xA;End	U+E010&#xA;Home	U+E011&#xA;Left arrow	U+E012&#xA;Up arrow	U+E013&#xA;Right arrow	U+E014&#xA;Down arrow	U+E015&#xA;Insert	U+E016&#xA;Delete	U+E017&#xA;Semicolon	U+E018&#xA;Equals	U+E019 | Key	CodeNumpad 0	U+E01A&#xA;Numpad 1	U+E01B&#xA;Numpad 2	U+E01C&#xA;Numpad 3	U+E01D&#xA;Numpad 4	U+E01E&#xA;Numpad 5	U+E01F&#xA;Numpad 6	U+E020&#xA;Numpad 7	U+E021&#xA;Numpad 8	U+E022&#xA;Numpad 9	U+E023 | Key	CodeMultiply	U+E024&#xA;Add	U+E025&#xA;Separator	U+E026&#xA;Subtract	U+E027&#xA;Decimal	U+E028&#xA;Divide	U+E029 | Key	CodeF1	U+E031&#xA;F2	U+E032&#xA;F3	U+E033&#xA;F4	U+E034&#xA;F5	U+E035&#xA;F6	U+E036&#xA;F7	U+E037&#xA;F8	U+E038&#xA;F9	U+E039&#xA;F10	U+E03A&#xA;F11	U+E03B&#xA;F12	U+E03C&#xA;Command/Meta	U+E03D |
        | 1 The return key is *not the same* as the [enter key](http://en.wikipedia.org/wiki/Enter_key).                                                                                                                                         |                                                                                                                                                                                                                                                             |                                                                                                                                                                                                             |                                                                                                                      |                                                                                                                                                                                                        |

        The server must process the key sequence as follows:

        * Each key that appears on the keyboard without requiring modifiers are sent as a keydown followed by a key up.
        * If the server does not support native events and must simulate key strokes with JavaScript, it must generate keydown, keypress, and keyup events, in that order. The keypress event should only be fired when the corresponding key is for a printable character.
        * If a key requires a modifier key (e.g. "!" on a standard US keyboard), the sequence is: `modifier` down, `key` down, `key` up, `modifier` up, where `key` is the ideal unmodified key value (using the previous example, a "1").
        * Modifier keys (Ctrl, Shift, Alt, and Command/Meta) are assumed to be "sticky"; each modifier should be held down (e.g. only a keydown event) until either the modifier is encountered again in the sequence, or the `NULL` (U+E000) key is encountered.
        * Each key sequence is terminated with an implicit `NULL` key. Subsequently, all depressed modifier keys must be released (with corresponding keyup events) at the end of the sequence.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **JSON Parameters:**

          `value` - `{Array.<string>}` The sequence of keys to type. An array must be provided. The server should flatten the array items to a single string to be typed.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.
          * `ElementNotVisible` - If the referenced element is not visible on the page (either is hidden by CSS, has 0-width, or has 0-height)

***

#### /session/:sessionId/keys

* * #### POST /session/:sessionId/keys

  * * * Send a sequence of key strokes to the active element. This command is similar to the [send keys](JsonWireProtocol#/session/:sessionId/element/:id/value.md) command in every aspect except the implicit termination: The modifiers are **not** released at the end of the call. Rather, the state of the modifier keys is kept between calls, so mouse interactions can be performed while modifier keys are depressed.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `value` - `{Array.<string>}` The keys sequence to be sent. The sequence is defined in the[send keys](JsonWireProtocol#/session/:sessionId/element/:id/value.md) command.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/element/:id/name

* * #### GET /session/:sessionId/element/:id/name

  * * * Query for an element's tag name.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Returns:**

          `{string}` The element's tag name, as a lowercase string.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/clear

* * #### POST /session/:sessionId/element/:id/clear

  * * * Clear a `TEXTAREA` or `text INPUT` element's value.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.
          * `ElementNotVisible` - If the referenced element is not visible on the page (either is hidden by CSS, has 0-width, or has 0-height)
          * `InvalidElementState` - If the referenced element is disabled.

***

#### /session/:sessionId/element/:id/selected

* * #### GET /session/:sessionId/element/:id/selected

  * * * Determine if an `OPTION` element, or an `INPUT` element of type `checkbox` or `radiobutton` is currently selected.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Returns:**

          `{boolean}` Whether the element is selected.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/enabled

* * #### GET /session/:sessionId/element/:id/enabled

  * * * Determine if an element is currently enabled.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Returns:**

          `{boolean}` Whether the element is enabled.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/attribute/:name

* * #### GET /session/:sessionId/element/:id/attribute/:name

  * * * Get the value of an element's attribute.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Returns:**

          `{string|null}` The value of the attribute, or null if it is not set on the element.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/equals/:other

* * #### GET /session/:sessionId/element/:id/equals/:other

  * * * Test if two element IDs refer to the same DOM element.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.
          * `:other` - ID of the element to compare against.

      * * **Returns:**

          `{boolean}` Whether the two IDs refer to the same element.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If either the element refered to by `:id` or `:other` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/displayed

* * #### GET /session/:sessionId/element/:id/displayed

  * * * Determine if an element is currently displayed.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Returns:**

          `{boolean}` Whether the element is displayed.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/location

* * #### GET /session/:sessionId/element/:id/location

  * * * Determine an element's location on the page. The point `(0, 0)` refers to the upper-left corner of the page. The element's coordinates are returned as a JSON object with `x` and `y` properties.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Returns:**

          `{x:number, y:number}` The X and Y coordinates for the element on the page.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/location\_in\_view

* * #### GET /session/:sessionId/element/:id/location\_in\_view

  * * * Determine an element's location on the screen once it has been scrolled into view.\
        \
        **Note:** This is considered an internal command and should **only** be used to determine an element's\
        location for correctly generating native events.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Returns:**

          `{x:number, y:number}` The X and Y coordinates for the element.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/size

* * #### GET /session/:sessionId/element/:id/size

  * * * Determine an element's size in pixels. The size will be returned as a JSON object with `width` and `height` properties.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Returns:**

          `{width:number, height:number}` The width and height of the element, in pixels.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/element/:id/css/:propertyName

* * #### GET /session/:sessionId/element/:id/css/:propertyName

  * * * Query the value of an element's computed CSS property. The CSS property to query should be specified using the CSS property name, **not** the JavaScript property name (e.g. `background-color` instead of `backgroundColor`).

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:id` - ID of the element to route the command to.

      * * **Returns:**

          `{string}` The value of the specified CSS property.

      * * **Potential Errors:**

          * `NoSuchWindow` - If the currently selected window has been closed.
          * `StaleElementReference` - If the element referenced by `:id` is no longer attached to the page's DOM.

***

#### /session/:sessionId/orientation

* * #### GET /session/:sessionId/orientation

  * * * Get the current browser orientation. The server should return a valid orientation value as defined in [ScreenOrientation](http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/ScreenOrientation.html): `{LANDSCAPE|PORTRAIT}`.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{string}` The current browser orientation corresponding to a value defined in [ScreenOrientation](http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/ScreenOrientation.html): `{LANDSCAPE|PORTRAIT}`.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

- - #### POST /session/:sessionId/orientation

  - * * Set the browser orientation. The orientation should be specified as defined in [ScreenOrientation](http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/ScreenOrientation.html): `{LANDSCAPE|PORTRAIT}`.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `orientation` - `{string}` The new browser orientation as defined in [ScreenOrientation](http://selenium.googlecode.com/git/docs/api/java/org/openqa/selenium/ScreenOrientation.html): `{LANDSCAPE|PORTRAIT}`.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/alert\_text

* * #### GET /session/:sessionId/alert\_text

  * * * Gets the text of the currently displayed JavaScript `alert()`, `confirm()`, or `prompt()` dialog.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{string}` The text of the currently displayed alert.

      * * **Potential Errors:**

          `NoAlertPresent` - If there is no alert displayed.

- - #### POST /session/:sessionId/alert\_text

  - * * Sends keystrokes to a JavaScript `prompt()` dialog.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `text` - `{string}` Keystrokes to send to the `prompt()` dialog.

      * * **Potential Errors:**

          `NoAlertPresent` - If there is no alert displayed.

***

#### /session/:sessionId/accept\_alert

* * #### POST /session/:sessionId/accept\_alert

  * * * Accepts the currently displayed alert dialog. Usually, this is equivalent to clicking on the 'OK' button in the dialog.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `NoAlertPresent` - If there is no alert displayed.

***

#### /session/:sessionId/dismiss\_alert

* * #### POST /session/:sessionId/dismiss\_alert

  * * * Dismisses the currently displayed alert dialog. For `confirm()` and `prompt()` dialogs, this is equivalent to clicking the 'Cancel' button. For `alert()` dialogs, this is equivalent to clicking the 'OK' button.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `NoAlertPresent` - If there is no alert displayed.

***

#### /session/:sessionId/moveto

* * #### POST /session/:sessionId/moveto

  * * * Move the mouse by an offset of the specificed element. If no element is specified, the move is relative to the current mouse cursor. If an element is provided but no offset, the mouse will be moved to the center of the element. If the element is not visible, it will be scrolled into view.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `element` - `{string}` Opaque ID assigned to the element to move to, as described in the WebElement JSON Object. If not specified or is null, the offset is relative to current position of the mouse.
          * `xoffset` - `{number}` X offset to move to, relative to the top-left corner of the element. If not specified, the mouse will move to the middle of the element.
          * `yoffset` - `{number}` Y offset to move to, relative to the top-left corner of the element. If not specified, the mouse will move to the middle of the element.

***

#### /session/:sessionId/click

* * #### POST /session/:sessionId/click

  * * * Click any mouse button (at the coordinates set by the last moveto command). Note that calling this command after calling buttondown and before calling button up (or any out-of-order interactions sequence) will yield undefined behaviour).

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `button` - `{number}` Which button, enum: `{LEFT = 0, MIDDLE = 1 , RIGHT = 2}`. Defaults to the left mouse button if not specified.

***

#### /session/:sessionId/buttondown

* * #### POST /session/:sessionId/buttondown

  * * * Click and hold the left mouse button (at the coordinates set by the last moveto command). Note that the next mouse-related command that should follow is buttonup . Any other mouse command (such as click or another call to buttondown) will yield undefined behaviour.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `button` - `{number}` Which button, enum: `{LEFT = 0, MIDDLE = 1 , RIGHT = 2}`. Defaults to the left mouse button if not specified.

***

#### /session/:sessionId/buttonup

* * #### POST /session/:sessionId/buttonup

  * * * Releases the mouse button previously held (where the mouse is currently at). Must be called once for every buttondown command issued. See the note in click and buttondown about implications of out-of-order commands.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `button` - `{number}` Which button, enum: `{LEFT = 0, MIDDLE = 1 , RIGHT = 2}`. Defaults to the left mouse button if not specified.

***

#### /session/:sessionId/doubleclick

* * #### POST /session/:sessionId/doubleclick

  * * * Double-clicks at the current mouse coordinates (set by moveto).

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

***

#### /session/:sessionId/touch/click

* * #### POST /session/:sessionId/touch/click

  * * * Single tap on the touch enabled device.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `element` - `{string}` ID of the element to single tap on.

***

#### /session/:sessionId/touch/down

* * #### POST /session/:sessionId/touch/down

  * * * Finger down on the screen.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `x` - `{number}` X coordinate on the screen.
          * `y` - `{number}` Y coordinate on the screen.

***

#### /session/:sessionId/touch/up

* * #### POST /session/:sessionId/touch/up

  * * * Finger up on the screen.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `x` - `{number}` X coordinate on the screen.
          * `y` - `{number}` Y coordinate on the screen.

***

#### session/:sessionId/touch/move

* * #### POST session/:sessionId/touch/move

  * * * Finger move on the screen.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `x` - `{number}` X coordinate on the screen.
          * `y` - `{number}` Y coordinate on the screen.

***

#### session/:sessionId/touch/scroll

* * #### POST session/:sessionId/touch/scroll

  * * * Scroll on the touch screen using finger based motion events. Use this command to start scrolling at a particular screen location.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `element` - `{string}` ID of the element where the scroll starts.
          * `xoffset` - `{number}` The x offset in pixels to scroll by.
          * `yoffset` - `{number}` The y offset in pixels to scroll by.

***

#### session/:sessionId/touch/scroll

* * #### POST session/:sessionId/touch/scroll

  * * * Scroll on the touch screen using finger based motion events. Use this command if you don't care where the scroll starts on the screen.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `xoffset` - `{number}` The x offset in pixels to scrollby.
          * `yoffset` - `{number}` The y offset in pixels to scrollby.

***

#### session/:sessionId/touch/doubleclick

* * #### POST session/:sessionId/touch/doubleclick

  * * * Double tap on the touch screen using finger motion events.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `element` - `{string}` ID of the element to double tap on.

***

#### session/:sessionId/touch/longclick

* * #### POST session/:sessionId/touch/longclick

  * * * Long press on the touch screen using finger motion events.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `element` - `{string}` ID of the element to long press on.

***

#### session/:sessionId/touch/flick

* * #### POST session/:sessionId/touch/flick

  * * * Flick on the touch screen using finger motion events. This flickcommand starts at a particulat screen location.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `element` - `{string}` ID of the element where the flick starts.
          * `xoffset` - `{number}` The x offset in pixels to flick by.
          * `yoffset` - `{number}` The y offset in pixels to flick by.
          * `speed` - `{number}` The speed in pixels per seconds.

***

#### session/:sessionId/touch/flick

* * #### POST session/:sessionId/touch/flick

  * * * Flick on the touch screen using finger motion events. Use this flick command if you don't care where the flick starts on the screen.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `xspeed` - `{number}` The x speed in pixels per second.
          * `yspeed` - `{number}` The y speed in pixels per second.

***

#### /session/:sessionId/location

* * #### GET /session/:sessionId/location

  * * * Get the current geo location.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{latitude: number, longitude: number, altitude: number}` The current geo location.

- - #### POST /session/:sessionId/location

  - * * Set the current geo location.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `location` - `{latitude: number, longitude: number, altitude: number}` The new location.

***

#### /session/:sessionId/local\_storage

* * #### GET /session/:sessionId/local\_storage

  * * * Get all keys of the storage.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{Array.<string>}` The list of keys.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

- - #### POST /session/:sessionId/local\_storage

  - * * Set the storage item for the given key.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `key` - `{string}` The key to set.
          * `value` - `{string}` The value to set.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

* * #### DELETE /session/:sessionId/local\_storage

  * * * Clear the storage.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/local\_storage/key/:key

* * #### GET /session/:sessionId/local\_storage/key/:key

  * * * Get the storage item for the given key.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:key` - The key to get.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

- - #### DELETE /session/:sessionId/local\_storage/key/:key

  - * * Remove the storage item for the given key.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:key` - The key to remove.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/local\_storage/size

* * #### GET /session/:sessionId/local\_storage/size

  * * * Get the number of items in the storage.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{number}` The number of items in the storage.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/session\_storage

* * #### GET /session/:sessionId/session\_storage

  * * * Get all keys of the storage.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{Array.<string>}` The list of keys.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

- - #### POST /session/:sessionId/session\_storage

  - * * Set the storage item for the given key.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          * `key` - `{string}` The key to set.
          * `value` - `{string}` The value to set.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

* * #### DELETE /session/:sessionId/session\_storage

  * * * Clear the storage.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/session\_storage/key/:key

* * #### GET /session/:sessionId/session\_storage/key/:key

  * * * Get the storage item for the given key.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:key` - The key to get.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

- - #### DELETE /session/:sessionId/session\_storage/key/:key

  - * * Remove the storage item for the given key.

      * * **URL Parameters:**

          * `:sessionId` - ID of the session to route the command to.
          * `:key` - The key to remove.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/session\_storage/size

* * #### GET /session/:sessionId/session\_storage/size

  * * * Get the number of items in the storage.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{number}` The number of items in the storage.

      * * **Potential Errors:**

          `NoSuchWindow` - If the currently selected window has been closed.

***

#### /session/:sessionId/log

* * #### POST /session/:sessionId/log

  * * * Get the log for a given log type. Log buffer is reset after each request.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **JSON Parameters:**

          `type` - `{string}` The [log type](#Log_Type.md). This must be provided.

      * * **Returns:**

          `{Array.<object>}` The list of [log entries](#Log_Entry_JSON_Object.md).

***

#### /session/:sessionId/log/types

* * #### GET /session/:sessionId/log/types

  * * * Get available log types.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{Array.<string>}` The list of available [log types](#Log_Type.md).

***

#### /session/:sessionId/application\_cache/status

* * #### GET /session/:sessionId/application\_cache/status

  * * * Get the status of the html5 application cache.

      * * **URL Parameters:**

          `:sessionId` - ID of the session to route the command to.

      * * **Returns:**

          `{number}` Status code for application cache: {UNCACHED = 0, IDLE = 1, CHECKING = 2, DOWNLOADING = 3, UPDATE\_READY = 4, OBSOLETE = 5}

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/bidi/logging/
----

# WebDriver BiDi 日志功能

这些功能与日志记录有关。 由于"logging"可以指代许多不同的事物, 因此这些方法通过"script"命名空间提供.

请记住, 要使用 WebDriver BiDi, 您必须在选项中启用它. 更多详情, 请参阅 [启用 BiDi](https://www.selenium.dev/zh-cn/documentation/webdriver/bidi/) .

## 控制台消息处理程序

记录或对 `console.log` 事件采取行动.

### 添加处理程序

*
*
*
*
*
*

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.script.add_console_message_handler(log_entries.append)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/test_bidi_logging.py#L11)

##### /examples/python/tests/bidi/test\_bidi\_logging.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_console_message_handler(log_entries.append)

    driver.find_element(By.ID, "consoleLog").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Hello, world!"


@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0


@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_javascript_error_handler(log_entries.append)

    driver.find_element(By.ID, "jsException").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Error: Not working"


@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    log_entries = []
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/logging_spec.rb#L11)

##### /examples/ruby/spec/bidi/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_console_message_handler { |log| log_entries << log }

    driver.find_element(id: 'consoleLog').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Hello, world!'
  end

  it 'removes console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_console_message_handler { |log| log_entries << log }
    driver.script.remove_console_message_handler(id)

    driver.find_element(id: 'consoleLog').click
    expect(log_entries).to be_empty
  end

  it 'adds JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_javascript_error_handler { |error| log_entries << error }

    driver.find_element(id: 'jsException').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Error: Not working'
  end

  it 'removes JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_javascript_error_handler { |error| log_entries << error }
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(id: 'jsException').click
    expect(log_entries).to be_empty
  end
end
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

### 删除处理程序

您需要存储添加处理程序时返回的 ID 以便将其删除.

*
*
*
*
*
*

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/test_bidi_logging.py#L23-24)

##### /examples/python/tests/bidi/test\_bidi\_logging.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_console_message_handler(log_entries.append)

    driver.find_element(By.ID, "consoleLog").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Hello, world!"


@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0


@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_javascript_error_handler(log_entries.append)

    driver.find_element(By.ID, "jsException").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Error: Not working"


@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    log_entries = []
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/logging_spec.rb#L22-L23)

##### /examples/ruby/spec/bidi/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_console_message_handler { |log| log_entries << log }

    driver.find_element(id: 'consoleLog').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Hello, world!'
  end

  it 'removes console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_console_message_handler { |log| log_entries << log }
    driver.script.remove_console_message_handler(id)

    driver.find_element(id: 'consoleLog').click
    expect(log_entries).to be_empty
  end

  it 'adds JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_javascript_error_handler { |error| log_entries << error }

    driver.find_element(id: 'jsException').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Error: Not working'
  end

  it 'removes JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_javascript_error_handler { |error| log_entries << error }
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(id: 'jsException').click
    expect(log_entries).to be_empty
  end
end
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

## JavaScript 异常处理程序

记录或对 JavaScript 异常事件采取行动.

### 添加处理程序

*
*
*
*
*
*

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.script.add_javascript_error_handler(log_entries.append)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/test_bidi_logging.py#L35)

##### /examples/python/tests/bidi/test\_bidi\_logging.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_console_message_handler(log_entries.append)

    driver.find_element(By.ID, "consoleLog").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Hello, world!"


@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0


@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_javascript_error_handler(log_entries.append)

    driver.find_element(By.ID, "jsException").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Error: Not working"


@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    log_entries = []
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/logging_spec.rb#L33)

##### /examples/ruby/spec/bidi/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_console_message_handler { |log| log_entries << log }

    driver.find_element(id: 'consoleLog').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Hello, world!'
  end

  it 'removes console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_console_message_handler { |log| log_entries << log }
    driver.script.remove_console_message_handler(id)

    driver.find_element(id: 'consoleLog').click
    expect(log_entries).to be_empty
  end

  it 'adds JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_javascript_error_handler { |error| log_entries << error }

    driver.find_element(id: 'jsException').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Error: Not working'
  end

  it 'removes JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_javascript_error_handler { |error| log_entries << error }
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(id: 'jsException').click
    expect(log_entries).to be_empty
  end
end
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

### 删除处理程序

您需要存储添加处理程序时返回的 ID 以便将其删除.

*
*
*
*
*
*

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/test_bidi_logging.py#L47-48)

##### /examples/python/tests/bidi/test\_bidi\_logging.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_console_message_handler(log_entries.append)

    driver.find_element(By.ID, "consoleLog").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Hello, world!"


@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0


@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_javascript_error_handler(log_entries.append)

    driver.find_element(By.ID, "jsException").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Error: Not working"


@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    log_entries = []
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/logging_spec.rb#L44-L45)

##### /examples/ruby/spec/bidi/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_console_message_handler { |log| log_entries << log }

    driver.find_element(id: 'consoleLog').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Hello, world!'
  end

  it 'removes console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_console_message_handler { |log| log_entries << log }
    driver.script.remove_console_message_handler(id)

    driver.find_element(id: 'consoleLog').click
    expect(log_entries).to be_empty
  end

  it 'adds JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_javascript_error_handler { |error| log_entries << error }

    driver.find_element(id: 'jsException').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Error: Not working'
  end

  it 'removes JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_javascript_error_handler { |error| log_entries << error }
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(id: 'jsException').click
    expect(log_entries).to be_empty
  end
end
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

最后修改 April 30, 2025: [Update Bidi Logging Doc for zh-cn (#2290) (4e326433eb1)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/4e326433eb1096cd78b58df4350ff8414459bece)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/browsers/edge/
----

# Funcionalidade específica do Edge

```java

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L38-L39)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options = get_default_edge_options()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L9-L10)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        {
            var options = new EdgeOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L30-L31)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let options = new edge.Options();
    driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/openEdgeTest.spec.js#L11-L15)

##### /examples/javascript/test/getting\_started/openEdgeTest.spec.js

```js
const {Browser, Builder} = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');


describe('Open Edge', function () {
  let driver;



  before(async function () {
    let options = new edge.Options();
    driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options)
      .build();
  });

  after(async () => await driver.quit());

  it('Basic Edge test', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
  public void arguments() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L46)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L18)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L39)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.args << '--start-maximized'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L17)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.addArguments('--headless=new'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L12)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```java
  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L54)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L29)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L49)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.binary = edge_location
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L25)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L66)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L40)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L61)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.add_extension(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L34)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L55)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L51)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

**Note**: This is already the default behavior in .NET.

```rb
      options.detach = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L45)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.detachDriver(true))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L32)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```java
  public void excludeSwitches() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L79)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L62)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L76)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.exclude_switches << 'disable-popup-blocking'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L53)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L22)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```java
  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L101)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY`\
Property value: String representing path to log file

```py
def test_log_to_file(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L71)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L86)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L67)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    File logLocation = getTempFile("logsToConsole", ".log");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L114)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
def test_log_to_stdout(capfd):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L82)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

`$stdout` and `$stderr` are both valid values

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L76)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L127-L128)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY`\
Property value: String representation of `ChromiumDriverLogLevel` enum

```py
def test_log_level(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L93)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '--log-level=DEBUG'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L87)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L143-L144)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows toggling these features by System Property:\
Property keys: `EdgeDriverService.EDGE_DRIVER_APPEND_LOG_PROPERTY` and `EdgeDriverService.EDGE_DRIVER_READABLE_TIMESTAMP`\
Property value: `"true"` or `"false"`

```py
def test_log_features(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L104)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << '--append-log'
      service.args << '--readable-timestamp'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L97-L98)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L161-L162)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows disabling build checks by System Property:\
Property key: `EdgeDriverService.EDGE_DRIVER_DISABLE_BUILD_CHECK`\
Property value: `"true"` or `"false"`

```py
def test_build_checks(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L115)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L155)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << '--disable-build-check'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L108)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L225-L230)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L170-L174)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L119-L123)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L198-L204)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L129-L135)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L129)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    consoleLogButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L242)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L186)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      sleep 1
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L141)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    EdgeDriver driver = new EdgeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L184)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L149)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L149-L150)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### DevTools

See the \[Chrome DevTools] section for more information about using DevTools in Edge

----
url: https://www.selenium.dev/ja/documentation/test_practices/discouraged/two_factor_authentication/
----

# 二要素認証

*2FA* として知られている2要素認証は、“Google Authenticator” 、 “Microsoft Authenticator” などの"Authenticator" モバイルアプリを使用して、 またはSMS、電子メールで認証することにより、 ワンタイムパスワード（OTP）を生成する認証メカニズムです。 これをシームレスかつ一貫して自動化することは、Seleniumの大きな課題です。 このプロセスを自動化する方法はいくつかあります。 しかし、これはSeleniumテストの上にある別のレイヤーであり、また安全でもありません。 したがって、2FAの自動化を回避したほうがいいです。

2FAチェックを回避するいくつかの選択肢があります。

* テスト環境で特定のユーザーの2FAを無効にして、 それらのユーザー資格情報を自動化で使用できるようにします。
* テスト環境で2FAを無効にします。
* 特定のIPからログインする場合は、2FAを無効にします。 そうすれば、テストマシンのIPを設定してこれを回避できます。

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/interactions/cookies/
----

# 同cookies一起工作

```java

    WebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L30-L32)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L5-9)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L32-L34)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L9-L11)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L18)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

  const {Browser, Builder} = require("selenium-webdriver");
  const assert = require('assert')
  
  
  describe('Cookies', function() {
    let driver;
  
    before(async function() {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('Create a cookie', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // set a cookie on the current domain
      await driver.manage().addCookie({ name: 'key', value: 'value' });
    });
  
    it('Create cookies with sameSite', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
      await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
      await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
    });
  
    it('Read cookie', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // set a cookie on the current domain
      await driver.manage().addCookie({ name: 'foo', value: 'bar' });
  
      // Get cookie details with named cookie 'foo'
      await driver.manage().getCookie('foo').then(function(cookie) {
        assert.equal(cookie.value, 'bar');
      });
    });
  
    it('Read all cookies', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // Add few cookies
      await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
      await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
  
      // Get all Available cookies
      await driver.manage().getCookies().then(function(cookies) {
        assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
      });
    });
  
    it('Delete a cookie', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // Add few cookies
      await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
      await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
  
      // Delete a cookie with name 'test1'
      await driver.manage().deleteCookie('test1');
  
      // Get all Available cookies
      await driver.manage().getCookies().then(function(cookies) {
        assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
      });
    });
  
    it('Delete all cookies', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // Add few cookies
      await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
      await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
  
      // Delete all cookies
      await driver.manage().deleteAllCookies();
    });
  });
  
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")

        // Adds the cookie into current browser context
        driver.manage().addCookie(Cookie("key", "value"))
    } finally {
        driver.quit()
    }
}  
  
```

```java
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L38-L42)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L13-L20)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L40-L44)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L17-L21)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L35-L38)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("foo", "bar"))

        // Get cookie details with named cookie 'foo'
        val cookie = driver.manage().getCookieNamed("foo")
        println(cookie)
    } finally {
        driver.quit()
    }
}  
  
```

```java
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L52-L66)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L24-L32)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L51-L64)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L26-L31)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L49-L51)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        driver.manage().addCookie(Cookie("test2", "cookie2"))

        // Get All available cookies
        val cookies = driver.manage().cookies
        println(cookies)
    } finally {
        driver.quit()
    }
}  
  
```

```java
        }
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L74-L77)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L35-L43)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L70-L73)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L40-L43)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L61-L62)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        val cookie1 = Cookie("test2", "cookie2")
        driver.manage().addCookie(cookie1)

        // delete a cookie with name 'test1'
        driver.manage().deleteCookieNamed("test1")
        
        // delete cookie by passing cookie object of current browsing context.
        driver.manage().deleteCookie(cookie1)
    } finally {
        driver.quit()
    }
}  
  
```

```java
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L100-L105)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L47-L55)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L92-L97)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L49-L54)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L77-L78)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        driver.manage().addCookie(Cookie("test2", "cookie2"))

        // deletes all cookies
        driver.manage().deleteAllCookies()
    } finally {
        driver.quit()
    }
}
  
```

```java

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L112-L121)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L59-L71)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SameSiteCookie {
  class SameSiteCookie {
    static void Main(string[] args) {
      IWebDriver driver = new ChromeDriver();
      try {
        driver.Navigate().GoToUrl("http://www.example.com");

        var cookie1Dictionary = new System.Collections.Generic.Dictionary<string, object>() {
          { "name", "test1" }, { "value", "cookie1" }, { "sameSite", "Strict" } };
        var cookie1 = Cookie.FromDictionary(cookie1Dictionary);

        var cookie2Dictionary = new System.Collections.Generic.Dictionary<string, object>() {
          { "name", "test2" }, { "value", "cookie2" }, { "sameSite", "Lax" } };
        var cookie2 = Cookie.FromDictionary(cookie2Dictionary);

        driver.Manage().Cookies.AddCookie(cookie1);
        driver.Manage().Cookies.AddCookie(cookie2);

        System.Console.WriteLine(cookie1.SameSite);
        System.Console.WriteLine(cookie2.SameSite);
      } finally {
        driver.Quit();
      }
    }
  }
}
  
```

```ruby
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://www.example.com'
  # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
  driver.manage.add_cookie(name: "foo", value: "bar", same_site: "Strict")
  driver.manage.add_cookie(name: "foo1", value: "bar", same_site: "Lax")
  puts driver.manage.cookie_named('foo')
  puts driver.manage.cookie_named('foo1')
ensure
  driver.quit
end
  
```

```js
  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L24-L26)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("http://www.example.com")
        val cookie = Cookie.Builder("key", "value").sameSite("Strict").build()
        val cookie1 = Cookie.Builder("key", "value").sameSite("Lax").build()
        driver.manage().addCookie(cookie)
        driver.manage().addCookie(cookie1)
        println(cookie.getSameSite())
        println(cookie1.getSameSite())
    } finally {
        driver.quit()
    }
} 
  
```

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/browsers/internet_explorer/
----

# Funcionalidade específica do IE

```java
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#38-L41)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

```py
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L11-L14)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L35-L38)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

```rb
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L17-L20)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#46-L47)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

```py
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L21-L22)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L44-L45)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L24-L25)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
let driver = await new Builder()
.forBrowser('internet explorer')
.setIEOptions(options)
.build();
```

```kotlin
<p><a href=/documentation/about/contributing/#moving-examples>
<span class="selenium-badge-code" data-bs-toggle="tooltip" data-bs-placement="right"
      title="One or more of these examples need to be implemented in the examples directory; click for details in the contribution guide">Move Code</span></a></p>


val options = InternetExplorerOptions()
val driver = InternetExplorerDriver(options)
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.waitForUploadDialogUpTo(Duration.ofSeconds(2));
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L28-L29)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.FileUploadDialogTimeout = TimeSpan.FromMilliseconds(2000);
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.file_upload_dialog_timeout = 2000
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L29)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().fileUploadDialogTimeout(2000);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.waitForUploadDialogUpTo(Duration.ofSeconds(2))
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.destructivelyEnsureCleanSession();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ensure_clean_session = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L38-L39)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.EnsureCleanSession = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ensure_clean_session = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L35)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().ensureCleanSession(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.destructivelyEnsureCleanSession()
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.ignoreZoomSettings();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L48-L49)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.IgnoreZoomLevel = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ignore_zoom_level = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L41)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().ignoreZoomSetting(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.ignoreZoomSettings()
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.introduceFlakinessByIgnoringSecurityDomains();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L58-L59)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.IntroduceInstabilityByIgnoringProtectedModeSettings = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ignore_protected_mode_settings = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L47)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().introduceFlakinessByIgnoringProtectedModeSettings(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.introduceFlakinessByIgnoringSecurityDomains()
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.setCapability("silent", true);
WebDriver driver = new InternetExplorerDriver(options);
  
```

```py
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L68-L69)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
InternetExplorerOptions options = new InternetExplorerOptions();
options.AddAdditionalInternetExplorerOption("silent", true);
IWebDriver driver = new InternetExplorerDriver(options);
  
```

```rb
      @options.silent = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L53)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const {Builder,By, Capabilities} = require('selenium-webdriver');
let caps = Capabilities.ie();
caps.set('silent', true);

(async function example() {
    let driver = await new Builder()
        .forBrowser('internet explorer')
        .withCapabilities(caps)
        .build();
    try {
        await driver.get('http://www.google.com/ncr');
    }
    finally {
        await driver.quit();
    }
})();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.setCapability("silent", true)
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  
```

```java
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;

public class ieTest {
    public static void main(String[] args) {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.useCreateProcessApiToLaunchIe();
        options.addCommandSwitches("-k");
        InternetExplorerDriver driver = new InternetExplorerDriver(options);
        try {
            driver.get("https://google.com/ncr");
            Capabilities caps = driver.getCapabilities();
            System.out.println(caps);
        } finally {
            driver.quit();
        }
    }
}
  
```

```py
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L76-L79)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;

namespace ieTest {
 class Program {
  static void Main(string[] args) {
   InternetExplorerOptions options = new InternetExplorerOptions();
   options.ForceCreateProcessApi = true;
   options.BrowserCommandLineArguments = "-k";
   IWebDriver driver = new InternetExplorerDriver(options);
   driver.Url = "https://google.com/ncr";
  }
 }
}
  
```

```rb
      @options.add_argument('-k')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L58)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options();
options.addBrowserCommandSwitches('-k');
options.addBrowserCommandSwitches('-private');
options.forceCreateProcessApi(true);

driver = await env.builder()
          .setIeOptions(options)
          .build();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.useCreateProcessApiToLaunchIe()
    options.addCommandSwitches("-k")
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  
```

```java
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;

public class ieTest {
    public static void main(String[] args) {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.useCreateProcessApiToLaunchIe();
        InternetExplorerDriver driver = new InternetExplorerDriver(options);
        try {
            driver.get("https://google.com/ncr");
            Capabilities caps = driver.getCapabilities();
            System.out.println(caps);
        } finally {
            driver.quit();
        }
    }
}
  
```

```py
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L87-L90)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;

namespace ieTest {
 class Program {
  static void Main(string[] args) {
   InternetExplorerOptions options = new InternetExplorerOptions();
   options.ForceCreateProcessApi = true;
   IWebDriver driver = new InternetExplorerDriver(options);
   driver.Url = "https://google.com/ncr";
  }
 }
}
  
```

```rb
      @options.force_create_process_api = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L63)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options();
options.forceCreateProcessApi(true);

driver = await env.builder()
          .setIeOptions(options)
          .build();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.useCreateProcessApiToLaunchIe()
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  
```

```java
                .withLogFile(getLogLocation())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L53)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY`\
Property value: String representing path to log file

```py
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L97-L99)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L82)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
                .withLogOutput(System.out)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L67)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L109-L111)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L91)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L82)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGLEVEL_PROPERTY`\
Property value: String representation of `InternetExplorerDriverLogLevel.DEBUG.toString()` enum

```py
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L121-123)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            if (_tempPath == null || !File.Exists(_tempPath))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L85)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '-log-level=WARN'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L102)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
                .withExtractPath(getTempDirectory())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L94)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

\*\*Note\*\*: Java also allows setting log level by System Property:\ Property key: \`InternetExplorerDriverService.IE\_DRIVER\_EXTRACT\_PATH\_PROPERTY\`\ Property value: String representing path to supporting files directory

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L133-135)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L98)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << "–extract-path=#{root_directory}"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L112)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/browsers/
----

# 支持的浏览器列表

每个浏览器都有定制和特有的功能。

***

##### [Chrome 特定功能](/zh-cn/documentation/webdriver/browsers/chrome/)

特定于 Google Chrome 浏览器的功能和特性.

##### [Edge 特定功能](/zh-cn/documentation/webdriver/browsers/edge/)

这些是特定于微软Edge浏览器的功能和特性.

##### [Firefox specific functionality](/zh-cn/documentation/webdriver/browsers/firefox/)

These are capabilities and features specific to Mozilla Firefox browsers.

##### [IE 特定功能](/zh-cn/documentation/webdriver/browsers/internet_explorer/)

这些是 Microsoft Internet Explorer 浏览器特有的功能和特性.

##### [Safari 特定功能](/zh-cn/documentation/webdriver/browsers/safari/)

这些是特定于Apple Safari浏览器的功能和特性.

最后修改 October 13, 2022: [Update \_index.zh-cn.md (#1194) (9101cc0a53e)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/9101cc0a53ed23e09f121c2181eed7801e5c9e7e)

----
url: https://www.selenium.dev/ja/documentation/webdriver/drivers/remote_webdriver/
----

# リモートWebDriver

```java
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L38-L39)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L13-L14)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L28-L29)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L20-L21)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L49-L52)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

Pythonでは、リモートWebDriverインスタンスにデフォルトでローカルファイルディテクターが追加されますが、独自のクラスを作成することも可能です。

```py
    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#LL29-L32)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

.NETでは、リモートWebDriverインスタンスにデフォルトでローカルファイルディテクターが追加されますが、独自のクラスを作成することも可能です。

```cs
            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L47-L50)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

Rubyでは、リモートWebDriverインスタンスにデフォルトでローカルファイルディテクターが追加されますが、独自のラムダを作成することも可能です。

```rb
    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L33-L36)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## ダウンロード

Chrome、Edge、およびFirefoxでは、それぞれダウンロードディレクトリの場所を設定できます。 ただし、リモートコンピュータでこれを行う場合、その場所はリモートコンピュータのローカルファイルシステム上にあります。Seleniumを使用すると、クライアントコンピュータにこれらのファイルをダウンロードできるように設定することが可能です。

### グリッドでのダウンロードを有効化

クライアントに関係なく、ノードまたはスタンドアロンモードでグリッドを起動する際には、次のフラグを追加する必要があります:

```
--enable-managed-downloads true
```

```java
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L60-L62)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L42-L44)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L59-L64)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L43-L44)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    List<String> files = ((HasDownloads) driver).getDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L73)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    files = driver.get_downloadable_files()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L52)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L72)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    files = driver.downloadable_files
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L52)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L83)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    driver.download_file(downloadable_file, target_directory)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L58)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L79)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    driver.download_file(downloadable_file, target_directory)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L57)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((HasDownloads) driver).deleteDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L88)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    driver.delete_downloadable_files()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L64)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ((RemoteWebDriver)driver).DeleteDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L84)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    driver.delete_downloadable_files
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L62)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    driver = new Augmenter().augment(driver);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L98)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

興味深いことに、RemoteWebDriverBuilderを使用すると、ドライバーが自動的に拡張されるため、デフォルトで全ての機能を取得するのに最適な方法です。

```java
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L106-L111)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

.NETでは、リモートドライバーで指定されたブラウザに対して有効なコマンドを実行するために、カスタムコマンドエグゼキュータを使用します。

```cs
            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L96-L100)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```xml
  <dependency>
      <groupId>io.opentelemetry</groupId>
      <artifactId>opentelemetry-exporter-jaeger</artifactId>
      <version>1.0.0</version>
    </dependency>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-netty</artifactId>
      <version>1.35.0</version>
    </dependency>
```

### クライアントの実行中に必要なシステムプロパティを追加/渡す

*

```java
System.setProperty("otel.traces.exporter", "jaeger");
System.setProperty("otel.exporter.jaeger.endpoint", "http://localhost:14250");
System.setProperty("otel.resource.attributes", "service.name=selenium-java-client");

ImmutableCapabilities capabilities = new ImmutableCapabilities("browserName", "chrome");

WebDriver driver = new RemoteWebDriver(new URL("http://www.example.com"), capabilities);

driver.get("http://www.google.com");

driver.quit();

  
```

ご希望のSeleniumのバージョンに必要な外部依存関係のバージョンの詳細については、 [トレースのセットアップ](https://github.com/SeleniumHQ/selenium/blob/selenium-4.0.0-beta-1/java/server/src/org/openqa/selenium/grid/commands/tracing.txt) を参照してください。

詳細については、下記URLを参照してください。

* OpenTelemetry: <https://opentelemetry.io>
* OpenTelemetryの構成:: <https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure>
* Jaeger: <https://www.jaegertracing.io>
* [Selenium Grid 可観測性](https://www.selenium.dev/ja/documentation/grid/advanced_features/observability/)

----
url: https://www.selenium.dev/documentation/test_practices/encouraged/domain_specific_language/
----

# Domain specific language

```java
/**
 * Takes a username and password, fills out the fields, and clicks "login".
 * @return An instance of the AccountPage
 */
public AccountPage loginAsUser(String username, String password) {
  WebElement loginField = driver.findElement(By.id("loginField"));
  loginField.clear();
  loginField.sendKeys(username);

  // Fill out the password field. The locator we're using is "By.id", and we should
  // have it defined elsewhere in the class.
  WebElement passwordField = driver.findElement(By.id("password"));
  passwordField.clear();
  passwordField.sendKeys(password);

  // Click the login button, which happens to have the id "submit".
  driver.findElement(By.id("submit")).click();

  // Create and return a new instance of the AccountPage (via the built-in Selenium
  // PageFactory).
  return PageFactory.newInstance(AccountPage.class);
}
```

This method completely abstracts the concepts of input fields, buttons, clicking, and even pages from your test code. Using this approach, all a tester has to do is call this method. This gives you a maintenance advantage: if the login fields ever changed, you would only ever have to change this method - not your tests.

```java
public void loginTest() {
    loginAsUser("cbrown", "cl0wn3");

    // Now that we're logged in, do some other stuff--since we used a DSL to support
    // our testers, it's as easy as choosing from available methods.
    do.something();
    do.somethingElse();
    Assert.assertTrue("Something should have been done!", something.wasDone());

    // Note that we still haven't referred to a button or web control anywhere in this
    // script...
}
```

It bears repeating: one of your primary goals should be writing an API that allows your tests to address **the problem at hand, and NOT the problem of the UI**. The UI is a secondary concern for your users – they do not care about the UI, they just want to get their job done. Your test scripts should read like a laundry list of things the user wants to DO, and the things they want to KNOW. The tests should not concern themselves with HOW the UI requires you to go about it.

\***AUT**: Application under test

Last modified December 13, 2021: [Move wiki content to docs (#877) \[deploy site\] (aa6066432f5)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/aa6066432f56dbf40be0e25e685f10d7ef0ce48b)

----
url: https://www.selenium.dev/documentation/webdriver/support_features/thread_guard/
----

# ThreadGuard

This class is only available in the Java Binding

ThreadGuard checks that a driver is called only from the same thread that created it. Threading issues especially when running tests in Parallel may have mysterious and hard to diagnose errors. Using this wrapper prevents this category of errors and will raise an exception when it happens.

The following example simulate a clash of threads:

```java
public class DriverClash {
  //thread main (id 1) created this driver
  private WebDriver protectedDriver = ThreadGuard.protect(new ChromeDriver()); 

  static {
    System.setProperty("webdriver.chrome.driver", "<Set path to your Chromedriver>");
  }
  
  //Thread-1 (id 24) is calling the same driver causing the clash to happen
  Runnable r1 = () -> {protectedDriver.get("https://selenium.dev");};
  Thread thr1 = new Thread(r1);
   
  void runThreads(){
    thr1.start();
  }

  public static void main(String[] args) {
    new DriverClash().runThreads();
  }
}
```

The result shown below:

```text
Exception in thread "Thread-1" org.openqa.selenium.WebDriverException:
Thread safety error; this instance of WebDriver was constructed
on thread main (id 1)and is being accessed by thread Thread-1 (id 24)
This is not permitted and *will* cause undefined behaviour
```

----
url: https://www.selenium.dev/pt-br/documentation/overview/details/
----

# Detalhes

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/remote_webdriver/
----

# 远程WebDriver

```java
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L38-L39)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L13-L14)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L28-L29)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L20-L21)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L49-L52)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

Python adds a local file detector to remote webdriver instances by default, but you can also create your own class.

```py
    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#LL29-L32)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

.NET adds a local file detector to remote webdriver instances by default, but you can also create your own class.

```cs
            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L47-L50)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

Ruby adds a local file detector to remote webdriver instances by default, but you can also create your own lambda:

```rb
    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L33-L36)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## 下载

Chrome、Edge和Firefox都允许您设置下载目录的位置. 但是, 当您在远程计算机上执行此操作时, 位置在远程计算机的本地文件系统上. Selenium允许您启用下载功能, 将这些文件下载到客户端计算机上.

### 在网格中启用下载

当以节点或独立模式启动网格时, 你必须添加参数:

```
--enable-managed-downloads true
```

```java
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L60-L62)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L42-L44)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L59-L64)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L43-L44)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    List<String> files = ((HasDownloads) driver).getDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L73)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    files = driver.get_downloadable_files()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L52)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L72)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    files = driver.downloadable_files
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L52)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L83)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    driver.download_file(downloadable_file, target_directory)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L58)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L79)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    driver.download_file(downloadable_file, target_directory)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L57)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((HasDownloads) driver).deleteDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L88)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    driver.delete_downloadable_files()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L64)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ((RemoteWebDriver)driver).DeleteDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L84)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    driver.delete_downloadable_files
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L62)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    driver = new Augmenter().augment(driver);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L98)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

Of interest, using the `RemoteWebDriverBuilder` automatically augments the driver, so it is a great way to get all the functionality by default:

```java
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L106-L111)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

.NET uses a custom command executor for executing commands that are valid for the given browser in the remote driver.

```cs
            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L96-L100)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```xml
  <dependency>
      <groupId>io.opentelemetry</groupId>
      <artifactId>opentelemetry-exporter-jaeger</artifactId>
      <version>1.0.0</version>
    </dependency>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-netty</artifactId>
      <version>1.35.0</version>
    </dependency>
```

### 在运行客户端时添加/传递所需的系统属性

*

```java
System.setProperty("otel.traces.exporter", "jaeger");
System.setProperty("otel.exporter.jaeger.endpoint", "http://localhost:14250");
System.setProperty("otel.resource.attributes", "service.name=selenium-java-client");

ImmutableCapabilities capabilities = new ImmutableCapabilities("browserName", "chrome");

WebDriver driver = new RemoteWebDriver(new URL("http://www.example.com"), capabilities);

driver.get("http://www.google.com");

driver.quit();

  
```

有关所需Selenium版本 及其外部依赖关系版本等更多信息, 请参阅[追踪设置](https://github.com/SeleniumHQ/selenium/blob/selenium-4.0.0-beta-1/java/server/src/org/openqa/selenium/grid/commands/tracing.txt) .

更多信息请访问:

* OpenTelemetry: <https://opentelemetry.io>
* 配置OpenTelemetry: <https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure>
* Jaeger: <https://www.jaegertracing.io>
* [Selenium Grid 可观测性](https://www.selenium.dev/zh-cn/documentation/grid/advanced_features/observability/)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/waits/
----

# 等待策略

或许浏览器自动化面临的最常见挑战在于, 确保网络应用程序处于能够按预期执行特定 Selenium 命令的状态. 这些过程常常陷入一种 *竞态条件* , 有时浏览器会先达到正确状态 (一切按预期运行) , 有时 Selenium 代码会先执行 (一切未按预期运行) . 这是导致 *不稳定测试* 的主要原因之一.

所有导航命令都会等待特定基于 [页面加载策略](https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/options/#pageloadstrategy) 的值 `readyState` (默认等待的值为 `"complete"` ) , 然后驱动程序才会将控制权交还给代码. `readyState` 仅关注 HTML 中定义的资源加载, 但加载的 JavaScript 资源常常会导致网站发生变化, 而当代码准备执行下一个 Selenium 命令时, 需要交互的元素可能尚未出现在页面上.

同样, 在许多单页应用程序中, 元素会根据点击操作动态添加到页面上或改变可见性.\
对于 Selenium 能够与之交互, 该元素必须既存在于页面上又处于[displayed](https://www.selenium.dev/zh-cn/documentation/webdriver/elements/information/#is-displayed) 状态.

以这个页面为例: <https://www.selenium.dev/selenium/web/dynamic.html> 当点击 “Add a box!” 按钮时, 会创建一个原本不存在的 “div” 元素.\
当点击 “Reveal a new input” 按钮时, 一个隐藏的文本字段元素会被显示出来.\
在这两种情况下, 过渡都需要几秒钟.\
如果 Selenium 代码要点击其中一个按钮并与生成的元素进行交互,\
它会在该元素准备好之前就执行操作, 从而导致失败.

许多人首先想到的解决办法是在代码中添加一个睡眠语句, 让代码暂停执行一段设定的时间. 由于代码无法确切知道需要等待多久, 如果设置的睡眠时间不够长, 这种方法可能会失败. 相反, 如果睡眠时间设置得过高, 并且在每个需要的地方都添加睡眠语句, 那么会话的持续时间可能会变得难以接受.

Selenium 提供了更好的两种不同的同步机制,

## 隐式等待

Selenium 内置了一种自动等待元素出现的方式, 称为 *隐式等待* .\
隐式等待的值可以通过浏览器选项中的 [timeouts](https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/options/#timeouts) 设置来设定, 也可以通过驱动程序的方法来设定 (如下所示) .

这是一个全局设置, 适用于整个会话期间的每个元素定位调用. 默认值为 `0` , 这意味着如果未找到元素, 将立即返回错误. 如果设置了隐式等待, 驱动程序将在返回错误之前等待所提供的时长. 请注意, 一旦定位到元素, 驱动程序将返回元素引用, 代码将继续执行, 因此较大的隐式等待值不一定增加会话的持续时间.

*警告:* 请勿混合使用隐式等待和显式等待.\
这样做可能会导致等待时间不可预测. 例如, 设置 10 秒的隐式等待和 15 秒的显式等待,\
可能会导致在 20 秒后发生超时.

使用隐式等待解决我们的示例代码如下:

*
*
*
*
*
*

```java
    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L50)

##### /examples/java/src/test/java/dev/selenium/waits/WaitsTest.java

```java
package dev.selenium.waits;

import dev.selenium.BaseTest;
import java.time.Duration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.ElementNotInteractableException;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

public class WaitsTest extends BaseTest {
  @Test
  public void fails() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Assertions.assertThrows(
        NoSuchElementException.class,
        () -> {
          driver.findElement(By.id("box0"));
        });
  }

  @Test
  public void sleep() throws InterruptedException {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Thread.sleep(1000);

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void implicit() {
    startChromeDriver(new ChromeOptions());

    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void explicit() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    wait.until(d -> revealed.isDisplayed());

    revealed.sendKeys("Displayed");
    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }

  @Test
  public void explicitWithOptions() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait =
        new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(2))
            .pollingEvery(Duration.ofMillis(300))
            .ignoring(ElementNotInteractableException.class);

    wait.until(
        d -> {
          revealed.sendKeys("Displayed");
          return true;
        });

    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }
}
```

```py
    driver.implicitly_wait(2)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/waits/test_waits.py#L27)

##### /examples/python/tests/waits/test\_waits.py

```py
import pytest
import time
from selenium.common import NoSuchElementException, ElementNotInteractableException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


def test_fails(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    with pytest.raises(NoSuchElementException):
        driver.find_element(By.ID, 'box0')


def test_sleep(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    time.sleep(2)
    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_implicit(driver):
    driver.implicitly_wait(2)
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_explicit(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(lambda _ : revealed.is_displayed())

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"


def test_explicit_options(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    errors = [NoSuchElementException, ElementNotInteractableException]
    wait = WebDriverWait(driver, timeout=2, poll_frequency=.2, ignored_exceptions=errors)
    wait.until(lambda _ : revealed.send_keys("Displayed") or True)

    assert revealed.get_property("value") == "Displayed"
```

```cs
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L39)

##### /examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs

```cs
using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Waits
{
    [TestClass]
    public class WaitsTest : BaseChromeTest
    {
        [TestMethod]
        public void Fails()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Assert.ThrowsException<NoSuchElementException>(
                () => driver.FindElement(By.Id("box0"))
            );
        }

        [TestMethod]
        public void Sleep()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Thread.Sleep(1000);

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Implicit()
        {
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
            
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Explicit()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2));
            wait.Until(d => revealed.Displayed);

            revealed.SendKeys("Displayed");
            Assert.AreEqual("Displayed", revealed.GetDomProperty("value"));
        }

        [TestMethod]
        public void ExplicitOptions()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2))
            {
                PollingInterval = TimeSpan.FromMilliseconds(300),
            };
            wait.IgnoreExceptionTypes(typeof(ElementNotInteractableException));

            wait.Until(d => {
                revealed.SendKeys("Displayed");
                return true;
            });

            Assert.AreEqual("input", revealed.TagName);
        }
    }
}
```

```rb
    driver.manage.timeouts.implicit_wait = 2
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/waits/waits_spec.rb#L28)

##### /examples/ruby/spec/waits/waits\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Waits' do
  let(:driver) { start_session }

  it 'fails' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    expect {
      driver.find_element(id: 'box0')
    }.to raise_error(Selenium::WebDriver::Error::NoSuchElementError)
  end

  it 'sleeps' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    sleep 1
    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'implicit' do
    driver.manage.timeouts.implicit_wait = 2
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    wait = Selenium::WebDriver::Wait.new
    wait.until { revealed.displayed? }

    revealed.send_keys('Displayed')
    expect(revealed.property(:value)).to eq('Displayed')
  end

  it 'options with explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    errors = [Selenium::WebDriver::Error::NoSuchElementError,
              Selenium::WebDriver::Error::ElementNotInteractableError]
    wait = Selenium::WebDriver::Wait.new(timeout: 2,
                                         interval: 0.3,
                                         ignore: errors)

    wait.until { revealed.send_keys('Displayed') || true }

    expect(revealed.property(:value)).to eq('Displayed')
  end
end
```

```js
        await driver.manage().setTimeouts({ implicit: 2000 });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/waits/waits.spec.js#L39)

##### /examples/javascript/test/waits/waits.spec.js

```js

const { By, Browser, until, Builder} = require('selenium-webdriver');
const assert = require("node:assert");


describe('Waits', function () {
    let driver;

    before(async function () {
        driver = new Builder()
          .forBrowser(Browser.CHROME)
          .build();
    });

    after(async () => await driver.quit());

    it('fail', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        await assert.rejects(async () => {
              await driver.findElement(By.id("box0"))
          },
          Error
        )
    });

    it('sleep', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        await driver.sleep(2000);
        let added = await driver.findElement(By.id("box0"));

        assert.equal(await added.getAttribute('class'), "redbox")
    });

    it('implicit', async function () {
        await driver.manage().setTimeouts({ implicit: 2000 });
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        let added = await driver.findElement(By.id("box0"));

        assert.equal(await added.getAttribute('class'), "redbox")
    });

    it('explicit', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        let revealed = await driver.findElement(By.id("revealed"));
        await driver.findElement(By.id("reveal")).click();
        await driver.wait(until.elementIsVisible(revealed), 2000);
        await revealed.sendKeys("Displayed");
        assert.equal(await revealed.getAttribute("value"), "Displayed")
    })
});
```

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk/examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt#L19)

##### examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt

```kt
```

## 显式等待

*显式等待* 是在代码中添加的, 用于轮询应用程序的循环, 直到特定条件评估为真时, 才退出循环并继续执行代码中的下一个命令. 如果在指定的超时值之前条件未满足, 代码将给出超时错误. 由于应用程序未处于所需状态的方式有很多, 因此显式等待是为每个需要等待的地方指定确切等待条件的绝佳选择.\
另一个不错的特性是, 默认情况下, Selenium 等待类会自动等待指定的元素存在.

*
*
*
*
*
*

This example shows the condition being waited for as a *lambda*. Java also supports [Expected Conditions](https://www.selenium.dev/zh-cn/documentation/webdriver/support_features/expected_conditions/)

```java
    Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    wait.until(d -> revealed.isDisplayed());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L67-L68)

##### /examples/java/src/test/java/dev/selenium/waits/WaitsTest.java

```java
package dev.selenium.waits;

import dev.selenium.BaseTest;
import java.time.Duration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.ElementNotInteractableException;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

public class WaitsTest extends BaseTest {
  @Test
  public void fails() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Assertions.assertThrows(
        NoSuchElementException.class,
        () -> {
          driver.findElement(By.id("box0"));
        });
  }

  @Test
  public void sleep() throws InterruptedException {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Thread.sleep(1000);

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void implicit() {
    startChromeDriver(new ChromeOptions());

    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void explicit() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    wait.until(d -> revealed.isDisplayed());

    revealed.sendKeys("Displayed");
    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }

  @Test
  public void explicitWithOptions() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait =
        new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(2))
            .pollingEvery(Duration.ofMillis(300))
            .ignoring(ElementNotInteractableException.class);

    wait.until(
        d -> {
          revealed.sendKeys("Displayed");
          return true;
        });

    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }
}
```

This example shows the condition being waited for as a *lambda*. Python also supports [Expected Conditions](https://www.selenium.dev/zh-cn/documentation/webdriver/support_features/expected_conditions/)

```py
    wait = WebDriverWait(driver, timeout=2)
    wait.until(lambda _ : revealed.is_displayed())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/waits/test_waits.py#L41-L42)

##### /examples/python/tests/waits/test\_waits.py

```py
import pytest
import time
from selenium.common import NoSuchElementException, ElementNotInteractableException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


def test_fails(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    with pytest.raises(NoSuchElementException):
        driver.find_element(By.ID, 'box0')


def test_sleep(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    time.sleep(2)
    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_implicit(driver):
    driver.implicitly_wait(2)
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_explicit(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(lambda _ : revealed.is_displayed())

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"


def test_explicit_options(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    errors = [NoSuchElementException, ElementNotInteractableException]
    wait = WebDriverWait(driver, timeout=2, poll_frequency=.2, ignored_exceptions=errors)
    wait.until(lambda _ : revealed.send_keys("Displayed") or True)

    assert revealed.get_property("value") == "Displayed"
```

```cs
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2));
            wait.Until(d => revealed.Displayed);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L56-L57)

##### /examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs

```cs
using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Waits
{
    [TestClass]
    public class WaitsTest : BaseChromeTest
    {
        [TestMethod]
        public void Fails()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Assert.ThrowsException<NoSuchElementException>(
                () => driver.FindElement(By.Id("box0"))
            );
        }

        [TestMethod]
        public void Sleep()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Thread.Sleep(1000);

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Implicit()
        {
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
            
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Explicit()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2));
            wait.Until(d => revealed.Displayed);

            revealed.SendKeys("Displayed");
            Assert.AreEqual("Displayed", revealed.GetDomProperty("value"));
        }

        [TestMethod]
        public void ExplicitOptions()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2))
            {
                PollingInterval = TimeSpan.FromMilliseconds(300),
            };
            wait.IgnoreExceptionTypes(typeof(ElementNotInteractableException));

            wait.Until(d => {
                revealed.SendKeys("Displayed");
                return true;
            });

            Assert.AreEqual("input", revealed.TagName);
        }
    }
}
```

```rb
    wait = Selenium::WebDriver::Wait.new
    wait.until { revealed.displayed? }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/waits/waits_spec.rb#L42-L43)

##### /examples/ruby/spec/waits/waits\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Waits' do
  let(:driver) { start_session }

  it 'fails' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    expect {
      driver.find_element(id: 'box0')
    }.to raise_error(Selenium::WebDriver::Error::NoSuchElementError)
  end

  it 'sleeps' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    sleep 1
    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'implicit' do
    driver.manage.timeouts.implicit_wait = 2
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    wait = Selenium::WebDriver::Wait.new
    wait.until { revealed.displayed? }

    revealed.send_keys('Displayed')
    expect(revealed.property(:value)).to eq('Displayed')
  end

  it 'options with explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    errors = [Selenium::WebDriver::Error::NoSuchElementError,
              Selenium::WebDriver::Error::ElementNotInteractableError]
    wait = Selenium::WebDriver::Wait.new(timeout: 2,
                                         interval: 0.3,
                                         ignore: errors)

    wait.until { revealed.send_keys('Displayed') || true }

    expect(revealed.property(:value)).to eq('Displayed')
  end
end
```

JavaScript also supports [Expected Conditions](https://www.selenium.dev/zh-cn/documentation/webdriver/support_features/expected_conditions/)

```js
        await driver.wait(until.elementIsVisible(revealed), 2000);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/waits/waits.spec.js#L52)

##### /examples/javascript/test/waits/waits.spec.js

```js

const { By, Browser, until, Builder} = require('selenium-webdriver');
const assert = require("node:assert");


describe('Waits', function () {
    let driver;

    before(async function () {
        driver = new Builder()
          .forBrowser(Browser.CHROME)
          .build();
    });

    after(async () => await driver.quit());

    it('fail', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        await assert.rejects(async () => {
              await driver.findElement(By.id("box0"))
          },
          Error
        )
    });

    it('sleep', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        await driver.sleep(2000);
        let added = await driver.findElement(By.id("box0"));

        assert.equal(await added.getAttribute('class'), "redbox")
    });

    it('implicit', async function () {
        await driver.manage().setTimeouts({ implicit: 2000 });
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        await driver.findElement(By.id("adder")).click();

        let added = await driver.findElement(By.id("box0"));

        assert.equal(await added.getAttribute('class'), "redbox")
    });

    it('explicit', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/dynamic.html');
        let revealed = await driver.findElement(By.id("revealed"));
        await driver.findElement(By.id("reveal")).click();
        await driver.wait(until.elementIsVisible(revealed), 2000);
        await revealed.sendKeys("Displayed");
        assert.equal(await revealed.getAttribute("value"), "Displayed")
    })
});
```

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk/examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt#L36-L37)

##### examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt

```kt
```

### 定制

Wait 类可以通过各种参数进行实例化, 这些参数会改变条件的评估方式.

这可以包括：

* 更改代码的评估频率 (轮询间隔)
* 指定哪些异常应自动处理
* 更改总超时时长
* 自定义超时消息

例如, 如果默认情况下对 *元素不可交互* 错误进行重试, 那么我们可以在执行中的代码里的某个方法内添加一个操作 (我们只需要确保代码在成功时返回 `true` 即可)：

*
*
*
*
*
*

The easiest way to customize Waits in Java is to use the `FluentWait` class:

```java
    Wait<WebDriver> wait =
        new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(2))
            .pollingEvery(Duration.ofMillis(300))
            .ignoring(ElementNotInteractableException.class);

    wait.until(
        d -> {
          revealed.sendKeys("Displayed");
          return true;
        });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/waits/WaitsTest.java#L82-L92)

##### /examples/java/src/test/java/dev/selenium/waits/WaitsTest.java

```java
package dev.selenium.waits;

import dev.selenium.BaseTest;
import java.time.Duration;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.ElementNotInteractableException;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.FluentWait;
import org.openqa.selenium.support.ui.Wait;
import org.openqa.selenium.support.ui.WebDriverWait;

public class WaitsTest extends BaseTest {
  @Test
  public void fails() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Assertions.assertThrows(
        NoSuchElementException.class,
        () -> {
          driver.findElement(By.id("box0"));
        });
  }

  @Test
  public void sleep() throws InterruptedException {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    Thread.sleep(1000);

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void implicit() {
    startChromeDriver(new ChromeOptions());

    driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(2));
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    driver.findElement(By.id("adder")).click();

    WebElement added = driver.findElement(By.id("box0"));

    Assertions.assertEquals("redbox", added.getDomAttribute("class"));
  }

  @Test
  public void explicit() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(2));
    wait.until(d -> revealed.isDisplayed());

    revealed.sendKeys("Displayed");
    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }

  @Test
  public void explicitWithOptions() {
    startChromeDriver(new ChromeOptions());

    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    WebElement revealed = driver.findElement(By.id("revealed"));
    driver.findElement(By.id("reveal")).click();

    Wait<WebDriver> wait =
        new FluentWait<>(driver)
            .withTimeout(Duration.ofSeconds(2))
            .pollingEvery(Duration.ofMillis(300))
            .ignoring(ElementNotInteractableException.class);

    wait.until(
        d -> {
          revealed.sendKeys("Displayed");
          return true;
        });

    Assertions.assertEquals("Displayed", revealed.getDomProperty("value"));
  }
}
```

```py
    errors = [NoSuchElementException, ElementNotInteractableException]
    wait = WebDriverWait(driver, timeout=2, poll_frequency=.2, ignored_exceptions=errors)
    wait.until(lambda _ : revealed.send_keys("Displayed") or True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/waits/test_waits.py#L53-L55)

##### /examples/python/tests/waits/test\_waits.py

```py
import pytest
import time
from selenium.common import NoSuchElementException, ElementNotInteractableException
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


def test_fails(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    with pytest.raises(NoSuchElementException):
        driver.find_element(By.ID, 'box0')


def test_sleep(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    time.sleep(2)
    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_implicit(driver):
    driver.implicitly_wait(2)
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    driver.find_element(By.ID, "adder").click()

    added = driver.find_element(By.ID, "box0")

    assert added.get_dom_attribute('class') == "redbox"


def test_explicit(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(lambda _ : revealed.is_displayed())

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"


def test_explicit_options(driver):
    driver.get('https://www.selenium.dev/selenium/web/dynamic.html')
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    errors = [NoSuchElementException, ElementNotInteractableException]
    wait = WebDriverWait(driver, timeout=2, poll_frequency=.2, ignored_exceptions=errors)
    wait.until(lambda _ : revealed.send_keys("Displayed") or True)

    assert revealed.get_property("value") == "Displayed"
```

```cs
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2))
            {
                PollingInterval = TimeSpan.FromMilliseconds(300),
            };
            wait.IgnoreExceptionTypes(typeof(ElementNotInteractableException));

            wait.Until(d => {
                revealed.SendKeys("Displayed");
                return true;
            });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs#L70-L79)

##### /examples/dotnet/SeleniumDocs/Waits/WaitsTest.cs

```cs
using System;
using System.Threading;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Waits
{
    [TestClass]
    public class WaitsTest : BaseChromeTest
    {
        [TestMethod]
        public void Fails()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Assert.ThrowsException<NoSuchElementException>(
                () => driver.FindElement(By.Id("box0"))
            );
        }

        [TestMethod]
        public void Sleep()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            Thread.Sleep(1000);

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Implicit()
        {
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
            
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            driver.FindElement(By.Id("adder")).Click();

            IWebElement added = driver.FindElement(By.Id("box0"));

            Assert.AreEqual("redbox", added.GetDomAttribute("class"));
        }

        [TestMethod]
        public void Explicit()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2));
            wait.Until(d => revealed.Displayed);

            revealed.SendKeys("Displayed");
            Assert.AreEqual("Displayed", revealed.GetDomProperty("value"));
        }

        [TestMethod]
        public void ExplicitOptions()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            IWebElement revealed = driver.FindElement(By.Id("revealed"));
            driver.FindElement(By.Id("reveal")).Click();

            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(2))
            {
                PollingInterval = TimeSpan.FromMilliseconds(300),
            };
            wait.IgnoreExceptionTypes(typeof(ElementNotInteractableException));

            wait.Until(d => {
                revealed.SendKeys("Displayed");
                return true;
            });

            Assert.AreEqual("input", revealed.TagName);
        }
    }
}
```

```rb
    errors = [Selenium::WebDriver::Error::NoSuchElementError,
              Selenium::WebDriver::Error::ElementNotInteractableError]
    wait = Selenium::WebDriver::Wait.new(timeout: 2,
                                         interval: 0.3,
                                         ignore: errors)

    wait.until { revealed.send_keys('Displayed') || true }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/waits/waits_spec.rb#L54-L60)

##### /examples/ruby/spec/waits/waits\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Waits' do
  let(:driver) { start_session }

  it 'fails' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    expect {
      driver.find_element(id: 'box0')
    }.to raise_error(Selenium::WebDriver::Error::NoSuchElementError)
  end

  it 'sleeps' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    sleep 1
    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'implicit' do
    driver.manage.timeouts.implicit_wait = 2
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    driver.find_element(id: 'adder').click

    added = driver.find_element(id: 'box0')

    expect(added.dom_attribute(:class)).to eq('redbox')
  end

  it 'explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    wait = Selenium::WebDriver::Wait.new
    wait.until { revealed.displayed? }

    revealed.send_keys('Displayed')
    expect(revealed.property(:value)).to eq('Displayed')
  end

  it 'options with explicit' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'
    revealed = driver.find_element(id: 'revealed')
    driver.find_element(id: 'reveal').click

    errors = [Selenium::WebDriver::Error::NoSuchElementError,
              Selenium::WebDriver::Error::ElementNotInteractableError]
    wait = Selenium::WebDriver::Wait.new(timeout: 2,
                                         interval: 0.3,
                                         ignore: errors)

    wait.until { revealed.send_keys('Displayed') || true }

    expect(revealed.property(:value)).to eq('Displayed')
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk/examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt#L51-L60)

##### examples/kotlin/src/test/kotlin/dev/selenium/waits/WaitsTest.kt

```kt
```

最后修改 October 31, 2025: [Added Kotlin Code Examples (#2499) (e49b07e4f68)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e49b07e4f68275d61faff820b9b2b640e9d16fb3)

----
url: https://www.selenium.dev/zh-cn/documentation/grid/advanced_features/graphql_support/
----

# GraphQL查询支持

```shell
{
    session(id: "<session-id>") : {
        id,
        capabilities,
        startTime,
        uri,
        nodeId,
        nodeUri,
        sessionDurationMillis
        slot : {
            id,
            stereotype,
            lastStarted
        }
    }
    grid: {
        uri,
        totalSlots,
        nodeCount,
        maxSession,
        sessionCount,
        version,
        sessionQueueSize
    }
    sessionsInfo: {
        sessionQueueRequests,
        sessions: [
            {
                id,
                capabilities,
                startTime,
                uri,
                nodeId,
                nodeUri,
                sessionDurationMillis
                slot : {
                    id,
                    stereotype,
                    lastStarted
                }
            }
        ]
    }
    nodesInfo: {
        nodes : [
            {
                id,
                uri,
                status,
                maxSession,
                slotCount,
                sessions: [
                    {
                        id,
                        capabilities,
                        startTime,
                        uri,
                        nodeId,
                        nodeUri,
                        sessionDurationMillis
                        slot : {
                            id,
                            stereotype,
                            lastStarted
                        }
                    }
                ],
                sessionCount,
                stereotypes,
                version,
                osInfo: {
                    arch,
                    name,
                    version
                }
            }
        ]
    }
}
```

## 查询 GraphQL

查询GraphQL的最佳方法是使用`curl`请求. GraphQL允许您仅获取所需的数据, 仅此而已.

下面给出了一些GraphQL查询的示例. 您可以根据需要构建自己的查询.

### 查询网格中 `maxSession` 和 `sessionCount` 的数量:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ grid { maxSession, sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

通常在本地机器上 `<LINK_TO_GRAPHQL_ENDPOINT>` 会是 `http://localhost:4444/graphql`

### 查询全部会话、及节点以及网格的详情 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { uri, maxSession, sessionCount }, nodesInfo { nodes { id, uri, status, sessions { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } }, slotCount, sessionCount }} }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询以获取当前网格的会话总数 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询以获取网格中的最大会话数量 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { maxSession } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询以获取网格中所有节点的全部会话详情 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, capabilities, startTime, uri, nodeId, nodeId, sessionDurationMillis } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询以获取网格中每个节点中所有会话的插槽信息 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, slot { id, stereotype, lastStarted } } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询以获取给定会话的会话信息查询以获取给定会话的会话信息 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ session (id: \"<session-id>\") { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } } } "}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询网格中每个节点的功能 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { stereotypes } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询网格中每个节点的状态 :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { status } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 查询每个节点和网格的 URI :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { uri } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the current requests in the New Session Queue:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessionQueueRequests } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the New Session Queue size :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionQueueSize } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

最后修改 January 24, 2022: [Properly parse quotes for GraphQl query's session id (#941) \[deploy site\] (548fa83a491)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/548fa83a491330341485e5667d5053743f8e313c)

----
url: https://www.selenium.dev/ja/documentation/legacy/selenium_1/
----

# Selenium RC (Selenium 1)

```shell
    java -jar selenium-server-standalone-<version-number>.jar
```

これは、上記のコマンドを含むバッチまたはシェル実行可能ファイル（Windowsでは.bat、Linuxでは.sh）を作成することで簡素化できます。 次に、デスクトップ上でその実行可能ファイルへのショートカットを作成し、アイコンをダブルクリックしてサーバーを起動します。

サーバーを実行するには、Javaをインストールし、PATH環境変数をコンソールから実行するように正しく構成する必要があります。 コンソールで次を実行すると、Javaが正しくインストールされていることを確認できます。

```shell
       java -version
```

|                   |                            |             |
| ----------------- | -------------------------- | ----------- |
| open              | /                          |             |
| type              | q                          | selenium rc |
| clickAndWait      | btnG                       |             |
| assertTextPresent | Results \* for selenium rc |             |

注：この例は、Google検索ページ <http://www.google.com> で機能します。

### プログラミングコードとしてのSelenese

サポートされている各プログラミング言語に(Selenium-IDE経由で)エクスポートされたテストスクリプトを次に示します。 オブジェクト指向プログラミング言語の少なくとも基本的な知識がある場合は、これらの例のいずれかを読むことで、SeleniumがSeleneseコマンドを実行する方法を理解できます。 特定の言語の例を表示するには、これらのボタンのいずれかを選択します。

#### CSharp

```csharp

        using System;
        using System.Text;
        using System.Text.RegularExpressions;
        using System.Threading;
        using NUnit.Framework;
        using Selenium;

        namespace SeleniumTests
        {
            [TestFixture]
            public class NewTest
            {
                private ISelenium selenium;
                private StringBuilder verificationErrors;
                
                [SetUp]
                public void SetupTest()
                {
                    selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
                    selenium.Start();
                    verificationErrors = new StringBuilder();
                }
                
                [TearDown]
                public void TeardownTest()
                {
                    try
                    {
                        selenium.Stop();
                    }
                    catch (Exception)
                    {
                        // Ignore errors if unable to close the browser
                    }
                    Assert.AreEqual("", verificationErrors.ToString());
                }
                
                [Test]
                public void TheNewTest()
                {
                    selenium.Open("/");
                    selenium.Type("q", "selenium rc");
                    selenium.Click("btnG");
                    selenium.WaitForPageToLoad("30000");
                    Assert.AreEqual("selenium rc - Google Search", selenium.GetTitle());
                }
            }
        }
```

#### Java

```java
      
	  /** Add JUnit framework to your classpath if not already there 
	   *  for this example to work
	  */
      package com.example.tests;

      import com.thoughtworks.selenium.*;
      import java.util.regex.Pattern;

      public class NewTest extends SeleneseTestCase {
          public void setUp() throws Exception {
              setUp("http://www.google.com/", "*firefox");
          }
            public void testNew() throws Exception {
                selenium.open("/");
                selenium.type("q", "selenium rc");
                selenium.click("btnG");
                selenium.waitForPageToLoad("30000");
                assertTrue(selenium.isTextPresent("Results * for selenium rc"));
          }
      }
```

#### Php

```php
      <?php

      require_once 'PHPUnit/Extensions/SeleniumTestCase.php';

      class Example extends PHPUnit_Extensions_SeleniumTestCase
      {
        function setUp()
        {
          $this->setBrowser("*firefox");
          $this->setBrowserUrl("http://www.google.com/");
        }

        function testMyTestCase()
        {
          $this->open("/");
          $this->type("q", "selenium rc");
          $this->click("btnG");
          $this->waitForPageToLoad("30000");
          $this->assertTrue($this->isTextPresent("Results * for selenium rc"));
        }
      }
      ?>
```

#### Python

```python

     from selenium import selenium
      import unittest, time, re

      class NewTest(unittest.TestCase):
          def setUp(self):
              self.verificationErrors = []
              self.selenium = selenium("localhost", 4444, "*firefox",
                      "http://www.google.com/")
              self.selenium.start()
         
          def test_new(self):
              sel = self.selenium
              sel.open("/")
              sel.type("q", "selenium rc")
              sel.click("btnG")
              sel.wait_for_page_to_load("30000")
              self.failUnless(sel.is_text_present("Results * for selenium rc"))
         
          def tearDown(self):
              self.selenium.stop()
              self.assertEqual([], self.verificationErrors)
```

#### Ruby

```ruby

      require "selenium/client"
      require "test/unit"

      class NewTest < Test::Unit::TestCase
        def setup
          @verification_errors = []
          if $selenium
            @selenium = $selenium
          else
            @selenium =  Selenium::Client::Driver.new("localhost", 4444, "*firefox", "http://www.google.com/", 60);
            @selenium.start
          end
          @selenium.set_context("test_new")
        end

        def teardown
          @selenium.stop unless $selenium
          assert_equal [], @verification_errors
        end

        def test_new
          @selenium.open "/"
          @selenium.type "q", "selenium rc"
          @selenium.click "btnG"
          @selenium.wait_for_page_to_load "30000"
          assert @selenium.is_text_present("Results * for selenium rc")
        end
      end
```

```java
    selenium = new DefaultSelenium("localhost", 4444, "*iehta", "http://www.google.com/");
```

Selenium-IDEで生成されたコードは次のようになります。 この例では、わかりやすくするためにコメントを手動で追加しています。

```java
   package com.example.tests;
   // We specify the package of our tests

   import com.thoughtworks.selenium.*;
   // This is the driver's import. You'll use this for instantiating a
   // browser and making it do what you need.

   import java.util.regex.Pattern;
   // Selenium-IDE add the Pattern module because it's sometimes used for 
   // regex validations. You can remove the module if it's not used in your 
   // script.

   public class NewTest extends SeleneseTestCase {
   // We create our Selenium test case

         public void setUp() throws Exception {
           setUp("http://www.google.com/", "*firefox");
                // We instantiate and start the browser
         }

         public void testNew() throws Exception {
              selenium.open("/");
              selenium.type("q", "selenium rc");
              selenium.click("btnG");
              selenium.waitForPageToLoad("30000");
              assertTrue(selenium.isTextPresent("Results * for selenium rc"));
              // These are the real test steps
        }
   }
```

### `C#`

.NETクライアントドライバーはMicrosoft.NETで動作します。 NUnitやVisual Studio 2005 Team Systemなどの.NETテストフレームワークで利用できます。

Selenium-IDEは、テストフレームワークとしてNUnitを使用することを想定しています。 以下の生成コードでこれを確認できます。 NUnitの *using* ステートメントと、テストクラスの各メンバー関数の役割を識別する対応するNUnit属性が含まれています。

おそらく、テストクラスの名前を"NewTest"から独自の選択に変更する必要があります。 また、ステートメントのブラウザで開くパラメーターを変更する必要があります。

```csharp
    selenium = new DefaultSelenium("localhost", 4444, "*iehta", "http://www.google.com/");
```

生成されたコードは次のようになります。

```csharp

    using System;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading;
    using NUnit.Framework;
    using Selenium;
    
    namespace SeleniumTests

    {
        [TestFixture]

        public class NewTest

        {
        private ISelenium selenium;

        private StringBuilder verificationErrors;

        [SetUp]

        public void SetupTest()

        {
            selenium = new DefaultSelenium("localhost", 4444, "*iehta",
            "http://www.google.com/");

            selenium.Start();

            verificationErrors = new StringBuilder();
        }

        [TearDown]

        public void TeardownTest()
        {
            try
            {
            selenium.Stop();
            }

            catch (Exception)
            {
            // Ignore errors if unable to close the browser
            }

            Assert.AreEqual("", verificationErrors.ToString());
        }
        [Test]

        public void TheNewTest()
        {
            // Open Google search engine.        
            selenium.Open("http://www.google.com/"); 
            
            // Assert Title of page.
            Assert.AreEqual("Google", selenium.GetTitle());
            
            // Provide search term as "Selenium OpenQA"
            selenium.Type("q", "Selenium OpenQA");
            
            // Read the keyed search term and assert it.
            Assert.AreEqual("Selenium OpenQA", selenium.GetValue("q"));
            
            // Click on Search button.
            selenium.Click("btnG");
            
            // Wait for page to load.
            selenium.WaitForPageToLoad("5000");
            
            // Assert that "www.openqa.org" is available in search results.
            Assert.IsTrue(selenium.IsTextPresent("www.openqa.org"));
            
            // Assert that page title is - "Selenium OpenQA - Google Search"
            Assert.AreEqual("Selenium OpenQA - Google Search", 
                         selenium.GetTitle());
        }
        }
    }
```

NUnitにテストの実行を管理させることができます。 または、テストオブジェクトをインスタンス化し、`SetupTest()`、`TheNewTest()`、`TeardownTest()` の各メソッドを順番に実行する単純な `main()` プログラムを作成することもできます。

### Python

Pyunitは、Pythonで使用するテストフレームワークです。

基本的なテスト構造は次のとおりです。

```python

   from selenium import selenium
   # This is the driver's import.  You'll use this class for instantiating a
   # browser and making it do what you need.

   import unittest, time, re
   # This are the basic imports added by Selenium-IDE by default.
   # You can remove the modules if they are not used in your script.

   class NewTest(unittest.TestCase):
   # We create our unittest test case

       def setUp(self):
           self.verificationErrors = []
           # This is an empty array where we will store any verification errors
           # we find in our tests

           self.selenium = selenium("localhost", 4444, "*firefox",
                   "http://www.google.com/")
           self.selenium.start()
           # We instantiate and start the browser

       def test_new(self):
           # This is the test code.  Here you should put the actions you need
           # the browser to do during your test.
            
           sel = self.selenium
           # We assign the browser to the variable "sel" (just to save us from 
           # typing "self.selenium" each time we want to call the browser).
            
           sel.open("/")
           sel.type("q", "selenium rc")
           sel.click("btnG")
           sel.wait_for_page_to_load("30000")
           self.failUnless(sel.is_text_present("Results * for selenium rc"))
           # These are the real test steps

       def tearDown(self):
           self.selenium.stop()
           # we close the browser (I'd recommend you to comment this line while
           # you are creating and debugging your tests)

           self.assertEqual([], self.verificationErrors)
           # And make the test fail if we found that any verification errors
           # were found
```

### Ruby

Selenium-IDEの古い（2.0より前の）バージョンは、古いSelenium gemを必要とするRubyコードを生成します。 したがって、IDEによって生成されたRubyスクリプトを次のように更新することをお勧めします。

1. １行目を `require "selenium"` から `require "selenium/client"` に変更

2. 11行目を `Selenium::SeleniumDriver.new` から `Selenium::Client::Driver.new` に変更

クラス名を"Untitled"よりもわかりやすい名前に変更し、テストメソッドの名前を"test\_untitled"以外の名前に変更することもできます。

上記のように、Selenium IDEによって生成されたRubyコードを変更して作成された簡単な例を次に示します。

```ruby

   # load the Selenium-Client gem
   require "selenium/client"

   # Load Test::Unit, Ruby's default test framework.
   # If you prefer RSpec, see the examples in the Selenium-Client
   # documentation.
   require "test/unit"

   class Untitled < Test::Unit::TestCase

     # The setup method is called before each test.
     def setup

       # This array is used to capture errors and display them at the
       # end of the test run.
       @verification_errors = []

       # Create a new instance of the Selenium-Client driver.
       @selenium = Selenium::Client::Driver.new \
         :host => "localhost",
         :port => 4444,
         :browser => "*chrome",
         :url => "http://www.google.com/",
         :timeout_in_second => 60

       # Start the browser session
       @selenium.start

       # Print a message in the browser-side log and status bar
       # (optional).
       @selenium.set_context("test_untitled")

     end

     # The teardown method is called after each test.
     def teardown

       # Stop the browser session.
       @selenium.stop

       # Print the array of error messages, if any.
       assert_equal [], @verification_errors
     end

     # This is the main body of your test.
     def test_untitled
     
       # Open the root of the site we specified when we created the
       # new driver instance, above.
       @selenium.open "/"

       # Type 'selenium rc' into the field named 'q'
       @selenium.type "q", "selenium rc"

       # Click the button named "btnG"
       @selenium.click "btnG"

       # Wait for the search results page to load.
       # Note that we don't need to set a timeout here, because that
       # was specified when we created the new driver instance, above.
       @selenium.wait_for_page_to_load

       begin

          # Test whether the search results contain the expected text.
	  # Notice that the star (*) is a wildcard that matches any
	  # number of characters.
	  assert @selenium.is_text_present("Results * for selenium rc")
	  
       rescue Test::Unit::AssertionFailedError
       
          # If the assertion fails, push it onto the array of errors.
	  @verification_errors << $!

       end
     end
   end
```

### Perl, PHP

ドキュメントチームのメンバーは、PerlまたはPHPでSelenium RCを使用していません。 これらの2つの言語のいずれかでSelenium RCを使用している場合は、ドキュメントチームに連絡してください（貢献に関する章を参照）。 PerlおよびPHPユーザーをサポートするために、あなたとあなたの経験からいくつかの例を含めたいと思います。

## APIを学ぶ

Selenium RC APIは、Seleneseを理解していると仮定すると、インターフェイスのほとんどが自明である命名規則を使用します。 ただし、ここでは、最も重要で、おそらくそれほど明白ではない側面について説明します。

### ブラウザーを起動する

#### CSharp

```csharp
      selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
      selenium.Start();
```

#### Java

```java

      setUp("http://www.google.com/", "*firefox");
```

#### Perl

```perl
      my $sel = Test::WWW::Selenium->new( host => "localhost", 
                                          port => 4444, 
                                          browser => "*firefox", 
                                          browser_url => "http://www.google.com/" );
```

#### Php

```php
      $this->setBrowser("*firefox");
      $this->setBrowserUrl("http://www.google.com/");
```

#### Python

```python
      self.selenium = selenium("localhost", 4444, "*firefox",
                               "http://www.google.com/")
      self.selenium.start()
```

#### Ruby

```ruby
      @selenium = Selenium::ClientDriver.new("localhost", 4444, "*firefox", "http://www.google.com/", 10000);
      @selenium.start
```

```
    selenium.type("field-id","string to type")
```

|                   |                              |               |
| ----------------- | ---------------------------- | ------------- |
| open              | /                            |               |
| type              | q                            | selenium rc   |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium rc   |               |
| type              | q                            | selenium ide  |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium ide  |               |
| type              | q                            | selenium grid |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium grid |               |

同じ手順を3回実行するためにコードが繰り返されています。 ただし、同じコードのコピーを複数作成することは、維持する作業が増えるため、プログラムとしては適切ではありません。 プログラミング言語を使用することで、検索結果を反復処理して、より柔軟で保守可能なソリューションを実現できます。

#### `C#` の場合

```csharp
   // Collection of String values.
   String[] arr = {"ide", "rc", "grid"};    
        
   // Execute loop for each String in array 'arr'.
   foreach (String s in arr) {
       sel.open("/");
       sel.type("q", "selenium " +s);
       sel.click("btnG");
       sel.waitForPageToLoad("30000");
       assertTrue("Expected text: " +s+ " is missing on page."
       , sel.isTextPresent("Results * for selenium " + s));
    }
```

### 条件ステートメント

テストでの条件の使用を説明するために、例から始めます。 Seleniumテストの実行中に発生する一般的な問題は、ページで予期される要素が利用できない場合に発生します。 たとえば、次の行を実行する場合です。

```
   selenium.type("q", "selenium " +s);
```

要素 ‘q’がページにない場合、例外がスローされます。

```java
   com.thoughtworks.selenium.SeleniumException: ERROR: Element q not found
```

これにより、テストが中断する可能性があります。 いくつかのテストでは、それがあなたの望むものです。 しかし、多くの場合、テストスクリプトには実行する他の多くのテストがあるため、これは望ましくありません。

より良いアプローチは、まず要素が実際に存在するかどうかを検証し、次に存在しない場合に代替手段を取ることです。 Javaを使用してこれを見てみましょう。

```java
   // If element is available on page then perform type operation.
   if(selenium.isElementPresent("q")) {
       selenium.type("q", "Selenium rc");
   } else {
       System.out.printf("Element: " +q+ " is not available on page.")
   }
```

このアプローチの利点は、ページで一部のUI要素が利用できない場合でも、テストの実行を続行できることです。

### テストからJavaScriptを実行する

JavaScriptは、セレンによって直接サポートされていないアプリケーションを実行する際に非常に便利です。 Selenium APIの **getEval** メソッドを使用して、Selenium RCからJavaScriptを実行できます。

静的な識別子のないチェックボックスを持つアプリケーションを考えてください。 この場合、Selenium RCからJavaScriptを評価して、すべてのチェックボックスのIDを取得し、それらを実行できます。

```java
   public static String[] getAllCheckboxIds () { 
		String script = "var inputId  = new Array();";// Create array in java script.
		script += "var cnt = 0;"; // Counter for check box ids.  
		script += "var inputFields  = new Array();"; // Create array in java script.
		script += "inputFields = window.document.getElementsByTagName('input');"; // Collect input elements.
		script += "for(var i=0; i<inputFields.length; i++) {"; // Loop through the collected elements.
		script += "if(inputFields[i].id !=null " +
		"&& inputFields[i].id !='undefined' " +
		"&& inputFields[i].getAttribute('type') == 'checkbox') {"; // If input field is of type check box and input id is not null.
		script += "inputId[cnt]=inputFields[i].id ;" + // Save check box id to inputId array.
		"cnt++;" + // increment the counter.
		"}" + // end of if.
		"}"; // end of for.
		script += "inputId.toString();" ;// Convert array in to string.			
		String[] checkboxIds = selenium.getEval(script).split(","); // Split the string.
		return checkboxIds;
    }
```

ページ上の画像の数を数えるには、以下のとおりです。

```java
   selenium.getEval("window.document.images.length;");
```

デフォルトでは、テストウィンドウではなくSeleniumウィンドウが参照されるため、DOM式の場合は必ずウィンドウオブジェクトを使用してください。

## サーバーオプション

サーバーの起動時に、コマンドラインオプションを使用してデフォルトのサーバーの動作を変更できます。

サーバーを起動するには、次を実行してください。

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar
```

オプションのリストを表示するには、 `-h` オプションを指定してサーバーを実行します。

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar -h
```

サーバーで使用できるすべてのオプションのリストとそれぞれの簡単な説明が表示されます。 提供された説明では必ずしも十分ではないため、いくつかのより重要なオプションについて説明しました。

### プロキシ設定

AUTが認証を必要とするHTTPプロキシの後ろにある場合、次のコマンドを使用してhttp.proxyHost、http.proxyPort、http.proxyUserおよびhttp.proxyPasswordを設定する必要があります。

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar -Dhttp.proxyHost=proxy.com -Dhttp.proxyPort=8080 -Dhttp.proxyUser=username -Dhttp.proxyPassword=password
```

### マルチウィンドウモード

Selenium 1.0を使用している場合は、マルチウィンドウモードがデフォルトの動作であるため、おそらくこのセクションをスキップできます。 ただし、バージョン1.0より前は、Seleniumはデフォルトで、ここに示すようにサブフレームでテスト対象のアプリケーションを実行していました。

一部のアプリケーションはサブフレームで正しく実行されず、ウィンドウの上部フレームにロードする必要がありました。 マルチウィンドウモードオプションにより、AUTはデフォルトフレームではなく別のウィンドウで実行でき、そこで必要なトップフレームを取得できました。

Seleniumの古いバージョンでは、次のオプションで明示的にマルチウィンドウモードを指定する必要があります。

```bash
   -multiwindow 
```

Selenium RC 1.0の時点で、単一のフレーム内でテストを実行する場合（つまり、以前のSeleniumバージョンの標準を使用する場合）、オプションを使用してこれをSelenium Serverに指定できます。

```bash
   -singlewindow 
```

### Firefoxプロファイルの指定

Firefoxは、インスタンスごとに個別のプロファイルを指定しない限り、2つのインスタンスを同時に実行しません。 Selenium RC 1.0以降は個別のプロファイルで自動的に実行されるため、Selenium 1.0を使用している場合は、このセクションをスキップできます。 ただし、Seleniumの古いバージョンを使用している場合、またはテストに特定のプロファイルを使用する必要がある場合（https証明書の追加やアドオンのインストールなど）、プロファイルを明示的に指定する必要があります。

最初に、別のFirefoxプロファイルを作成するには、次の手順に従います。 Windowsのスタートメニューを開き、“実行"を選択して、次のいずれかを入力します。

```bash
   firefox.exe -profilemanager 
```

```bash
   firefox.exe -P 
```

ダイアログを使用して新しいプロファイルを作成します。 次に、Seleniumサーバーを実行するときに、サーバーのコマンドラインオプション *-firefoxProfileTemplate* でこの新しいFirefoxプロファイルを使用し、ファイル名とディレクトリパスを使用してプロファイルへのパスを指定するように指示します。

```bash
   -firefoxProfileTemplate "path to the profile" 
```

**警告**: 必ずデフォルトとは別の新しいフォルダーにプロファイルを入れてください!!! Firefoxプロファイルマネージャーツールは、プロファイルを削除すると、プロファイルファイルであるかどうかに関係なく、フォルダー内のすべてのファイルを削除します。

Firefoxプロファイルの詳細については、[Mozillaのナレッジベース](http://support.mozilla.com/en/kb/Managing+profiles)をご覧ください。

### -htmlSuiteを使用してサーバー内でSeleneseを直接実行する

HTMLファイルをサーバーのコマンドラインに渡すことで、Selenese HTMLファイルをSelenium Server内で直接実行できます。 例えば、

```bash
   java -jar selenium-server-standalone-<version-number>.jar -htmlSuite "*firefox" 
   "http://www.google.com" "c:\absolute\path\to\my\HTMLSuite.html" 
   "c:\absolute\path\to\my\results.html"
```

これにより、HTMLスイートが自動的に起動され、すべてのテストが実行され、結果とともにHTMLレポートが保存されます。

*注意:* このオプションを使用すると、サーバーはテストを開始し、テストが完了するまで指定された秒数待機します。 その時間内にテストが完了しない場合、コマンドはゼロ以外の終了コードで終了し、結果ファイルは生成されません。

このコマンドラインは非常に長いため、入力するときは注意してください。 これには、単一のテストではなく、HTML Seleneseスイートを渡す必要があることに注意してください。 また、 -htmlSuite オプションは`-interactive`と互換性がないことに注意してください。 両方を同時に実行することはできません。

### Seleniumサーバーのログ

#### サーバー側のログ

Seleniumサーバーを起動するときに、 **-log** オプションを使用して、Seleniumサーバーによってレポートされた貴重なデバッグ情報をテキストファイルに記録できます。

```bash
   java -jar selenium-server-standalone-<version-number>.jar -log selenium.log
```

このログファイルは、標準のコンソールログよりも詳細です（DEBUGレベルのログメッセージが含まれます）。 ログファイルには、ロガー名、およびメッセージを記録したスレッドのID番号も含まれます。 例えば、

```bash
   20:44:25 DEBUG [12] org.openqa.selenium.server.SeleniumDriverResourceHandler - 
   Browser 465828/:top frame1 posted START NEW
```

メッセージの形式は、以下のとおりです。

```bash
   TIMESTAMP(HH:mm:ss) LEVEL [THREAD] LOGGER - MESSAGE
```

このメッセージは複数行の場合があります。

#### ブラウザ側のログ

ブラウザ側のJavaScript（Selenium Core）も重要なメッセージを記録します。 多くの場合、これらは通常のSeleniumサーバーログよりもエンドユーザーにとって有用です。 ブラウザ側のログにアクセスするには、 **-browserSideLog** 引数をSeleniumサーバーに渡します。

```bash
   java -jar selenium-server-standalone-<version-number>.jar -browserSideLog
```

**-browserSideLog** を **-log** 引数と組み合わせて、browserSideLogs（および他のすべてのDEBUGレベルのログメッセージ）をファイルに記録する必要があります。

## 特定のブラウザへのパスを指定する

特定のブラウザーへのパスをSelenium RCに指定できます。 これは、同じブラウザーの異なるバージョンがあり、特定のブラウザーを使用する場合に便利です。 また、これは、Selenium RCで直接サポートされていないブラウザーに対してテストを実行できるようにするために使用されます。 実行モードを指定するときは、ブラウザの実行可能ファイルへのフルパスが後に続く \*custom 指定子を使用します。

```bash
   *custom <path to browser> 
```

```bash
   cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\MyBrowser.exe&2=http://www.google.com
```

### 異なるブラウザー設定でテストを実行する

通常、Selenium RCはブラウザーを自動的に設定しますが、”\*custom" 実行モードを使用してブラウザーを起動する場合、自動設定を使用せずにSelenium RCにブラウザーをそのまま強制的に起動させることができます。

たとえば、次のようなカスタム設定でFirefoxを起動できます。

```bash
   cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\firefox.exe&2=http://www.google.com
```

この方法でブラウザーを起動する場合、Selenium Serverをプロキシとして使用するようにブラウザーを手動で設定する必要があることに注意してください。 通常、これはブラウザーの設定を開き、“localhost:4444"をHTTPプロキシとして指定することを意味しますが、この手順はブラウザーごとに根本的に異なる場合があります。 詳細については、ブラウザーのドキュメントを参照してください。

Mozillaブラウザは、起動と停止の方法が異なる場合があることに注意してください。 Mozillaブラウザの動作をもう少し予測可能にするために、MOZ\_NO\_REMOTE環境変数を設定する必要があるかもしれません。 Unixユーザーは、シェルスクリプトを使用してブラウザを起動しないでください。 一般に、バイナリ実行可能ファイル（firefox-binなど）を直接使用することをお勧めします。

## 一般的な問題のトラブルシューティング

Selenium RCの使用を開始すると、一般的に発生する可能性のある問題がいくつかあります。 ここでそれらとその解決策を紹介します。

### サーバーに接続できません

テストプログラムがSeleniumサーバーに接続できない場合、Seleniumはテストプログラムで例外をスローします。 このメッセージまたは同様のメッセージが表示されるはずです。

```bash
    "Unable to connect to remote server (Inner Exception Message: 
	No connection could be made because the target machine actively 
	refused it )"
    
	(using .NET and XP Service Pack 2) 
```

このようなメッセージが表示された場合は、必ずSeleniumサーバーを起動してください。 その場合、SeleniumクライアントライブラリとSeleniumサーバー間の接続に問題があります。

Selenium RCを使用する場合、ほとんどの人は、同じマシンでテストプログラム（Seleniumクライアントライブラリを使用）とSeleniumサーバーを実行することから始めます。 これを行うには、接続パラメーターとして"localhost"を使用します。 開始する潜在的なネットワークの問題の影響を軽減するため、この方法で開始することをお勧めします。 オペレーティングシステムに一般的なネットワーク設定とTCP/IP設定があると仮定すると、ほとんど問題はありません。 実際、多くの人がこの方法でテストを実行することを選択します。

ただし、リモートマシンでSeleniumサーバーを実行する場合は、2台のマシン間に有効なTCP/IP接続があると仮定すると、接続は良好です。

接続に問題がある場合は、 *ping* 、*telnet* 、 *ifconfig(Unix)/ipconfig(Windows)* などの一般的なネットワークツールを使用して、有効なネットワーク接続を確保できます。 これらに不慣れな場合は、システム管理者が支援できます。

### ブラウザをロードできません

わかりやすいエラーメッセージではありません。 申し訳ありませんが、Seleniumサーバーがブラウザをロードできない場合、このエラーが表示される可能性があります。

```bash
    (500) Internal Server Error
```

```bash
    Error:  java.lang.RuntimeException: Firefox refused shutdown while 
    preparing a profile 
```

サーバーからの完全なエラーメッセージを次に示します。

```bash
    16:20:03.919 INFO - Preparing Firefox profile... 
    16:20:27.822 WARN - GET /selenium-server/driver/?cmd=getNewBrowserSession&1=*fir 
    efox&2=http%3a%2f%2fsage-webapp1.qa.idc.com HTTP/1.1 
    java.lang.RuntimeException: Firefox refused shutdown while preparing a profile 
            at org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLaunc 
    her.waitForFullProfileToBeCreated(FirefoxCustomProfileLauncher.java:277) 
    ... 
    Caused by: org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLaunc 
    her$FileLockRemainedException: Lock file still present! C:\DOCUME~1\jsvec\LOCALS 
    ~1\Temp\customProfileDir203138\parent.lock 
```

これを解決するには、個別のFirefoxプロファイルの指定に関するセクションを参照してください。

### バージョン管理の問題

Seleniumのバージョンがブラウザのバージョンをサポートしていることを確認してください。 たとえば、Selenium RC 0.92はFirefox 3をサポートしていません。 時には幸運かもしれません（私はそうでした）。 ただし、使用しているSeleniumのバージョンでサポートされているブラウザのバージョンを確認することを忘れないでください。 疑わしい場合は、ブラウザの最も広く使用されているバージョンでSeleniumの最新リリースバージョンを使用してください。

### サーバーの起動中のエラーメッセージ： “(Unsupported major.minor version 49.0)”

このエラーは、正しいバージョンのJavaを使用していないことを示しています。 Selenium ServerにはJava 1.5以降が必要です。

Javaバージョンを再確認するには、コマンドラインからこれを実行します。

```bash
   java -version
```

Javaバージョンを示すメッセージが表示されます。

```bash
   java version "1.5.0_07"
   Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03)
   Java HotSpot(TM) Client VM (build 1.5.0_07-b03, mixed mode)
```

```bash
   cmd=getNewBrowserSession&1=*firefox /usr/local/firefox/firefox-bin&2=http://www.google.com
```

```bash
   /usr/lib/firefox-x.x.x/ 
```

x.x.xは現在使用しているバージョン番号です。 そのため、そのパスをユーザーのパスに追加します。 以下を.bashrcファイルに追加する必要があります。

```bash
   export PATH="$PATH:/usr/lib/firefox-x.x.x/"
```

必要に応じて、次のようにテストで直接firefox-binへのパスを指定できます。

```bash
   "*firefox /usr/lib/firefox-x.x.x/firefox-bin"
```

### IEおよびスタイル属性

Internet Explorerでテストを実行していて、style属性を使用して要素を見つけられない場合、例えば、次のような場合があります。

```bash
    //td[@style="background-color:yellow"]
```

これはFirefox、Opera、またはSafariで完全に機能しますが、IEでは機能しません。 IEは `@style` のキーを大文字として解釈します。 したがって、ソースコードが小文字であっても、下記のように使用したほうがよいです。

```bash
    //td[@style="BACKGROUND-COLOR:yellow"]
```

テストが複数のブラウザーで動作することを意図している場合、これは問題ですが、簡単にテストをコーディングして状況を検出し、IEでのみ動作する代替ロケーターを試すことができます。

### エラーが発生しました-\*googlechromeブラウザーのシャットダウン時に"Cannot convert object to primitive value”

このエラーを回避するには、同一オリジンポリシーチェックを無効にするオプションでブラウザを起動する必要があります。

```bash
   selenium.start("commandLineFlags=--disable-web-security");
```

### IEでエラーが発生しました - “Couldn’t open app window; is the pop-up blocker enabled?”

このエラーを回避するには、ブラウザを設定する必要があります。 ポップアップブロッカーを無効にし、ツール » オプション »セキュリティで’保護モードを有効にする’オプションをオフにします。

***

1. ブラウザーは、 localhost:4444 をHTTPプロキシーとして設定した構成プロファイルで起動されます。 これが、ブラウザーが行うHTTP要求がSeleniumサーバーを通過し、レスポンスが実サーバーからではなく通過する理由です。 [↩︎](#fnref:1)

2. プロキシは、2つの部分の間でボールを渡す中間の第三者です。 AUTをブラウザに配信する"Webサーバー"として機能します。 プロキシであるため、Seleniumサーバーはテスト対象アプリケーションの実際のURLについて"嘘をつく"機能を提供します。 [↩︎](#fnref:2)

----
url: https://www.selenium.dev/documentation/webdriver/
----

# WebDriver

WebDriver drives a browser natively; learn more about it.

WebDriver drives a browser natively, as a user would, either locally or on a remote machine using the Selenium server. It marks a leap forward in terms of browser automation.

Selenium WebDriver refers to both the language bindings and the implementations of the individual browser controlling code. This is commonly referred to as just *WebDriver*.

Selenium WebDriver is a [W3C Recommendation](https://www.w3.org/TR/webdriver1/)

* WebDriver is designed as a simple and more concise programming interface.

* WebDriver is a compact object-oriented API.

* It drives the browser effectively.

***

##### [Getting started](/documentation/webdriver/getting_started/)

If you are new to Selenium, we have a few resources that can help you get up to speed right away.

##### [Driver Sessions](/documentation/webdriver/drivers/)

##### [Supported Browsers](/documentation/webdriver/browsers/)

##### [Waiting Strategies](/documentation/webdriver/waits/)

##### [Web elements](/documentation/webdriver/elements/)

Identifying and working with element objects in the DOM.

##### [Browser interactions](/documentation/webdriver/interactions/)

##### [Actions API](/documentation/webdriver/actions_api/)

A low-level interface for providing virtualized device input actions to the web browser.

##### [BiDirectional functionality](/documentation/webdriver/bidi/)

##### [Support features](/documentation/webdriver/support_features/)

Support classes provide optional higher level features.

##### [Troubleshooting Assistance](/documentation/webdriver/troubleshooting/)

How to solve WebDriver problems.

----
url: https://www.selenium.dev/ja/documentation/webdriver/bidi/script/
----

# WebDriver BiDi Script Features

These features are related to scripts, and are made available via a “script” namespace.

The implementation of these features is being tracked here: [#13992](https://github.com/SeleniumHQ/selenium/issues/13992)

Remember that to use WebDriver BiDi, you must enable it in Options. For more details, see [Enabling BiDi](https://www.selenium.dev/ja/documentation/webdriver/bidi/)

## Script Pinning

## Execute Script

## DOM Mutation Handlers

最終更新 October 18, 2024: [add missing pages for BiDi script (71f0aa453d2)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/71f0aa453d297d3ed90300d73ba2a800270d478a)

----
url: https://www.selenium.dev/ja/documentation/webdriver/browsers/safari/
----

# Safari特有の機能

これらは、Apple Safariブラウザに特有の機能と機能です。

Unlike Chromium and Firefox drivers, the safaridriver is installed with the Operating System. To enable automation on Safari, run the following command from the terminal:

```shell
safaridriver --enable
```

```java
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#24-L25)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

```py
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L9-L10)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

```cs
            var options = new SafariOptions();
            driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/SafariTest.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/Browsers/SafariTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Safari;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("OSX")]
    public class SafariTest
    {
        private SafariDriver driver;

        [TestCleanup]
        public void QuitDriver()
        {
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new SafariOptions();
            driver = new SafariDriver(options);
        }
    }
}
```

```rb
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L8-L9)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

```js
    let driver = new Builder()
      .forBrowser(Browser.SAFARI)
      .setSafariOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/safariSpecificCap.spec.js#L8-L11)

##### /examples/javascript/test/browser/safariSpecificCap.spec.js

```js
const safari = require('selenium-webdriver/safari');
const {Browser, Builder} = require("selenium-webdriver");
const options = new safari.Options();
const process  =  require('node:process');

describe('Should be able to Test Command line arguments', function () {
  (process.platform === 'darwin' ? it : it.skip)('safari caps', async function () {
    let driver = new Builder()
      .forBrowser(Browser.SAFARI)
      .setSafariOptions(options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
val options = SafariOptions()
val driver = SafariDriver(options)
```

```java
                .withLogging(true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `SafariDriverService.SAFARI_DRIVER_LOGGING`\
Property value: `"true"` or `"false"`

[Selenium v4.26](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.26.0)

```py
    service = webdriver.SafariService(enable_logging=True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L17)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L20)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

```java
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#L39-L40)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

```py
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L25-L30)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L38-L39)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

----
url: https://www.selenium.dev/documentation/about/copyright/
----

# Copyright and attributions

| Software                            | Version  | License                                                     |
| ----------------------------------- | -------- | ----------------------------------------------------------- |
| [Hugo](/)                           | v0.110.0 | [Apache 2.0](//gohugo.io/about/license/)                    |
| [Docsy](//github.com/google/docsy/) | —        | [Apache 2.0](//github.com/google/docsy/blob/master/LICENSE) |

## License

All code and documentation originating from the Selenium project is licensed under the Apache 2.0 license, with the [Software Freedom Conservancy](/) as the copyright holder.

The license is included here for convenience, but you can also find it on the [Apache Foundation’s websites](//apache.org/licenses/LICENSE-2.0.html):

```markdown
                                 Apache License
                           Version 2.0, January 2004
                        http://www.apache.org/licenses/

   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION

   1. Definitions.

      "License" shall mean the terms and conditions for use, reproduction,
      and distribution as defined by Sections 1 through 9 of this document.

      "Licensor" shall mean the copyright owner or entity authorized by
      the copyright owner that is granting the License.

      "Legal Entity" shall mean the union of the acting entity and all
      other entities that control, are controlled by, or are under common
      control with that entity. For the purposes of this definition,
      "control" means (i) the power, direct or indirect, to cause the
      direction or management of such entity, whether by contract or
      otherwise, or (ii) ownership of fifty percent (50%) or more of the
      outstanding shares, or (iii) beneficial ownership of such entity.

      "You" (or "Your") shall mean an individual or Legal Entity
      exercising permissions granted by this License.

      "Source" form shall mean the preferred form for making modifications,
      including but not limited to software source code, documentation
      source, and configuration files.

      "Object" form shall mean any form resulting from mechanical
      transformation or translation of a Source form, including but
      not limited to compiled object code, generated documentation,
      and conversions to other media types.

      "Work" shall mean the work of authorship, whether in Source or
      Object form, made available under the License, as indicated by a
      copyright notice that is included in or attached to the work
      (an example is provided in the Appendix below).

      "Derivative Works" shall mean any work, whether in Source or Object
      form, that is based on (or derived from) the Work and for which the
      editorial revisions, annotations, elaborations, or other modifications
      represent, as a whole, an original work of authorship. For the purposes
      of this License, Derivative Works shall not include works that remain
      separable from, or merely link (or bind by name) to the interfaces of,
      the Work and Derivative Works thereof.

      "Contribution" shall mean any work of authorship, including
      the original version of the Work and any modifications or additions
      to that Work or Derivative Works thereof, that is intentionally
      submitted to Licensor for inclusion in the Work by the copyright owner
      or by an individual or Legal Entity authorized to submit on behalf of
      the copyright owner. For the purposes of this definition, "submitted"
      means any form of electronic, verbal, or written communication sent
      to the Licensor or its representatives, including but not limited to
      communication on electronic mailing lists, source code control systems,
      and issue tracking systems that are managed by, or on behalf of, the
      Licensor for the purpose of discussing and improving the Work, but
      excluding communication that is conspicuously marked or otherwise
      designated in writing by the copyright owner as "Not a Contribution."

      "Contributor" shall mean Licensor and any individual or Legal Entity
      on behalf of whom a Contribution has been received by Licensor and
      subsequently incorporated within the Work.

   2. Grant of Copyright License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      copyright license to reproduce, prepare Derivative Works of,
      publicly display, publicly perform, sublicense, and distribute the
      Work and such Derivative Works in Source or Object form.

   3. Grant of Patent License. Subject to the terms and conditions of
      this License, each Contributor hereby grants to You a perpetual,
      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
      (except as stated in this section) patent license to make, have made,
      use, offer to sell, sell, import, and otherwise transfer the Work,
      where such license applies only to those patent claims licensable
      by such Contributor that are necessarily infringed by their
      Contribution(s) alone or by combination of their Contribution(s)
      with the Work to which such Contribution(s) was submitted. If You
      institute patent litigation against any entity (including a
      cross-claim or counterclaim in a lawsuit) alleging that the Work
      or a Contribution incorporated within the Work constitutes direct
      or contributory patent infringement, then any patent licenses
      granted to You under this License for that Work shall terminate
      as of the date such litigation is filed.

   4. Redistribution. You may reproduce and distribute copies of the
      Work or Derivative Works thereof in any medium, with or without
      modifications, and in Source or Object form, provided that You
      meet the following conditions:

      (a) You must give any other recipients of the Work or
          Derivative Works a copy of this License; and

      (b) You must cause any modified files to carry prominent notices
          stating that You changed the files; and

      (c) You must retain, in the Source form of any Derivative Works
          that You distribute, all copyright, patent, trademark, and
          attribution notices from the Source form of the Work,
          excluding those notices that do not pertain to any part of
          the Derivative Works; and

      (d) If the Work includes a "NOTICE" text file as part of its
          distribution, then any Derivative Works that You distribute must
          include a readable copy of the attribution notices contained
          within such NOTICE file, excluding those notices that do not
          pertain to any part of the Derivative Works, in at least one
          of the following places: within a NOTICE text file distributed
          as part of the Derivative Works; within the Source form or
          documentation, if provided along with the Derivative Works; or,
          within a display generated by the Derivative Works, if and
          wherever such third-party notices normally appear. The contents
          of the NOTICE file are for informational purposes only and
          do not modify the License. You may add Your own attribution
          notices within Derivative Works that You distribute, alongside
          or as an addendum to the NOTICE text from the Work, provided
          that such additional attribution notices cannot be construed
          as modifying the License.

      You may add Your own copyright statement to Your modifications and
      may provide additional or different license terms and conditions
      for use, reproduction, or distribution of Your modifications, or
      for any such Derivative Works as a whole, provided Your use,
      reproduction, and distribution of the Work otherwise complies with
      the conditions stated in this License.

   5. Submission of Contributions. Unless You explicitly state otherwise,
      any Contribution intentionally submitted for inclusion in the Work
      by You to the Licensor shall be under the terms and conditions of
      this License, without any additional terms or conditions.
      Notwithstanding the above, nothing herein shall supersede or modify
      the terms of any separate license agreement you may have executed
      with Licensor regarding such Contributions.

   6. Trademarks. This License does not grant permission to use the trade
      names, trademarks, service marks, or product names of the Licensor,
      except as required for reasonable and customary use in describing the
      origin of the Work and reproducing the content of the NOTICE file.

   7. Disclaimer of Warranty. Unless required by applicable law or
      agreed to in writing, Licensor provides the Work (and each
      Contributor provides its Contributions) on an "AS IS" BASIS,
      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
      implied, including, without limitation, any warranties or conditions
      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
      PARTICULAR PURPOSE. You are solely responsible for determining the
      appropriateness of using or redistributing the Work and assume any
      risks associated with Your exercise of permissions under this License.

   8. Limitation of Liability. In no event and under no legal theory,
      whether in tort (including negligence), contract, or otherwise,
      unless required by applicable law (such as deliberate and grossly
      negligent acts) or agreed to in writing, shall any Contributor be
      liable to You for damages, including any direct, indirect, special,
      incidental, or consequential damages of any character arising as a
      result of this License or out of the use or inability to use the
      Work (including but not limited to damages for loss of goodwill,
      work stoppage, computer failure or malfunction, or any and all
      other commercial damages or losses), even if such Contributor
      has been advised of the possibility of such damages.

   9. Accepting Warranty or Additional Liability. While redistributing
      the Work or Derivative Works thereof, You may choose to offer,
      and charge a fee for, acceptance of support, warranty, indemnity,
      or other liability obligations and/or rights consistent with this
      License. However, in accepting such obligations, You may act only
      on Your own behalf and on Your sole responsibility, not on behalf
      of any other Contributor, and only if You agree to indemnify,
      defend, and hold each Contributor harmless for any liability
      incurred by, or claims asserted against, such Contributor by reason
      of your accepting any such warranty or additional liability.

   END OF TERMS AND CONDITIONS

   APPENDIX: How to apply the Apache License to your work.

      To apply the Apache License to your work, attach the following
      boilerplate notice, with the fields enclosed by brackets "[]"
      replaced with your own identifying information. (Don't include
      the brackets!)  The text should be enclosed in the appropriate
      comment syntax for the file format. We also recommend that a
      file or class name and description of purpose be included on the
      same "printed page" as the copyright notice for easier
      identification within third-party archives.

   Copyright [yyyy] [name of copyright owner]

   Licensed under the Apache License, Version 2.0 (the "License");
   you may not use this file except in compliance with the License.
   You may obtain a copy of the License at

       http://www.apache.org/licenses/LICENSE-2.0

   Unless required by applicable law or agreed to in writing, software
   distributed under the License is distributed on an "AS IS" BASIS,
   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   See the License for the specific language governing permissions and
   limitations under the License.
```

Last modified May 24, 2024: [modified a small text (#1738) (6e40fe33f83)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/6e40fe33f833133a0bbbf7a3f7ba09023105f350)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/elements/
----

# 网络元素

在DOM中识别和使用元素对象.

大多数人的Selenium代码都涉及使用web元素.

***

##### [查询网络元素](/zh-cn/documentation/webdriver/elements/finders/)

根据提供的定位值定位元素.

##### [Web元素交互](/zh-cn/documentation/webdriver/elements/interactions/)

用于操纵表单的高级指令集.

##### [定位策略](/zh-cn/documentation/webdriver/elements/locators/)

在DOM中标识一个或多个特定元素的方法.

##### [关于网络元素的信息](/zh-cn/documentation/webdriver/elements/information/)

元素相关的知识.

##### [文件上传](/zh-cn/documentation/webdriver/elements/file_upload/)

最后修改 January 16, 2022: [Update Chinese translation of "interactions.zh-cn.md" and “elements\\\_index.zh-cn.md” (#929)\[deploy site\] (87db00728ad)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/87db00728ad61b56da30fbcd24d5d1fb7bb80093)

----
url: https://www.selenium.dev/ja/documentation/webdriver/
----

# WebDriver

WebDriverはブラウザをネイティブに操作します。詳細については、こちらをご覧ください。

WebDriverは、ユーザーがローカルまたはSeleniumサーバーを使用するリモートマシンで行うように、ブラウザをネイティブに動かし、ブラウザの自動化に関して大きく前進します。

Selenium WebDriverは言語バインディングと個々のブラウザ制御コードの実装の両方を参照します。\
これは通常、単に *WebDriver* と呼ばれます。

Selenium WebDriverは、[W3C勧告](https://www.w3.org/TR/webdriver1/)です。

* WebDriverはシンプルでより簡潔なプログラミングインターフェイスとして設計されています。

* WebDriverはコンパクトなオブジェクト指向APIです。

* ブラウザーを効果的に動かします。

***

##### [入門](/ja/documentation/webdriver/getting_started/)

Seleniumを初めて使用する場合は、すぐに習得するのに役立つリソースがいくつかあります。

##### [ドライバーセッション](/ja/documentation/webdriver/drivers/)

##### [対応ブラウザ](/ja/documentation/webdriver/browsers/)

##### [待機](/ja/documentation/webdriver/waits/)

##### [Web要素](/ja/documentation/webdriver/elements/)

DOM内の要素オブジェクトの識別と操作

##### [ブラウザのインタラクション](/ja/documentation/webdriver/interactions/)

##### [アクション API](/ja/documentation/webdriver/actions_api/)

仮想化されたデバイス入力アクションを Web ブラウザーに提供するための低レベルのインターフェイス。

##### [双方向機能](/ja/documentation/webdriver/bidi/)

##### [サポート機能](/ja/documentation/webdriver/support_features/)

サポート クラスは、オプションの上位レベル機能を提供します。

##### [トラブルシューティングの支援](/ja/documentation/webdriver/troubleshooting/)

WebDriverの問題を管理する方法。

最終更新 February 6, 2024: [Indexing WebDriver as 2 (99486d915e3)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/99486d915e3439b679b9f6790927ba5f10c76e64)

----
url: https://www.selenium.dev/ja/documentation/grid/advanced_features/customize_node/
----

# Customizing a Node

```bash
java -jar custom_node-server.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

```bash
java -jar selenium-server-4.6.0.jar \
--ext custom_node-1.0-SNAPSHOT.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

Below is a sample that just prints some messages on to the console whenever there’s an activity of interest (session created, session deleted, a webdriver command executed etc.,) on the Node.

Sample customized node

```java
package org.seleniumhq.samples;

import java.net.URI;
import java.util.UUID;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.NoSuchSessionException;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.grid.config.Config;
import org.openqa.selenium.grid.data.CreateSessionRequest;
import org.openqa.selenium.grid.data.CreateSessionResponse;
import org.openqa.selenium.grid.data.NodeId;
import org.openqa.selenium.grid.data.NodeStatus;
import org.openqa.selenium.grid.data.Session;
import org.openqa.selenium.grid.log.LoggingOptions;
import org.openqa.selenium.grid.node.HealthCheck;
import org.openqa.selenium.grid.node.Node;
import org.openqa.selenium.grid.node.local.LocalNodeFactory;
import org.openqa.selenium.grid.security.Secret;
import org.openqa.selenium.grid.security.SecretOptions;
import org.openqa.selenium.grid.server.BaseServerOptions;
import org.openqa.selenium.internal.Either;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
import org.openqa.selenium.remote.tracing.Tracer;

public class DecoratedLoggingNode extends Node {

  private Node node;

  protected DecoratedLoggingNode(Tracer tracer, NodeId nodeId, URI uri, Secret registrationSecret, Duration sessionTimeout) {
    super(tracer, nodeId, uri, registrationSecret, sessionTimeout);
  }

  public static Node create(Config config) {
    LoggingOptions loggingOptions = new LoggingOptions(config);
    BaseServerOptions serverOptions = new BaseServerOptions(config);
    URI uri = serverOptions.getExternalUri();
    SecretOptions secretOptions = new SecretOptions(config);
    NodeOptions nodeOptions = new NodeOptions(config);
    Duration sessionTimeout = nodeOptions.getSessionTimeout();

    // Refer to the foot notes for additional context on this line.
    Node node = LocalNodeFactory.create(config);

    DecoratedLoggingNode wrapper = new DecoratedLoggingNode(loggingOptions.getTracer(),
        node.getId(),
        uri,
        secretOptions.getRegistrationSecret(),
        sessionTimeout);
    wrapper.node = node;
    return wrapper;
  }

  @Override
  public Either<WebDriverException, CreateSessionResponse> newSession(
      CreateSessionRequest sessionRequest) {
    System.out.println("Before newSession()");
    try {
      return this.node.newSession(sessionRequest);
    } finally {
      System.out.println("After newSession()");
    }
  }

  @Override
  public HttpResponse executeWebDriverCommand(HttpRequest req) {
    try {
      System.out.println("Before executeWebDriverCommand(): " + req.getUri());
      return node.executeWebDriverCommand(req);
    } finally {
      System.out.println("After executeWebDriverCommand()");
    }
  }

  @Override
  public Session getSession(SessionId id) throws NoSuchSessionException {
    try {
      System.out.println("Before getSession()");
      return node.getSession(id);
    } finally {
      System.out.println("After getSession()");
    }
  }

  @Override
  public HttpResponse uploadFile(HttpRequest req, SessionId id) {
    try {
      System.out.println("Before uploadFile()");
      return node.uploadFile(req, id);
    } finally {
      System.out.println("After uploadFile()");
    }
  }

  @Override
  public void stop(SessionId id) throws NoSuchSessionException {
    try {
      System.out.println("Before stop()");
      node.stop(id);
    } finally {
      System.out.println("After stop()");
    }
  }

  @Override
  public boolean isSessionOwner(SessionId id) {
    try {
      System.out.println("Before isSessionOwner()");
      return node.isSessionOwner(id);
    } finally {
      System.out.println("After isSessionOwner()");
    }
  }

  @Override
  public boolean isSupporting(Capabilities capabilities) {
    try {
      System.out.println("Before isSupporting");
      return node.isSupporting(capabilities);
    } finally {
      System.out.println("After isSupporting()");
    }
  }

  @Override
  public NodeStatus getStatus() {
    try {
      System.out.println("Before getStatus()");
      return node.getStatus();
    } finally {
      System.out.println("After getStatus()");
    }
  }

  @Override
  public HealthCheck getHealthCheck() {
    try {
      System.out.println("Before getHealthCheck()");
      return node.getHealthCheck();
    } finally {
      System.out.println("After getHealthCheck()");
    }
  }

  @Override
  public void drain() {
    try {
      System.out.println("Before drain()");
      node.drain();
    } finally {
      System.out.println("After drain()");
    }

  }

  @Override
  public boolean isReady() {
    try {
      System.out.println("Before isReady()");
      return node.isReady();
    } finally {
      System.out.println("After isReady()");
    }
  }
}
```

***Foot Notes:***

In the above example, the line `Node node = LocalNodeFactory.create(config);` explicitly creates a `LocalNode`.

There are basically 2 types of *user facing implementations* of `org.openqa.selenium.grid.node.Node` available.

These classes are good starting points to learn how to build a custom Node and also to learn the internals of a Node.

* `org.openqa.selenium.grid.node.local.LocalNode` - Used to represent a long running Node and is the default implementation that gets wired in when you start a `node`.

  * It can be created by calling `LocalNodeFactory.create(config);`, where:

    * `LocalNodeFactory` belongs to `org.openqa.selenium.grid.node.local`
    * `Config` belongs to `org.openqa.selenium.grid.config`

* `org.openqa.selenium.grid.node.k8s.OneShotNode` - This is a special reference implementation wherein the Node gracefully shuts itself down after servicing one test session. This class is currently not available as part of any pre-built maven artifact.

  * You can refer to the source code [here](https://github.com/SeleniumHQ/selenium/blob/trunk/java/src/org/openqa/selenium/grid/node/k8s/OneShotNode.java) to understand its internals.

  * To build it locally refer [here](https://github.com/SeleniumHQ/selenium/blob/trunk/deploys/k8s/README.md).

  * It can be created by calling `OneShotNode.create(config)`, where:

    * `OneShotNode` belongs to `org.openqa.selenium.grid.node.k8s`
    * `Config` belongs to `org.openqa.selenium.grid.config`

最終更新 May 17, 2024: [Update Custom Node Initialization in Grid Advanced Features (#1729) (808af3e6bdd)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/808af3e6bddcae225b07dc2547e4e8024feae912)

----
url: https://www.selenium.dev/pt-br/documentation/
----

# O Projeto Selenium de Automação de Navegadores

Selenium é um projeto que abrange uma variedade de ferramentas e bibliotecas que permitem e suportam a automação de navegadores da web.

Ele fornece extensões para emular a interação do usuário com os navegadores, um servidor de distribuição para escalonar a alocação do navegador, e a infraestrutura para implementações da [Especificação W3C WebDriver](//www.w3.org/TR/webdriver/) que permite escrever código intercambiável para todos os principais navegadores da web.

Este projeto é possível graças a colaboradores voluntários que dedicam milhares de horas de seu próprio tempo, e disponibilizaram o código-fonte [disponível gratuitamente](https://www.selenium.dev/pt-br/documentation/about/copyright/#license) para qualquer um usar, aproveitar e melhorar.

Selenium reúne criadores de navegadores, engenheiros e entusiastas para promover uma discussão aberta sobre a automação da plataforma da web. O projeto organiza [uma conferência anual](/pt-br/) para ensinar e nutrir a comunidade.

No núcleo do Selenium está [WebDriver](https://www.selenium.dev/pt-br/documentation/webdriver/), uma interface para escrever conjuntos de instruções que podem ser executados alternadamente em muitos navegadores. Aqui está uma das instruções mais simples que você pode fazer:

*
*
*
*
*
*

```java
package dev.selenium.hello;

import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

public class HelloSelenium {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://selenium.dev");

        driver.quit();
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/hello/HelloSelenium.java)

```py
from selenium import webdriver


driver = webdriver.Chrome()

driver.get("http://selenium.dev")

driver.quit()
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/hello/hello_selenium.py)

```cs
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Hello;

public static class HelloSelenium
{
    public static void Main()
    {
        var driver = new ChromeDriver();
            
        driver.Navigate().GoToUrl("https://selenium.dev");
            
        driver.Quit();
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/HelloSelenium.cs)

```rb
# frozen_string_literal: true

require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get 'https://selenium.dev'

driver.quit
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/hello/hello_selenium.rb)

```js
const {Builder, Browser} = require('selenium-webdriver');

(async function helloSelenium() {
  let driver = await new Builder().forBrowser(Browser.CHROME).build();

  await driver.get('https://selenium.dev');

  await driver.quit();
})();
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/hello/helloSelenium.js)

```kt
package dev.selenium.hello

import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()

    driver.get("https://selenium.dev")

    driver.quit()
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/hello/HelloSelenium.kt)

Consulte a [Visão Geral](https://www.selenium.dev/pt-br/documentation/overview/) para verificar os diferentes componentes do projeto e decidir se o Selenium é a ferramenta certa para você.

Você deve continuar no Guia de [Introdução](https://www.selenium.dev/pt-br/documentation/webdriver/getting_started/) para entender como instalar o Selenium e usá-lo com sucesso como uma ferramenta de automação de teste e dimensionar testes simples como esse para serem executados em ambientes grandes e distribuídos em vários navegadores e em vários sistemas operacionais diferentes.

***

##### [Resumo](/pt-br/documentation/overview/)

Será Selenium a ferramenta para você? Veja um resumo dos componentes do projecto.

##### [WebDriver](/pt-br/documentation/webdriver/)

WebDriver manipula um navegador nativamente; aprenda mais sobre isso.

##### [Gerenciador do Selenium (Beta)](/pt-br/documentation/selenium_manager/)

O Selenium Manager é uma ferramenta de linha de comando implementada em Rust que fornece gerenciamento automatizado de drivers e navegadores para o Selenium. As bibliotecas do Selenium usam essa ferramenta por padrão, portanto, você não precisa baixá-la, adicionar nada ao seu código ou realizar qualquer outra ação para utilizá-la.

##### [Grid](/pt-br/documentation/grid/)

Pretende executar testes em paralelo em várias máquinas? Então a Grid é para si.

##### [Servidor de drivers do IE](/pt-br/documentation/ie_driver_server/)

O Internet Explorer Driver é um servidor autónomo que implementa a especificação WebDriver.

##### [Selenium IDE](/pt-br/documentation/ide/)

Selenium IDE é uma extensão do navegador que grava e reproduz uma acção do utilizador.

##### [Diretrizes e recomendações](/pt-br/documentation/test_practices/)

Guias e recomendações ao preparar soluções de testes com o projecto Selenium.

##### [Legado](/pt-br/documentation/legacy/)

Nesta seção você pode encontrar toda a documentação relacionada aos componentes legados do Selenium. Isso deve ser mantido puramente por razões históricas e não como um incentivo para o uso obsoleto componentes.

##### [Sobre esta documentação](/pt-br/documentation/about/)

Última modificação April 6, 2025: [\[rb\] do not run hello selenium in examples (efaae63f2b6)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/efaae63f2b66029b5022e5b0348414a1a29c631f)

----
url: https://www.selenium.dev/documentation/webdriver/actions_api/wheel/
----

```java
        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L17-L20)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L11-L14)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L11-L14)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L16-L19)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L18-L21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L29-L33)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L22-L26)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L31-L35)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L22-L26)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L26-L31)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L30-L34)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L42-L46)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L35-L39)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L46-L53)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L34-L38)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L40-L44)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L43-L47)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L57-L61)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L50-L54)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L66-L75)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L48-L52)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L57-L61)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L59-L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L73-L76)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L66-L70)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L89-L97)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L63-L66)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L75-L77)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L75-L78)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

----
url: https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location/
----

# Unable to Locate Driver Error

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.bash_profile
source ~/.bash_profile
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Terminal and execute:

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.zshenv
source ~/.zshenv
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Command Prompt and execute:

```shell
echo %PATH%
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
setx PATH "%PATH%;C:\WebDriver\bin"
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver.exe --version
```

| Browser           | Supported OS                | Maintained by    | Download                                                                     | Issue Tracker                                             |
| ----------------- | --------------------------- | ---------------- | ---------------------------------------------------------------------------- | --------------------------------------------------------- |
| Chromium/Chrome   | Windows/macOS/Linux         | Google           | [Downloads](/downloads/)                                                     | [Issues](//bugs.chromium.org/p/chromedriver/issues/list)  |
| Firefox           | Windows/macOS/Linux         | Mozilla          | [Downloads](//github.com/mozilla/geckodriver/releases)                       | [Issues](//github.com/mozilla/geckodriver/issues)         |
| Edge              | Windows/macOS/Linux         | Microsoft        | [Downloads](//developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/) | [Issues](//github.com/MicrosoftEdge/EdgeWebDriver/issues) |
| Internet Explorer | Windows                     | Selenium Project | [Downloads](/downloads/)                                                     | [Issues](//github.com/SeleniumHQ/selenium/labels/D-IE)    |
| Safari            | macOS High Sierra and newer | Apple            | Built in                                                                     | [Issues](//bugreport.apple.com/logon)                     |

Note: The Opera driver no longer works with the latest functionality of Selenium and is currently officially unsupported.

----
url: https://www.selenium.dev/documentation/test_practices/discouraged/link_spidering/
----

# Link spidering

Using WebDriver to spider through links is not a recommended practice. Not because it cannot be done, but because WebDriver is definitely not the most ideal tool for this. WebDriver needs time to start up, and can take several seconds, up to a minute depending on how your test is written, just to get to the page and traverse through the DOM.

Instead of using WebDriver for this, you could save a ton of time by executing a [curl](https://curl.se/) command, or using a library such as BeautifulSoup since these methods do not rely on creating a browser and navigating to a page. You are saving tonnes of time by not using WebDriver for this task.

----
url: https://www.selenium.dev/pt-br/_print/documentation/legacy/selenium_3/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/legacy/selenium_3/).

# Selenium 3

Selenium 3 was the implementation of WebDriver without the Selenium RC Code. It has since been replaced with Selenium 4, which implements the W3C WebDriver specification.

* 1: [Grid 3](#pg-22c4f48b7072956000ca38f27da0cc05)
* 2: [Configurando a sua](#pg-695883420ae17227d8cc8d4d50b0aa70)
* 3: [Componentes](#pg-cc6eb5c9bdbe3ebfd6bff949748a4ae0)

# 1 - Grid 3

Selenium Grid 3 supported WebDriver without Selenium RC code. Grid 3 was completely rewritten for the new Grid 4.

[Grid 4](https://www.selenium.dev/pt-br/documentation/grid/)

*Selenium Grid* é um servidor proxy inteligente que permite que os testes Selenium encaminhem comandos para instâncias remotas do navegador da web. Seu objetivo é fornecer uma maneira fácil de executar testes em paralelo em várias máquinas.

Com Selenium Grid, um servidor atua como o hub que roteia comandos de teste formatados em JSON para um ou mais nós registrados. Os testes entram em contato com o hub para obter acesso a instâncias remotas do navegador. O hub tem uma lista de servidores registrados aos quais fornece acesso, e permite o controle dessas instâncias.

Selenium Grid nos permite executar testes em paralelo em várias máquinas, e gerenciar diferentes versões e configurações do navegador centralmente (em vez de em cada teste individual).

Selenium Grid não é uma bala de prata. Ele resolve um subconjunto de problemas comuns de delegação e distribuição, mas não irá, por exemplo, gerenciar sua infraestrutura, e pode não atender às suas necessidades específicas.

# 2 - Configurando a sua

```shell
java -jar selenium-server-standalone.jar -role hub
```

The Hub will listen to port 4444 by default. You can view the status of the hub by opening a browser window and navigating to <http://localhost:4444/grid/console>.

Para alterar a porta padrão, você pode adicionar a flag opcional `-port` com um número inteiro representando a porta a ser ouvida quando você executa o comando. Além disso, todas as outras opções que você vê no arquivo de configuração JSON (veja abaixo) são possíveis flags de linha de comando.

Você certamente pode sobreviver apenas com o comando simples mostrado acima, mas se você precisar de uma configuração mais avançada, você também pode especificar um arquivo de configuração de formato JSON, por conveniência, para configurar o hub ao iniciá-lo. Você pode fazer assim:

```shell
java -jar selenium-server-standalone.jar -role hub -hubConfig hubConfig.json -debug
```

Abaixo você verá um exemplo de um arquivo `hubConfig.json`. Entraremos em mais detalhes sobre como fornecer arquivos de configuração de nó no Passo 2.

```json
{
  "_comment" : "Configuration for Hub - hubConfig.json",
  "host": ip,
  "maxSession": 5,
  "port": 4444,
  "cleanupCycle": 5000,
  "timeout": 300000,
  "newSessionWaitTimeout": -1,
  "servlets": [],
  "prioritizer": null,
  "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
  "throwOnCapabilityNotPresent": true,
  "nodePolling": 180000,
  "platform": "WINDOWS"}
```

### Pasos 2: Inicialize os Nós

Independentemente de você querer executar uma Grid com a nova funcionalidade WebDriver, ou uma Grid com funcionalidade Selenium 1 RC, ou os dois ao mesmo tempo, você usa o mesmo arquivo `selenium-server-standalone.jar` para iniciar os nós:

```shell
java -jar selenium-server-standalone.jar -role node -hub http://localhost:4444
```

```shell
java -Dwebdriver.chrome.driver=chromedriver.exe -jar selenium-server-standalone.jar -role node -nodeConfig node1Config.json
```

E aqui está um exemplo do arquivo `nodeConfig.json`:

```json
{
  "capabilities": [
    {
      "browserName": "firefox",
      "acceptSslCerts": true,
      "javascriptEnabled": true,
      "takesScreenshot": false,
      "firefox_profile": "",
      "browser-version": "27",
      "platform": "WINDOWS",
      "maxInstances": 5,
      "firefox_binary": "",
      "cleanSession": true
    },
    {
      "browserName": "chrome",
      "maxInstances": 5,
      "platform": "WINDOWS",
      "webdriver.chrome.driver": "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"
    },
    {
      "browserName": "internet explorer",
      "maxInstances": 1,
      "platform": "WINDOWS",
      "webdriver.ie.driver": "C:/Program Files (x86)/Internet Explorer/iexplore.exe"
    }
  ],
  "configuration": {
    "_comment" : "Configuration for Node",
    "cleanUpCycle": 2000,
    "timeout": 30000,
    "proxy": "org.openqa.grid.selenium.proxy.WebDriverRemoteProxy",
    "port": 5555,
    "host": ip,
    "register": true,
    "hubPort": 4444,
    "maxSession": 5
  }
}
```

```shell
java -jar selenium-server-standalone.jar -role hub -log log.txt
```

Use o seu editor de texto favorito para abrir o arquivo de log (log.txt no exemplo acima) para encontrar registros de “ERROR” se você tiver problemas.

### Usando o argumento `-debug`

Você também pode usar o argumento `-debug` para imprimir logs de depuração no console. Inicie o Selenium Grid Hub ou Node com o argumento `-debug`. Por favor, veja o exemplo abaixo:

```shell
java -jar selenium-server-standalone.jar -role hub -debug
```

# 3 - Componentes

----
url: https://www.selenium.dev/zh-cn/_print/documentation/webdriver/interactions/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/webdriver/interactions/).

# 浏览器交互

* 1: [浏览器导航](#pg-ddad76d44f8bc51d5502d0c143ce3174)
* 2: [JavaScript 警告框,提示框和确认框](#pg-0643549b2851f978a474834397780f61)
* 3: [同cookies一起工作](#pg-d8053874605d92edef528879699c0b00)
* 4: [与IFrames和frames一起工作](#pg-fd060bfb3f1308b75ccac7fb442fd877)
* 5: [打印页面](#pg-064297ab40b7ad2413b675d6c801c17a)
* 6: [同窗口和标签一起工作](#pg-ff52405bd91a08f2a515a029bf275dcc)
* 7: [虚拟身份验证器](#pg-96dc337616681e4ec54c38c6acf93c38)

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java#L15)

##### /examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class InteractionsTest extends BaseChromeTest {
    @Test
    public void getTitle() {
        driver.get("https://www.selenium.dev/");
        // get title
        String title = driver.getTitle();
        Assertions.assertEquals(title, "Selenium");
    }

    @Test
    public void getCurrentUrl() {
        driver.get("https://www.selenium.dev/");
        // get current url
        String url = driver.getCurrentUrl();
        Assertions.assertEquals(url, "https://www.selenium.dev/");
    }
}
```

```py
title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_interactions.py#L7)

##### /examples/python/tests/interactions/test\_interactions.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")

title = driver.title
assert title == "Selenium"

url = driver.current_url
assert url == "https://www.selenium.dev/"

driver.quit()
```

```cs
            String title = driver.Title;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs#L37)

##### /examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class InteractionsTest
    {
        [TestMethod]
        public void TestInteractions()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url="https://www.selenium.dev/";
            //GetTitle
            String title = driver.Title;
            Assert.AreEqual(title, "Selenium");

            //GetCurrentURL
            String url = driver.Url;
            Assert.AreEqual(url, "https://www.selenium.dev/");

            //quitting driver
            driver.Quit(); //close all windows
        }
    }
}
```

```rb
  it 'gets the current title' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/browser_spec.rb#L8)

##### /examples/ruby/spec/interactions/browser\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'gets the current title' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_title = driver.title
    expect(current_title).to eq 'Selenium'
  end

  it 'gets the current url' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_url = driver.current_url
    expect(current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    let title = await driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/interactionsIndex.spec.js#L20)

##### /examples/javascript/test/interactions/interactionsIndex.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Should be able to get title and current url', async function () {
    const url = 'https://www.selenium.dev/';
    await driver.get(url);

    //Get Current title
    let title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Get Current url
    let currentUrl = await driver.getCurrentUrl();
    assert.equal(currentUrl, url);
  });
});
```

```kotlin
driver.title
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java#L26)

##### /examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class InteractionsTest extends BaseChromeTest {
    @Test
    public void getTitle() {
        driver.get("https://www.selenium.dev/");
        // get title
        String title = driver.getTitle();
        Assertions.assertEquals(title, "Selenium");
    }

    @Test
    public void getCurrentUrl() {
        driver.get("https://www.selenium.dev/");
        // get current url
        String url = driver.getCurrentUrl();
        Assertions.assertEquals(url, "https://www.selenium.dev/");
    }
}
```

```py
url = driver.current_url
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_interactions.py#L10)

##### /examples/python/tests/interactions/test\_interactions.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")

title = driver.title
assert title == "Selenium"

url = driver.current_url
assert url == "https://www.selenium.dev/"

driver.quit()
```

```cs
            String url = driver.Url;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs#L41)

##### /examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class InteractionsTest
    {
        [TestMethod]
        public void TestInteractions()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url="https://www.selenium.dev/";
            //GetTitle
            String title = driver.Title;
            Assert.AreEqual(title, "Selenium");

            //GetCurrentURL
            String url = driver.Url;
            Assert.AreEqual(url, "https://www.selenium.dev/");

            //quitting driver
            driver.Quit(); //close all windows
        }
    }
}
```

```rb
  it 'gets the current url' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/browser_spec.rb#L14)

##### /examples/ruby/spec/interactions/browser\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'gets the current title' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_title = driver.title
    expect(current_title).to eq 'Selenium'
  end

  it 'gets the current url' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_url = driver.current_url
    expect(current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    let currentUrl = await driver.getCurrentUrl();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/interactionsIndex.spec.js#L24)

##### /examples/javascript/test/interactions/interactionsIndex.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Should be able to get title and current url', async function () {
    const url = 'https://www.selenium.dev/';
    await driver.get(url);

    //Get Current title
    let title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Get Current url
    let currentUrl = await driver.getCurrentUrl();
    assert.equal(currentUrl, url);
  });
});
```

```kotlin
driver.currentUrl
```

# 1 - 浏览器导航

```java
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L14-L18)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.get("https://www.selenium.dev/selenium/web/index.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L6)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Convenient
            driver.Url = "https://selenium.dev";
            //Longer
            driver.Navigate().GoToUrl("https://selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class NavigationTest
    {
        [TestMethod]
        public void TestNavigationCommands()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            //Convenient
            driver.Url = "https://selenium.dev";
            //Longer
            driver.Navigate().GoToUrl("https://selenium.dev");
            var title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Back
            driver.Navigate().Back();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Forward
            driver.Navigate().Forward();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Refresh
            driver.Navigate().Refresh();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Quit the browser
            driver.Quit();
        }
    }
}
```

```rb

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L7-L9)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L16-L20)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
// 简便的方法
driver.get("https://selenium.dev")

// 更长的方法
driver.navigate().to("https://selenium.dev")
```

```java
        //Back
        driver.navigate().back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L22-L23)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.back()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L11)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Back
             driver.Navigate().Back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L24-L25)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
    driver.navigate.to 'https://www.selenium.dev/'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L15)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Back
    await driver.navigate().back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L24-L25)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().back() 
```

```java
        //Forward
        driver.navigate().forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L27-L28)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.forward()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L15)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Forward
             driver.Navigate().Forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L29-L30)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L23)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Forward
    await driver.navigate().forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L29-L30)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().forward()
```

```java
        //Refresh
        driver.navigate().refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L32-L33)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.refresh()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L19)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Refresh
             driver.Navigate().Refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L34-L35)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
  it 'refreshes the page' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L29)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Refresh
    await driver.navigate().refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L34-L35)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().refresh()
```

# 2 - JavaScript 警告框,提示框和确认框

```java

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L36-L41)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L12-L18)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See an example alert")).Click();

//Wait for the alert to be displayed and store it in a variable
IAlert alert = wait.Until(ExpectedConditions.AlertIsPresent());

//Store the alert text in a variable
string text = alert.Text;

//Press the OK button
alert.Accept();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L15-L22)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L19-L21)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See an example alert")).click()

//Wait for the alert to be displayed and store it in a variable
val alert = wait.until(ExpectedConditions.alertIsPresent())

//Store the alert text in a variable
val text = alert.getText()

//Press the OK button
alert.accept()
  
```

```java
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L131-L138)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L26-L32)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See a sample confirm")).Click();

//Wait for the alert to be displayed
wait.Until(ExpectedConditions.AlertIsPresent());

//Store the alert in a variable
IAlert alert = driver.SwitchTo().Alert();

//Store the alert in a variable for reuse
string text = alert.Text;

//Press the Cancel button
alert.Dismiss();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L28-L35)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L30-L32)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See a sample confirm")).click()

//Wait for the alert to be displayed
wait.until(ExpectedConditions.alertIsPresent())

//Store the alert in a variable
val alert = driver.switchTo().alert()

//Store the alert in a variable for reuse
val text = alert.text

//Press the Cancel button
alert.dismiss()
  
```

```java
        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L79-L84)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L40-L47)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See a sample prompt")).Click();

//Wait for the alert to be displayed and store it in a variable
IAlert alert = wait.Until(ExpectedConditions.AlertIsPresent());

//Type your message
alert.SendKeys("Selenium");

//Press the OK button
alert.Accept();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L41-L48)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L42-L45)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See a sample prompt")).click()

//Wait for the alert to be displayed and store it in a variable
val alert = wait.until(ExpectedConditions.alertIsPresent())

//Type your message
alert.sendKeys("Selenium")

//Press the OK button
alert.accept()
  
```

# 3 - 同cookies一起工作

```java

    WebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L30-L32)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L5-9)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L32-L34)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L9-L11)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L18)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

  const {Browser, Builder} = require("selenium-webdriver");
  const assert = require('assert')
  
  
  describe('Cookies', function() {
    let driver;
  
    before(async function() {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('Create a cookie', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // set a cookie on the current domain
      await driver.manage().addCookie({ name: 'key', value: 'value' });
    });
  
    it('Create cookies with sameSite', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
      await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
      await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
    });
  
    it('Read cookie', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // set a cookie on the current domain
      await driver.manage().addCookie({ name: 'foo', value: 'bar' });
  
      // Get cookie details with named cookie 'foo'
      await driver.manage().getCookie('foo').then(function(cookie) {
        assert.equal(cookie.value, 'bar');
      });
    });
  
    it('Read all cookies', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // Add few cookies
      await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
      await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
  
      // Get all Available cookies
      await driver.manage().getCookies().then(function(cookies) {
        assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
      });
    });
  
    it('Delete a cookie', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // Add few cookies
      await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
      await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
  
      // Delete a cookie with name 'test1'
      await driver.manage().deleteCookie('test1');
  
      // Get all Available cookies
      await driver.manage().getCookies().then(function(cookies) {
        assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
      });
    });
  
    it('Delete all cookies', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // Add few cookies
      await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
      await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
  
      // Delete all cookies
      await driver.manage().deleteAllCookies();
    });
  });
  
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")

        // Adds the cookie into current browser context
        driver.manage().addCookie(Cookie("key", "value"))
    } finally {
        driver.quit()
    }
}  
  
```

```java
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L38-L42)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L13-L20)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L40-L44)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L17-L21)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L35-L38)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("foo", "bar"))

        // Get cookie details with named cookie 'foo'
        val cookie = driver.manage().getCookieNamed("foo")
        println(cookie)
    } finally {
        driver.quit()
    }
}  
  
```

```java
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L52-L66)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L24-L32)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L51-L64)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L26-L31)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L49-L51)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        driver.manage().addCookie(Cookie("test2", "cookie2"))

        // Get All available cookies
        val cookies = driver.manage().cookies
        println(cookies)
    } finally {
        driver.quit()
    }
}  
  
```

```java
        }
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L74-L77)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L35-L43)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L70-L73)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L40-L43)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L61-L62)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        val cookie1 = Cookie("test2", "cookie2")
        driver.manage().addCookie(cookie1)

        // delete a cookie with name 'test1'
        driver.manage().deleteCookieNamed("test1")
        
        // delete cookie by passing cookie object of current browsing context.
        driver.manage().deleteCookie(cookie1)
    } finally {
        driver.quit()
    }
}  
  
```

```java
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L100-L105)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L47-L55)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L92-L97)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L49-L54)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L77-L78)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        driver.manage().addCookie(Cookie("test2", "cookie2"))

        // deletes all cookies
        driver.manage().deleteAllCookies()
    } finally {
        driver.quit()
    }
}
  
```

```java

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L112-L121)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L59-L71)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SameSiteCookie {
  class SameSiteCookie {
    static void Main(string[] args) {
      IWebDriver driver = new ChromeDriver();
      try {
        driver.Navigate().GoToUrl("http://www.example.com");

        var cookie1Dictionary = new System.Collections.Generic.Dictionary<string, object>() {
          { "name", "test1" }, { "value", "cookie1" }, { "sameSite", "Strict" } };
        var cookie1 = Cookie.FromDictionary(cookie1Dictionary);

        var cookie2Dictionary = new System.Collections.Generic.Dictionary<string, object>() {
          { "name", "test2" }, { "value", "cookie2" }, { "sameSite", "Lax" } };
        var cookie2 = Cookie.FromDictionary(cookie2Dictionary);

        driver.Manage().Cookies.AddCookie(cookie1);
        driver.Manage().Cookies.AddCookie(cookie2);

        System.Console.WriteLine(cookie1.SameSite);
        System.Console.WriteLine(cookie2.SameSite);
      } finally {
        driver.Quit();
      }
    }
  }
}
  
```

```ruby
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://www.example.com'
  # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
  driver.manage.add_cookie(name: "foo", value: "bar", same_site: "Strict")
  driver.manage.add_cookie(name: "foo1", value: "bar", same_site: "Lax")
  puts driver.manage.cookie_named('foo')
  puts driver.manage.cookie_named('foo1')
ensure
  driver.quit
end
  
```

```js
  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L24-L26)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("http://www.example.com")
        val cookie = Cookie.Builder("key", "value").sameSite("Strict").build()
        val cookie1 = Cookie.Builder("key", "value").sameSite("Lax").build()
        driver.manage().addCookie(cookie)
        driver.manage().addCookie(cookie1)
        println(cookie.getSameSite())
        println(cookie1.getSameSite())
    } finally {
        driver.quit()
    }
} 
  
```

# 4 - 与IFrames和frames一起工作

框架是一种现在已被弃用的方法，用于从同一域中的多个文档构建站点布局。除非你使用的是 HTML5 之前的 webapp，否则你不太可能与他们合作。内嵌框架允许插入来自完全不同领域的文档，并且仍然经常使用。

如果您需要使用框架或 iframe, WebDriver 允许您以相同的方式使用它们。考虑 iframe 中的一个按钮。 如果我们使用浏览器开发工具检查元素，我们可能会看到以下内容:

```html
<div id="modal">
  <iframe id="buttonframe" name="myframe" src="https://seleniumhq.github.io">
   <button>Click here</button>
 </iframe>
</div>
```

```java
// 这不会工作
driver.findElement(By.tagName("button")).click();
```

```python
    # 这不会工作
driver.find_element(By.TAG_NAME, 'button').click()
```

```csharp
// 这不会工作
driver.FindElement(By.TagName("button")).Click();
```

```ruby
    # 这不会工作
driver.find_element(:tag_name,'button').click
```

```javascript
// 这不会工作
await driver.findElement(By.css('button')).click();
```

```kotlin
// 这不会工作
driver.findElement(By.tagName("button")).click()
```

```java
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L38-L46)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L24-L32)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L38-L46)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L26-L33)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// 存储网页元素
const iframe = driver.findElement(By.css('#modal> iframe'));

// 切换到 frame
await driver.switchTo().frame(iframe);

// 现在可以点击按钮
await driver.findElement(By.css('button')).click();
```

```kotlin
// 存储网页元素
val iframe = driver.findElement(By.cssSelector("#modal>iframe"))

// 切换到 frame
driver.switchTo().frame(iframe)

// 现在可以点击按钮
driver.findElement(By.tagName("button")).click()
```

```java
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L50-L58)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L34-L42)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L50-L58)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L36-L43)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// 使用 ID
await driver.switchTo().frame('buttonframe');

// 或者使用 name 代替
await driver.switchTo().frame('myframe');

// 现在可以点击按钮
await driver.findElement(By.css('button')).click();
```

```kotlin
// 使用 ID
driver.switchTo().frame("buttonframe")

// 或者使用 name 代替
driver.switchTo().frame("myframe")

// 现在可以点击按钮
driver.findElement(By.tagName("button")).click()
```

```java
         //switch To IFrame using index
         driver.switchTo().frame(0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L62-L63)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L45-L46)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L62-L63)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L46-L47)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// 切换到第 2 个框架
await driver.switchTo().frame(1);
```

```kotlin
// 切换到第 2 个框架
driver.switchTo().frame(1)
```

```java
         //leave frame
         driver.switchTo().defaultContent();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L66-L67)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L49-L50)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //leave frame
            driver.SwitchTo().DefaultContent();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L66-L67)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L49-L50)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// 回到顶层
await driver.switchTo().defaultContent();
```

```kotlin
// 回到顶层
driver.switchTo().defaultContent()
```

# 5 - 打印页面

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L14-L17)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L12-L19)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L12-L14)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L23-L26)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L22-L29)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L18-L20)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L32-L35)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L32-L38)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L24-L26)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L41-L48)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L51-L57)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L30-L35)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L53-L57)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L61-L68)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L42-L45)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L63-L66)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L41-L48)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L49-L51)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L72-L75)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L71-L78)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L55-L57)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java#L27-L31)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.Pdf;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.PrintsPage;
import dev.selenium.BaseTest;

public class PrintsPageTest extends BaseTest{

    @BeforeEach
    public void setup() {
        ChromeOptions options = getDefaultChromeOptions();
        options.setCapability("webSocketUrl", true);
        driver = new ChromeDriver(options);
    }

    @Test
    public void PrintWithPrintsPageTest() 
    {
        driver.get("https://www.selenium.dev/");
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }

    @Test
    public void PrintWithBrowsingContextTest() 
    {
        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);
        Assertions.assertTrue(printPage.length() > 0);
    }
}
```

**BrowsingContext()**

```java
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        PrintOptions printOptions = new PrintOptions();
        String printPage = browsingContext.print(printOptions);
        Assertions.assertTrue(printPage.length() > 0);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java#L37-L41)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.Pdf;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.PrintsPage;
import dev.selenium.BaseTest;

public class PrintsPageTest extends BaseTest{

    @BeforeEach
    public void setup() {
        ChromeOptions options = getDefaultChromeOptions();
        options.setCapability("webSocketUrl", true);
        driver = new ChromeDriver(options);
    }

    @Test
    public void PrintWithPrintsPageTest() 
    {
        driver.get("https://www.selenium.dev/");
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }

    @Test
    public void PrintWithBrowsingContextTest() 
    {
        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);
        Assertions.assertTrue(printPage.length() > 0);
    }
}
```

```cs
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L81-L88)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

**print\_page()**

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    pdf = driver.print_page(print_options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_prints_page.py#L12-L14)

##### /examples/python/tests/interactions/test\_prints\_page.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_prints_page(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    pdf = driver.print_page(print_options)
    assert len(pdf) > 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

# 6 - 同窗口和标签一起工作

```java
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L16-L20)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L16-L18)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L17-L21)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
driver.window_handle
```

```javascript
await driver.getWindowHandle();
```

```kotlin
driver.windowHandle
```

```java
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L22-L29)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L22-L32)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L23-L30)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
    # 存储原始窗口的 ID
original_window = driver.window_handle

    #检查一下，我们还没有打开其他的窗口
assert(driver.window_handles.length == 1,'Expected one window')

    #点击在新窗口中打开的链接
driver.find_element(link:'new window').click

    #等待新窗口或标签页
wait.until {driver.window_handles.length == 2}

    #循环执行，直到找到一个新的窗口句柄
driver.window_handles.each do |handle|
if handle != original_window
driver.switch_to.window handle
break
end
end

    #等待新标签页完成加载内容
wait.until {driver.title =='Selenium documentation'}
```

```javascript
// 存储原始窗口的 ID
const originalWindow = await driver.getWindowHandle();

// 检查一下，我们还没有打开其他的窗口
assert((await driver.getAllWindowHandles()).length === 1);

// 点击在新窗口中打开的链接
await driver.findElement(By.linkText('new window')).click();

// 等待新窗口或标签页
await driver.wait(async () => (await driver.getAllWindowHandles()).length === 2,
10000
);

// 循环执行，直到找到一个新的窗口句柄
const windows = await driver.getAllWindowHandles();
windows.forEach(async handle => {if (handle !== originalWindow) {await driver.switchTo().window(handle);
}
});

// 等待新标签页完成加载内容
await driver.wait(until.titleIs('Selenium documentation'), 10000);
```

```kotlin
// 存储原始窗口的 ID
val originalWindow = driver.getWindowHandle()

// 检查一下，我们还没有打开其他的窗口
assert(driver.getWindowHandles().size() === 1)

// 点击在新窗口中打开的链接
driver.findElement(By.linkText("new window")).click()

// 等待新窗口或标签页
wait.until(numberOfWindowsToBe(2))

// 循环执行，直到找到一个新的窗口句柄
for (windowHandle in driver.getWindowHandles()) {
if (!originalWindow.contentEquals(windowHandle)) {
driver.switchTo().window(windowHandle)
break
}
}

// 等待新标签页完成加载内容
wait.until(titleIs("Selenium documentation"))
```

```java
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L31-L34)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L46-L46)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L32-L35)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
    #关闭标签页或窗口
driver.close

    #切回到之前的标签页或窗口
driver.switch_to.window original_window
```

```javascript
//关闭标签页或窗口
await driver.close();

//切回到之前的标签页或窗口
await driver.switchTo().window(originalWindow);
```

```kotlin
//关闭标签页或窗口
driver.close()

//切回到之前的标签页或窗口
driver.switchTo().window(originalWindow)
```

```java
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L36-L42)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L53-L58)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L37-L43)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

打开新标签页并切换到新标签页

```rb
    driver.switch_to.new_window(:tab)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/windows_spec.rb#L9)

##### /examples/ruby/spec/interactions/windows\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Windows' do
  let(:driver) { start_session }

  it 'opens new tab' do
    driver.switch_to.new_window(:tab)

    expect(driver.window_handles.size).to eq 2
  end

  it 'opens new window' do
    driver.switch_to.new_window(:window)

    expect(driver.window_handles.size).to eq 2
  end
end
```

打开一个新窗口并切换到新窗口

```rb
    driver.switch_to.new_window(:window)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/windows_spec.rb#L15)

##### /examples/ruby/spec/interactions/windows\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Windows' do
  let(:driver) { start_session }

  it 'opens new tab' do
    driver.switch_to.new_window(:tab)

    expect(driver.window_handles.size).to eq 2
  end

  it 'opens new window' do
    driver.switch_to.new_window(:window)

    expect(driver.window_handles.size).to eq 2
  end
end
```

// 打开新标签页并切换到新标签页

```js
    await driver.switchTo().newWindow('tab');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L70)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

// 打开一个新窗口并切换到新窗口

```js
    await driver.switchTo().newWindow('window');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L75)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// 打开新标签页并切换到新标签页
driver.switchTo().newWindow(WindowType.TAB)

// 打开一个新窗口并切换到新窗口
driver.switchTo().newWindow(WindowType.WINDOW)
```

```java
        //quitting driver
        driver.quit(); //close all windows
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L44-L45)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L13-L13)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //quitting driver
              driver.Quit(); //close all windows
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L45-L46)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
driver.quit
```

```javascript
await driver.quit();
```

```kotlin
driver.quit()
```

```java
/**
* 使用 JUnit 的例子
* https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
*/
@AfterAll
public static void tearDown() {
    driver.quit();
}
```

```python
    # unittest teardown
    # https://docs.python.org/3/library/unittest.html?highlight=teardown#unittest.TestCase.tearDown
def tearDown(self):
self.driver.quit()
```

```csharp
/*
使用 Visual Studio 的 UnitTesting 的例子
https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.aspx
*/
[TestCleanup]
public void TearDown()
{driver.Quit();
}
```

```ruby
    # UnitTest Teardown
    # https://www.rubydoc.info/github/test-unit/test-unit/Test/Unit/TestCase
def teardown
@driver.quit
end
```

```javascript
/**
* 使用 Mocha 的例子
* https://mochajs.org/#hooks
  */
  after('Tear down', async function () {await driver.quit();
  });
  
```

```kotlin
/**
* 使用 JUnit 的例子
* https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
*/
@AfterAll
fun tearDown() {
	driver.quit()
}
```

```java
try {
    //WebDriver 代码…
} finally {
    driver.quit();
}
```

```python
try:
    #WebDriver 代码…
finally:
driver.quit()
```

```csharp
try {//WebDriver 代码…} finally {driver.Quit();
}
```

```ruby
begin
    #WebDriver 代码…
ensure
driver.quit
end
```

```javascript
try {//WebDriver 代码…} finally {await driver.quit();
}
```

```kotlin
try {//WebDriver 代码…} finally {driver.quit()
}
```

Python 的 WebDriver 现在支持 Python 上下文管理器，当使用 with 关键字时，可以在执行结束时自动退出驱动程序。

```python
with webdriver.Firefox() as driver:
  # WebDriver 代码…

# 在此缩进位置后 WebDriver 会自动退出
```

```java
// 分别获取每个尺寸
int width = driver.manage().window().getSize().getWidth();
int height = driver.manage().window().getSize().getHeight();

// 或者存储尺寸并在以后查询它们
Dimension size = driver.manage().window().getSize();
int width1 = size.getWidth();
int height1 = size.getHeight();
```

```python
    # 分别获取每个尺寸
width = driver.get_window_size().get("width")
height = driver.get_window_size().get("height")

    # 或者存储尺寸并在以后查询它们
size = driver.get_window_size()
width1 = size.get("width")
height1 = size.get("height")
```

```csharp
// 分别获取每个尺寸
int width = driver.Manage().Window.Size.Width;
int height = driver.Manage().Window.Size.Height;

// 或者存储尺寸并在以后查询它们
System.Drawing.Size size = driver.Manage().Window.Size;
int width1 = size.Width;
int height1 = size.Height;
```

```ruby
    # 分别获取每个尺寸
width = driver.manage.window.size.width
height = driver.manage.window.size.height

    # 或者存储尺寸并在以后查询它们
size = driver.manage.window.size
width1 = size.width
height1 = size.height
```

分别获取每个尺寸

```js
    const { width, height } = await driver.manage().window().getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L93)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

或者存储尺寸并在以后查询它们

```js
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L96-L98)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// 分别获取每个尺寸
val width = driver.manage().window().size.width
val height = driver.manage().window().size.height

// 或者存储尺寸并在以后查询它们
val size = driver.manage().window().size
val width1 = size.width
val height1 = size.height
```

```java
driver.manage().window().setSize(new Dimension(1024, 768));
```

```python
driver.set_window_size(1024, 768)
```

```csharp
driver.Manage().Window.Size = new Size(1024, 768);
```

```ruby
driver.manage.window.resize_to(1024,768)
```

```javascript
await driver.manage().window().setRect({width: 1024, height: 768});
```

```kotlin
driver.manage().window().size = Dimension(1024, 768)
```

```java
// 分别获取每个尺寸
int x = driver.manage().window().getPosition().getX();
int y = driver.manage().window().getPosition().getY();

// 或者存储尺寸并在以后查询它们
Point position = driver.manage().window().getPosition();
int x1 = position.getX();
int y1 = position.getY();
```

```python
    # 分别获取每个尺寸
x = driver.get_window_position().get('x')
y = driver.get_window_position().get('y')

    # 或者存储尺寸并在以后查询它们
position = driver.get_window_position()
x1 = position.get('x')
y1 = position.get('y')
```

```csharp
// 分别获取每个尺寸
int x = driver.Manage().Window.Position.X;
int y = driver.Manage().Window.Position.Y;

// 或者存储尺寸并在以后查询它们
Point position = driver.Manage().Window.Position;
int x1 = position.X;
int y1 = position.Y;
```

```ruby
    #Access each dimension individually
x = driver.manage.window.position.x
y = driver.manage.window.position.y

    # Or store the dimensions and query them later
rect  = driver.manage.window.rect
x1 = rect.x
y1 = rect.y
```

分别获取每个尺寸

```js
    const { x, y } = await driver.manage().window().getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L108)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

或者存储尺寸并在以后查询它们

```js
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L111-L113)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// 分别获取每个尺寸
val x = driver.manage().window().position.x
val y = driver.manage().window().position.y

// 或者存储尺寸并在以后查询它们
val position = driver.manage().window().position
val x1 = position.x
val y1 = position.y
```

```java
// 将窗口移动到主显示器的左上角
driver.manage().window().setPosition(new Point(0, 0));
```

```python
    # 将窗口移动到主显示器的左上角
driver.set_window_position(0, 0)
```

```csharp
// 将窗口移动到主显示器的左上角
driver.Manage().Window.Position = new Point(0, 0);
```

```ruby
driver.manage.window.move_to(0,0)
```

```javascript
// 将窗口移动到主显示器的左上角
await driver.manage().window().setRect({x: 0, y: 0});
```

```kotlin
// 将窗口移动到主显示器的左上角
driver.manage().window().position = Point(0,0)
```

```java
driver.manage().window().maximize();
```

```python
driver.maximize_window()
```

```csharp
driver.Manage().Window.Maximize();
```

```ruby
driver.manage.window.maximize
```

```javascript
await driver.manage().window().maximize();
```

```kotlin
driver.manage().window().maximize()
```

```java
driver.manage().window().minimize();
```

```python
driver.minimize_window()
```

```csharp
driver.Manage().Window.Minimize();
```

```ruby
driver.manage.window.minimize
```

```javascript
await driver.manage().window().minimize();
```

```kotlin
driver.manage().window().minimize()
```

```java
driver.manage().window().fullscreen();
```

```python
driver.fullscreen_window()
```

```csharp
driver.Manage().Window.FullScreen();
```

```ruby
driver.manage.window.full_screen
```

```javascript
await driver.manage().window().fullscreen();
```

```kotlin
driver.manage().window().fullscreen()
```

```java
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.*;
import org.openqa.selenium.*;

public class SeleniumTakeScreenshot {
	public static void main(String args[]) throws IOException {
		WebDriver driver = new ChromeDriver();
		driver.get("http://www.example.com");
		File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
		FileUtils.copyFile(scrFile, new File("./image.png"));
		driver.quit();
	}
}
```

```python
from selenium import webdriver

driver = webdriver.Chrome()

    # Navigate to url
driver.get("http://www.example.com")

    # Returns and base64 encoded string into image
driver.save_screenshot('./image.png')

driver.quit()
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;

    var driver = new ChromeDriver();
    driver.Navigate().GoToUrl("http://www.example.com");
    Screenshot screenshot = (driver as ITakesScreenshot).GetScreenshot();
    screenshot.SaveAsFile("screenshot.png", ScreenshotImageFormat.Png); // Format values are Bmp, Gif, Jpeg, Png, Tiff
```

```ruby
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
driver.get 'https://example.com/'

    # Takes and Stores the screenshot in specified path
driver.save_screenshot('./image.png')

end
```

```js
    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L56-L59)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
import com.oracle.tools.packager.IOUtils.copyFile
import org.openqa.selenium.*
import org.openqa.selenium.chrome.ChromeDriver
import java.io.File

fun main(){
val driver =  ChromeDriver()
driver.get("https://www.example.com")
val scrFile = (driver as TakesScreenshot).getScreenshotAs<File>(OutputType.FILE)
copyFile(scrFile, File("./image.png"))
driver.quit()
}
```

```java
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.File;
import java.io.IOException;

public class SeleniumelementTakeScreenshot {
public static void main(String args[]) throws IOException {
	WebDriver driver = new ChromeDriver();
		driver.get("https://www.example.com");
		WebElement element = driver.findElement(By.cssSelector("h1"));
		File scrFile = element.getScreenshotAs(OutputType.FILE);
		FileUtils.copyFile(scrFile, new File("./image.png"));
		driver.quit();
	}
}
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

    # Navigate to url
driver.get("http://www.example.com")

ele = driver.find_element(By.CSS_SELECTOR, 'h1')

    # Returns and base64 encoded string into image
ele.screenshot('./image.png')

driver.quit()
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Support.UI;

    // Webdriver
    var driver = new ChromeDriver();
    driver.Navigate().GoToUrl("http://www.example.com");

    // Fetch element using FindElement
    var webElement = driver.FindElement(By.CssSelector("h1"));

    // Screenshot for the element
    var elementScreenshot = (webElement as ITakesScreenshot).GetScreenshot();
    elementScreenshot.SaveAsFile("screenshot_of_element.png");
```

```ruby
    # Works with Selenium4-alpha7 Ruby bindings and above
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
driver.get 'https://example.com/'
ele = driver.find_element(:css, 'h1')

    # Takes and Stores the element screenshot in specified path
ele.save_screenshot('./image.jpg')
end
```

```js
    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L44-L48)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
import org.apache.commons.io.FileUtils
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.*
import java.io.File

fun main() {
val driver = ChromeDriver()
driver.get("https://www.example.com")
val element = driver.findElement(By.cssSelector("h1"))
val scrFile: File = element.getScreenshotAs(OutputType.FILE)
FileUtils.copyFile(scrFile, File("./image.png"))
driver.quit()
}
```

```java
//Creating the JavascriptExecutor interface object by Type casting
JavascriptExecutor js = (JavascriptExecutor)driver;
//Button Element
WebElement button =driver.findElement(By.name("btnLogin"));
//Executing JavaScript to click on element
js.executeScript("arguments[0].click();", button);
//Get return value from script
String text = (String) js.executeScript("return arguments[0].innerText", button);
//Executing JavaScript directly
js.executeScript("console.log('hello world')");
```

```python
    # Stores the header element
header = driver.find_element(By.CSS_SELECTOR, "h1")

    # Executing JavaScript to capture innerText of header element
driver.execute_script('return arguments[0].innerText', header)
```

```csharp
//creating Chromedriver instance
	IWebDriver driver = new ChromeDriver();
	//Creating the JavascriptExecutor interface object by Type casting
	IJavaScriptExecutor js = (IJavaScriptExecutor) driver;
	//Button Element
	IWebElement button = driver.FindElement(By.Name("btnLogin"));
	//Executing JavaScript to click on element
	js.ExecuteScript("arguments[0].click();", button);
	//Get return value from script
	String text = (String)js.ExecuteScript("return arguments[0].innerText", button);
	//Executing JavaScript directly
	js.ExecuteScript("console.log('hello world')");
```

```ruby
    # Stores the header element
header = driver.find_element(css: 'h1')

    # Get return value from script
result = driver.execute_script("return arguments[0].innerText", header)

    # Executing JavaScript directly
driver.execute_script("alert('hello world')")
```

```js
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L33-L37)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Stores the header element
val header = driver.findElement(By.cssSelector("h1"))

// Get return value from script
val result = driver.executeScript("return arguments[0].innerText", header)

// Executing JavaScript directly
driver.executeScript("alert('hello world')")
```

```java
import org.openqa.selenium.print.PrintOptions;

driver.get("https://www.selenium.dev");
printer = (PrintsPage) driver;

PrintOptions printOptions = new PrintOptions();
printOptions.setPageRanges("1-2");

Pdf pdf = printer.print(printOptions);
String content = pdf.getContent();
```

```python
from selenium.webdriver.common.print_page_options import PrintOptions

    print_options = PrintOptions()
    print_options.page_ranges = ['1-2']

    driver.get("printPage.html")

    base64code = driver.print_page(print_options)
```

```csharp
// code sample not available please raise a PR
```

```ruby
driver.navigate_to 'https://www.selenium.dev'

    base64encodedContent = driver.print_page(orientation: 'landscape')
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L22-L25)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
driver.get("https://www.selenium.dev")
val printer = driver as PrintsPage

val printOptions = PrintOptions()
printOptions.setPageRanges("1-2")

val pdf: Pdf = printer.print(printOptions)
val content = pdf.content
```

# 7 - 虚拟身份验证器

```java
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L55-L61)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L48-55)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L40-L46)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setHasUserVerification(true);
    options.setIsUserConsenting(true);
    options.setTransport(Transport['USB']);
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    assert(Object.keys(options).length === 6);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticatorOptions.spec.js#L11-L17)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticatorOptions.spec.js

```js
const {VirtualAuthenticatorOptions, Transport, Protocol} = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')


describe('Virtual authenticator options', function () {
  let options;

  it('Virtual options', async function () {
    options = new VirtualAuthenticatorOptions();
    options.setIsUserVerified(true);
    options.setHasUserVerification(true);
    options.setIsUserConsenting(true);
    options.setTransport(Transport['USB']);
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    assert(Object.keys(options).length === 6);
  });

  it('User verified', async function () {
    options.setIsUserVerified(true);

    assert(options.toDict()['isUserVerified']);
  });
});
```

```java
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L68-L73)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L63-71)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L53-L58)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L51-L55)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L86)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#80-86)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L68-L74)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L62-L63)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L100-L103)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#103-107)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L89-L97)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L80-L94)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L143-L145)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L145-148)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L140-L147)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L136-L140)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L137-L146)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L139-150)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.add_credential(credential)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L150)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L131-L142)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L157-L171)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L162-178)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    credential_list = driver.get_credentials()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L183)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L154-L170)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

## 删除凭据

根据传递的凭据ID从身份验证器中删除凭据。

```cs
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L189-198)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

*
*
*
*
*
*

```java
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L181-L190)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.remove_credential(credential.id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L209)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```java
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L196-L205)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L207-216)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.remove_all_credentials()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L239)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L181-L190)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L211-L212)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L224-225)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L245-L247)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setIsUserVerified(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L197-L197)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

----
url: https://www.selenium.dev/ja/_print/documentation/webdriver/support_features/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/webdriver/support_features/).

# サポート機能

サポート クラスは、オプションの上位レベル機能を提供します。

* 1: [Waiting with Expected Conditions](#pg-a328718bb74e2d303087278644029bd3)
* 2: [Command Listeners](#pg-17fa15089dfd67bf26cb59d93c853527)
* 3: [色を扱う](#pg-e1f3dc61cf0ac0af8d3f633e7c05fccc)
* 4: [選択要素の操作](#pg-e04b0f600159cea89d2bbe45c389a15c)
* 5: [ThreadGuard](#pg-29d835cb8ee678c4cfd046813596fd01)

The core libraries of Selenium try to be low level and non-opinionated. The Support classes in each language provide opinionated wrappers for common interactions that may be used to simplify some behaviors.

# 1 - Waiting with Expected Conditions

```py
    wait = WebDriverWait(driver, timeout=2)
    wait.until(EC.visibility_of_element_located((By.ID, "revealed")))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_expected_conditions.py#L14-L15)

##### /examples/python/tests/support/test\_expected\_conditions.py

```py
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

# Expected Conditions API Documentation:
# https://www.selenium.dev/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html


def test_expected_condition(driver):
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html")
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(EC.visibility_of_element_located((By.ID, "revealed")))

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"
```

# 3 - 色を扱う

```java
import org.openqa.selenium.support.Color;
  
```

```python
from selenium.webdriver.support.color import Color
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
include Selenium::WebDriver::Support
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
import org.openqa.selenium.support.Color
```

```java
private final Color HEX_COLOUR = Color.fromString("#2F7ED8");
private final Color RGB_COLOUR = Color.fromString("rgb(255, 255, 255)");
private final Color RGB_COLOUR = Color.fromString("rgb(40%, 20%, 40%)");
private final Color RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)");
private final Color RGBA_COLOUR = Color.fromString("rgba(40%, 20%, 40%, 0.5)");
private final Color HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)");
private final Color HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)");
  
```

```python
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
private val HEX_COLOUR = Color.fromString("#2F7ED8")
private val RGB_COLOUR = Color.fromString("rgb(255, 255, 255)")
private val RGB_COLOUR_PERCENT = Color.fromString("rgb(40%, 20%, 40%)")
private val RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)")
private val RGBA_COLOUR_PERCENT = Color.fromString("rgba(40%, 20%, 40%, 0.5)")
private val HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)")
private val HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)")
  
```

```java
private final Color BLACK = Color.fromString("black");
private final Color CHOCOLATE = Color.fromString("chocolate");
private final Color HOTPINK = Color.fromString("hotpink");
  
```

```python
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
private val BLACK = Color.fromString("black")
private val CHOCOLATE = Color.fromString("chocolate")
private val HOTPINK = Color.fromString("hotpink")
  
```

```java
private final Color TRANSPARENT = Color.fromString("transparent");
  
```

```python
TRANSPARENT = Color.from_string('transparent')
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
TRANSPARENT = Color.from_string('transparent')
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
private val TRANSPARENT = Color.fromString("transparent")
  
```

```java
Color loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"));

Color loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"));
  
```

```python
login_button_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('color'))

login_button_background_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('background-color'))
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
login_button_colour = Color.from_string(driver.find_element(id: 'login').css_value('color'))

login_button_background_colour = Color.from_string(driver.find_element(id: 'login').css_value('background-color'))
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
val loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"))

val loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"))
  
```

```java
assert loginButtonBackgroundColour.equals(HOTPINK);
  
```

```python
assert login_button_background_colour == HOTPINK
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
assert(login_button_background_colour == HOTPINK)
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
assert(loginButtonBackgroundColour.equals(HOTPINK))
  
```

```java
assert loginButtonBackgroundColour.asHex().equals("#ff69b4");
assert loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)");
assert loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)");
  
```

```python
assert login_button_background_colour.hex == '#ff69b4'
assert login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)'
assert login_button_background_colour.rgb == 'rgb(255, 105, 180)'
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
assert(login_button_background_colour.hex == '#ff69b4')
assert(login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)')
assert(login_button_background_colour.rgb == 'rgb(255, 105, 180)')
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
assert(loginButtonBackgroundColour.asHex().equals("#ff69b4"))
assert(loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)"))
assert(loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)"))
  
```

色はもはや問題ではありません。

# 4 - 選択要素の操作

```html
<select name="selectomatic">
    <option selected="selected" id="non_multi_option" value="one">One</option>
    <option value="two">Two</option>
    <option value="four">Four</option>
    <option value="still learning how to count, apparently">Still learning how to count, apparently</option>
</select>
```

### Multiple select

This select list allows selecting and deselecting more than one option at a time. This only applies to `<select>` elements with the `multiple` attribute.

```html
<select name="multi" id="multi" multiple="multiple">
    <option selected="selected" value="eggs">Eggs</option>
    <option value="ham">Ham</option>
    <option selected="selected" value="sausages">Sausages</option>
    <option value="onion gravy">Onion gravy</option>
</select>
```

```java
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L23-L24)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L9-L10)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L23-L24)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L13-L14)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js

  it('Select an option', async function () {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L18-L19)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L20-L21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        List<WebElement> optionList = select.getOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L51)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    option_list = select.options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L37)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            IList<IWebElement> optionList = select.Options;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L52)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    option_list = select.options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L40)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L45)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val optionList = select.getOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L48)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L54)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    selected_option_list = select.all_selected_options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L40)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L56)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    selected_option_list = select.selected_options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L43)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L51)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val selectedOptionList = select.getAllSelectedOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L51)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByVisibleText("Four");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L30)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_visible_text('Four')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L16)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByText("Four");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L30)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:text, 'Four')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L20)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L25)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByVisibleText("Four")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L27)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByValue("two");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L33)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_value('two')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L19)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByValue("two");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L33)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:value, 'two')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L23)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await fourElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L28)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByValue("two")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L30)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByIndex(3);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L36)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_index(3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L22)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByIndex(3);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L36)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:index, 3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L26)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await twoElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L31)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByIndex(3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L33)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

### Disabled options

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

Options with a `disabled` attribute may not be selected.

```html
    <select name="single_disabled">
      <option id="sinlge_disabled_1" value="enabled">Enabled</option>
      <option id="sinlge_disabled_2" value="disabled" disabled="disabled">Disabled</option>
    </select>
```

*
*
*
*
*
*

```java
        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L77-L79)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L60-L61)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L77)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L62-L64)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L73-L76)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L74-L76)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.deselectByValue("eggs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L66)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.deselect_by_value('eggs')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L49)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.DeselectByValue("eggs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L65)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.deselect_by(:value, 'eggs')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L52)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await gravyElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L63)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.deselectByValue("eggs")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

# 5 - ThreadGuard

このクラスは、Javaバインディングでのみ使用可能です。

ThreadGuardは、ドライバーが、それを作成した同じスレッドからのみ呼び出されることを確認します。 特に並行してテストを実行する場合のスレッドの問題は、不可解でエラーの診断が難しい場合があります。 このラッパーを使用すると、このカテゴリのエラーが防止され、発生時に例外が発生します。

次の例は、スレッドの衝突をシミュレートします。

```java
public class DriverClash {
  //thread main (id 1) created this driver
  private WebDriver protectedDriver = ThreadGuard.protect(new ChromeDriver());

  static {
    System.setProperty("webdriver.chrome.driver", "<Set path to your Chromedriver>");
  }

  //Thread-1 (id 24) is calling the same driver causing the clash to happen
  Runnable r1 = () -> {protectedDriver.get("https://selenium.dev");};
  Thread thr1 = new Thread(r1);

  void runThreads(){
    thr1.start();
  }

  public static void main(String[] args) {
    new DriverClash().runThreads();
  }
}
```

結果は以下のとおりです。

```text
Exception in thread "Thread-1" org.openqa.selenium.WebDriverException:
Thread safety error; this instance of WebDriver was constructed
on thread main (id 1)and is being accessed by thread Thread-1 (id 24)
This is not permitted and *will* cause undefined behaviour
```

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/bidi/w3c/browsing_context/
----

# Browsing Context

```java
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L44-L47)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L33-L35)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

    @Test
    void testNavigateToAUrl() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L58-L61)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L48-L50)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L37-L41)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L25-L28)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L50-L55)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L40-L43)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        Assertions.assertNotNull(browsingContext.getId());
        Assertions.assertNotNull(info.getNavigationId());
        Assertions.assertTrue(info.getUrl().contains("/bidi/logEntryAdded.html"));
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L64-L69)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L55-L58)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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"));
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L72-L80)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L67)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L83-L92)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L79-L82)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        Assertions.assertTrue(info.getChildren().get(0).getUrl().contains("formPage.html"));
    }

    @Test
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L95-L108)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    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()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L90-L96)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    }

    @Test
    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());
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L111-L123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L103-L109)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window2.close();

        Assertions.assertThrows(BiDiException.class, window2::getTree);
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L126-L133)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.20.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.20.0.0)

```js
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L426-L431)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext tab2 = new BrowsingContext(driver, WindowType.TAB);

        tab2.close();

        Assertions.assertThrows(BiDiException.class, tab2::getTree);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L136-L153)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```js
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L115-L118)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L157-L161)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L192-L194)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```js
    await window1.activate()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L204)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L169-L173)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.reload(undefined, 'complete')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L351)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    @Test
    void testDismissUserPromptWithText() {
        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";
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L220-L228)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.handleUserPrompt(true, userText)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L301)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        driver.get("https://www.selenium.dev/selenium/web/coordinates_tests/simple_page.html");

        WebElement element = driver.findElement(By.id("box"));
        Rectangle elementRectangle = element.getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L248-L252)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const response = await browsingContext.captureScreenshot()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L362)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    }

    @Test
    void textCaptureElementScreenshot() {
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L259-L268)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L165-L169)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L275-L280)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    const response = await browsingContext.captureElementScreenshot(elementId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L184)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L304-L307)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0)

```js
    await browsingContext.setViewport(250, 300)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L335)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L317-L322)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    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'],
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L145-L157)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java

        wait.until(visibilityOfElementLocated(By.id("imageButton"))).submit();
        wait.until(titleIs("We Arrive Here"));

        browsingContext.back();
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L330-L336)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.back()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L396)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L342-L352)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.forward()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L420)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextTest.java#L359-L365)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.BiDiException;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationResult;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.remote.RemoteWebElement;
import org.openqa.selenium.support.ui.WebDriverWait;

import static org.openqa.selenium.support.ui.ExpectedConditions.titleIs;
import static org.openqa.selenium.support.ui.ExpectedConditions.visibilityOfElementLocated;

class BrowsingContextTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void testCreateABrowsingContextForGivenId() {
        String id = driver.getWindowHandle();
        BrowsingContext browsingContext = new BrowsingContext(driver, id);
        Assertions.assertEquals(id, browsingContext.getId());
    }

    @Test
    void testCreateAWindow() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.WINDOW);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    void testCreateATab() {
        BrowsingContext browsingContext = new BrowsingContext(driver, WindowType.TAB);
        Assertions.assertNotNull(browsingContext.getId());
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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"));
    }

    @Test
    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());
    }

    @Test
    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());
    }

    @Test
    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);
    }

    @Test
    void testActivateABrowsingContext() {
        BrowsingContext window1 = new BrowsingContext(driver, driver.getWindowHandle());
        BrowsingContext window2 = new BrowsingContext(driver, WindowType.WINDOW);

        window1.activate();

        boolean isFocused = (boolean) ((JavascriptExecutor) driver).executeScript("return document.hasFocus();");

        Assertions.assertTrue(isFocused);
    }

    @Test
    void testReloadABrowsingContext() {
        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);

        Assertions.assertNotNull(reloadInfo.getNavigationId());
        Assertions.assertTrue(reloadInfo.getUrl().contains("/bidi/logEntryAdded.html"));
    }

    @Test
    void testHandleUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt();

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testAcceptUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testDismissUserPrompt() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        driver.findElement(By.id("alert")).click();

        browsingContext.handleUserPrompt("true");

        Assertions.assertTrue(driver.getPageSource().contains("Testing Alerts and Stuff"));
    }

    @Test
    void testPassUserTextToUserPrompt() {
        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);

        Assertions.assertTrue(driver.getPageSource().contains(userText));
    }

    @Test
    void testDismissUserPromptWithText() {
        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(false, userText);

        Assertions.assertFalse(driver.getPageSource().contains(userText));
    }

    @Test
    void textCaptureScreenshot() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());

        driver.get("https://www.selenium.dev/selenium/web/alerts.html");

        String screenshot = browsingContext.captureScreenshot();

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureViewportScreenshot() {
        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);

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textCaptureElementScreenshot() {
        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());

        Assertions.assertFalse(screenshot.isEmpty());
    }

    @Test
    void textSetViewport() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300);

        List<Long> newViewportSize =
                (List<Long>)
                        ((JavascriptExecutor) driver)
                                .executeScript("return [window.innerWidth, window.innerHeight];");

        Assertions.assertEquals(250, newViewportSize.get(0));
        Assertions.assertEquals(300, newViewportSize.get(1));
    }

    @Test
    void textSetViewportWithDevicePixelRatio() {
        BrowsingContext browsingContext = new BrowsingContext(driver, driver.getWindowHandle());
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");

        browsingContext.setViewport(250, 300, 5);

        Long newDevicePixelRatio =
                (Long) ((JavascriptExecutor) driver).executeScript("return window.devicePixelRatio");

        Assertions.assertEquals(5, newDevicePixelRatio);
    }

    @Test
    void testPrintPage() {
        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);

        Assertions.assertFalse(printPage.isEmpty());
    }

    @Test
    void testNavigateBackInTheBrowserHistory() {
        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"));
    }

    @Test
    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();
        wait.until(titleIs("We Arrive Here"));
    }

    @Test
    void canTraverseBrowserHistory() {
        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);
        Assertions.assertTrue(driver.getPageSource().contains("We Leave From Here"));
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await browsingContext.traverseHistory(-1)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContext.spec.js#L378)

##### /examples/javascript/test/bidirectional/browsingContext.spec.js

```js
const {By, until, Builder} = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');
const BrowsingContext = require('selenium-webdriver/bidi/browsingContext');
const assert = require("assert");

describe('Browsing Context', function () {
  let driver
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let pngMagicNumber = 'iVBOR'

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test create a browsing context for given id', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    assert.equal(browsingContext.id, id)
  })

  it('test create a window', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a window with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'window',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test create a tab with a reference context', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
      referenceContext: await driver.getWindowHandle(),
    })
    assert.notEqual(browsingContext.id, null)
  })

  it('test navigate to a url', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    let info = await browsingContext.navigate('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test navigate to a url with readiness state', async function () {
    const browsingContext = await BrowsingContext(driver, {
      type: 'tab',
    })

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html',
      'complete'
    )

    assert.notEqual(browsingContext.id, null)
    assert.notEqual(info.navigationId, null)
    assert(info.url.includes('/bidi/logEntryAdded.html'))
  })

  it('test get tree with a child', async function () {
    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()
    assert.equal(contextInfo.children.length, 1)
    assert.equal(contextInfo.id, browsingContextId)
    assert(contextInfo.children[0]['url'].includes('formPage.html'))
  })

  it('test get tree with depth', async function () {
    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)
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.id, browsingContextId)
  })

  it('test close a window', async function () {
    const window1 = await BrowsingContext(driver, {type: 'window'})
    const window2 = await BrowsingContext(driver, {type: 'window'})

    await window2.close()

    assert.doesNotThrow(async function () {
      await window1.getTree()
    })
    await assert.rejects(window2.getTree(), {message: 'no such frame'})
  })

  it('test close a tab', async function () {
    const tab1 = await BrowsingContext(driver, {type: 'tab'})
    const tab2 = await BrowsingContext(driver, {type: 'tab'})

    await tab2.close()

    assert.doesNotThrow(async function () {
      await tab1.getTree()
    })
    await assert.rejects(tab2.getTree(), {message: 'no such frame'})
  })

  it('can print PDF with all valid parameters', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/printPage.html")
    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'],
    })

    let base64Code = result.data.slice(0, 5)
    assert.strictEqual(base64Code, 'JVBER')
  })

  it('can take box screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureBoxScreenshot(5, 5, 10, 10)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can take element screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/formPage.html")
    const element = await driver.findElement(By.id('checky'))
    const elementId = await element.getId()
    const response = await browsingContext.captureElementScreenshot(elementId)

    const base64code = response.slice(0, 5)
    assert.equal(base64code, 'iVBOR')
  })

  it('can activate a browsing context', async function () {
    const id = await driver.getWindowHandle()
    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()
    const result2 = await driver.executeScript('return document.hasFocus();')

    assert.equal(result2, true)
  })

  it('can handle user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt()

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can accept user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(true)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can dismiss user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    await browsingContext.handleUserPrompt(false)

    const result = await driver.getTitle()

    assert.equal(result, 'Testing Alerts')
  })

  it('can pass user text to user prompt', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(undefined, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can accept user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('prompt')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(true, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), true)
  })

  it('can dismiss user prompt with user text', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/alerts.html")

    await driver.findElement(By.id('alert')).click()

    await driver.wait(until.alertIsPresent())

    const userText = 'Selenium automates browsers'

    await browsingContext.handleUserPrompt(false, userText)

    const result = await driver.getPageSource()
    assert.equal(result.includes(userText), false)
  })

  it('can set viewport', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await driver.get("https://www.selenium.dev/selenium/web/blank.html")

    await browsingContext.setViewport(250, 300)

    const result = await driver.executeScript('return [window.innerWidth, window.innerHeight];')
    assert.equal(result[0], 250)
    assert.equal(result[1], 300)
  })

  it('can reload a browsing context', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const result = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html', 'complete')

    await browsingContext.reload(undefined, 'complete')
    assert.notEqual(result.navigationId, null)
    assert(result.url.includes('/bidi/logEntryAdded.html'))
  })

  it('can take screenshot', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    const response = await browsingContext.captureScreenshot()
    const base64code = response.slice(startIndex, endIndex)
    assert.equal(base64code, pngMagicNumber)
  })

  it('can traverse browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.traverseHistory(-1)

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate back in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)
  })

  it('can navigate forward in browser history', async function () {
    const id = await driver.getWindowHandle()
    const browsingContext = await BrowsingContext(driver, {
      browsingContextId: id,
    })

    await browsingContext.navigate('https://www.selenium.dev/selenium/web/formPage.html', 'complete')

    await driver.wait(until.elementLocated(By.id('imageButton'))).submit()
    await driver.wait(until.titleIs('We Arrive Here'), 2500)

    await browsingContext.back()

    const source = await driver.getPageSource()

    assert.equal(source.includes('We Leave From Here'), true)

    await browsingContext.forward()

    await driver.wait(until.titleIs('We Arrive Here'), 2500)
  });

  it('Get All Top level browsing contexts', async () => {
    const id = await driver.getWindowHandle()
    const window1 = await BrowsingContext(driver, {
      browsingContextId: id,
    })
    await BrowsingContext(driver, { type: 'window' })
    const res = await window1.getTopLevelContexts()
    assert.equal(res.length, 2)
  })
})
```

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L34-L41)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L23-L28)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L54-L63)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L53-L62)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L81-88)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.2.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L70-L78)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L97-104)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L113-123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.15.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.15.0.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L86-L97)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L113-123)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L150-163)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/BrowsingContextInspectorTest.java#L170-L181)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/BrowsingContextInspectorTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.BrowsingContextInspector;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContextInfo;
import org.openqa.selenium.bidi.browsingcontext.NavigationInfo;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.browsingcontext.UserPromptClosed;
import org.openqa.selenium.bidi.browsingcontext.UserPromptOpened;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class BrowsingContextInspectorTest extends BaseTest {
    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToWindowBrowsingContextCreatedEvent()
        throws ExecutionException, InterruptedException, TimeoutException {
    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);

        Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToTabBrowsingContextCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<BrowsingContextInfo> future = new CompletableFuture<>();
            inspector.onBrowsingContextCreated(future::complete);

            String windowHandle = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();

            BrowsingContextInfo browsingContextInfo = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals(windowHandle, browsingContextInfo.getId());
        }
    }

    @Test
    void canListenToDomContentLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<NavigationInfo> future = new CompletableFuture<>();
            inspector.onDomContentLoaded(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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToBrowsingContextLoadedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToNavigationStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("bidi/logEntryAdded"));
        }
    }

    @Test
    void canListenToFragmentNavigatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);

            Assertions.assertTrue(navigationInfo.getUrl().contains("linkToAnchorOnThisPage"));
        }
    }

    @Test
    void canListenToUserPromptOpenedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (BrowsingContextInspector inspector = new BrowsingContextInspector(driver)) {
            CompletableFuture<UserPromptOpened> future = new CompletableFuture<>();

            BrowsingContext context = new BrowsingContext(driver, driver.getWindowHandle());
            inspector.onUserPromptOpened(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/alerts.html");

            driver.findElement(By.id("alert")).click();

            UserPromptOpened userPromptOpened = future.get(5, TimeUnit.SECONDS);
            Assertions.assertEquals(context.getId(), userPromptOpened.getBrowsingContextId());
        }
    }

    @Test
    void canListenToUserPromptClosedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    void canListenToBrowsingContextDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
            Assertions.assertTrue(browsingContextInfo.getUrl().contains("about:blank"));
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0.0)

```js
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/browsingContextInspector.spec.js#L105-L113)

##### /examples/javascript/test/bidirectional/browsingContextInspector.spec.js

```js
const BrowsingContextInspector = require("selenium-webdriver/bidi/browsingContextInspector");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const {Builder} = require("selenium-webdriver");

describe('Browsing Context Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to window browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')
    const windowHandle = await driver.getWindowHandle()
    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to tab browsing context created event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextCreated((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('tab')
    const tabHandle = await driver.getWindowHandle()

    assert.equal(contextInfo.id, tabHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children, null)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })

  it('can listen to dom content loaded event', async function () {
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to browsing context loaded event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('/bidi/logEntryAdded.html'), true)
  })

  it('can listen to fragment navigated event', async function () {
    let navigationInfo = null
    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')

    assert.equal(navigationInfo.browsingContextId, browsingContext.id)
    assert.strictEqual(navigationInfo.url.includes('linkToAnchorOnThisPage'), true)
  })

  it('can listen to browsing context destroyed event', async function () {
    let contextInfo = null
    const browsingContextInspector = await BrowsingContextInspector(driver)
    await browsingContextInspector.onBrowsingContextDestroyed((entry) => {
      contextInfo = entry
    })

    await driver.switchTo().newWindow('window')

    const windowHandle = await driver.getWindowHandle()
    await driver.close()

    assert.equal(contextInfo.id, windowHandle)
    assert.equal(contextInfo.url, 'about:blank')
    assert.equal(contextInfo.children.length, 0)
    assert.equal(contextInfo.parentBrowsingContext, null)
  })
})
```

----
url: https://www.selenium.dev/documentation/about/history/
----

# Musings about how things came to be

Details mostly of interest to Selenium devs about how and why certain parts of the project were created

This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/History)

## Introduction

This is a work in progress. Feel free to add things you know or remember.

### How did the Automation Atoms come about?

On 2012-04-04, jimevans asked on the #selenium IRC channel:

> “What I wanted to ask you about was the history of the automation atoms. I seem to remember them springing fully formed, as if from the head of Zeus, and I’m sure that wasn’t the case. Can you refresh my memory as to how the concept happened?”

simonstewart then proceeded to tell us a nice little story:

> Sure. Are we sitting comfortably? Then I’ll begin. (Brit joke, there)

> Imagine wavy lines as the screen dissolves and we’re transported back to when selenium and webdriver were different projects. Before the projects merged, there was an awful lot of congruent code in webdriver. Congruent, but not shared. The Firefox driver was in JS. The IE driver was mostly C++. The Chrome driver was mostly JS, but different JS from the Firefox driver. And HtmlUnit was unique.

> We then added Selenium Core to the mix. Yet more JS that did basically the same thing.

> Within Google, I was becoming the TL of the browser automation team. And was corralling a framework of our own into the mix. Which was written in JS, and had once been based on Core before it span off on its own path.

> So: multiple codebases, lots of JS doing more or less the same thing. And loads of bugs. Weird mismatches of behaviour in edge-cases.

> `*shudder*`

> So I had a bit of a think. (Dangerous, I know) The idea was to extract the “best of breed” code from all three frameworks (Core, WebDriver and the Google tool). Break them down into code that could be shared. “The smallest, indivisible unit of browser automation” .

> Or “atoms” for short.

> These could be used as the basis the *everything*. Consistent behaviour between browsers. and apis. The other important point was that the JS code in webdriver and core was grown organically. Which is a polite way of saying “I’d rather never edit it again”. Which is a polite way of saying that it was of dubious quality . In places.

> So: high quality was important. And I wanted the code broken up into modules. Because editing a 10k LOC file isn’t a bright idea.

> Within Google we had a library called Closure. Which not only allowed modularization, but “denormalization” of modules into a single file via compilation. And I knew it was being open sourced. So we started building the library in the google codebase. (Where we had access to the unreleased library, code review tools and our amazing testing infrastructure). Using Closure Library.

> “dom.js” was probably the first file I wrote. (We can check). Greg Dennis and Jason Leyba joined in the fun. And the atoms have been growing ever since.

> Technically, we should be calling anything outside of “javascript/atoms” molecules. But then we can’t say that we have atomic drivers. and use imagery from the 50s to describe them.

> `*sigh*`

jimevans replied: “molecular drivers?”

And simonstewart finished with:

> Indeed :) The idea is that the atoms are the lowest level. And we compose the atoms to conform to the WebDriver or RC apis in “javascript/{selenium,webdriver}-atoms” respecitively. And then suck those in as necessary.

### A Story of Crazy-Fun

Simon Stewart :

> So, let’s go back to the very beginning of the project

> When it was me, on my own\
> (the webdriver project, that is, not selenium itself)\
> I knew that I wanted to cover multiple different languages, and so wanted a build tool that could work with all of them\
> That is, that didn't have a built in preference for one that made working with other languages painful\
> ant is java biased. As is maven.\
> nant and msbuild are .net biased\
> rake, otoh, supports nothing very well\
> But, and this is key, any valid rake script is also a valid ruby program\
> It's possible to extend rake to build *anything*\
> So: rake it was\
> The initial rake file was pretty small and manageable\
> But as the project grew, so did the Rakefile\
> Until there was only person who could deal with it (me), and even then it was pretty shaky\
> So, rather than have a project that couldn't be built, I extracted some helper methods to do some of the heavy lifting\
> Which made the Rakefile comprehensible again\
> But they project kept. getting. bigger\
> And the Rakefile got harder and harder to grok\
> At the time, I was working at Google, who have a wonderful build system\
> Google's system is declarative and works across multiple different languages consistently\
> And, most important, it breaks up the build from a single file into little fragments\
> I asked the OSS chaps at Google if it was okay to open source the build grammar, and they gave it the green light\
> So we layered that build grammar into the selenium codebase\
> With one minor change (we handle dictionary args)\
> But that grammar sits on top of rake\
> still, after all this time\
> And there's a problem\
> And that's that rake is single threaded\
> So our builds are constrained to run serially\
> We could use "multitask" types to improve things, but when I've tried that things got very messy, very fast\
> So, our next hurdle is that crazyfun.rb is slow: we need to go faster\
> Which implies a rewrite of crazyfun\
> I'm most comfortable in java\
> So, I've spiked a new version in java that handles the java and js compilation\
> It's significantly faster\
> But, and this is also important, it's a spike\
> The code was designed to be disposable.\
> Now that things have been proved out, I'd really like to do a clean implementation\
> But I'm torn\
> Do I "finish" the new, very fast crazyfun java enough to replace the ruby version?

### A story of driver executeables

> jimevans\
> noob\_einsteinsfo: alright, story time, then. are we sitting comfortably? then we'll begin.\
> noob\_einsteinsfo: back when i first started working on the project (circa 2010), the drivers for all of the browsers were built and maintained by the project.\
> at the time, that meant IE, firefox, and chrome.\
> all of those drivers were packaged as part of the selenium standalone server, and were also packaged in with the various language bindings.\
> this was a conscious decision, so that if one were running locally, there would be no need for the java runtime on the machine just to automate a given browser.\
> there were two factors that led to the development of browser drivers as separate executables.\
> as a quick aside, remember that the webdriver philosophy is to automate the browser using the "best-fit" mechanism for that particular browser.\
> for IE, that means using the COM interfaces; for firefox at the time, that meant using a browser extension; for chrome, it also meant a browser extension.\
> so that meant that the IE driver was developed as a DLL in C++ that was loaded by the language bindings, and communicated with via whatever native-code mechanism was provided by the language (JNI for java, P/Invoke for .NET, ctypes for python, etc.).\
> it also meant that the firefox driver was developed as a browser extension that was packaged inside the various language bindings, and extracted, and used in a profile in firefox.\
> as i said, the IE driver was implemented as a DLL, loaded and communicated with using different mechanisms for different language bindings.\
> the problem is that each of those language-specific mechanisms had different load/unload semantics.\
> ruby, for example, would never call the windows FreeLibrary API after loading the DLL into memory, making multiple instances really challenging.\
> \*process\* semantics, however, as in, starting, stopping, and managing the lifetime of a process on the OS, whatever the OS, are remarkably similar across all languages.\
> so when the IE driver rewrite was completed in 2010, the development team (me) decided to make it a separate executable, so that the load/unload semantics could be consistent no matter what language bindings one was using.\
> concurrently with this, the chromium team made the decision to follow opera's lead and provide a driver implementation for chrome.\
> an implementation that they would develop, enhance, and maintain going forward, relieving the selenium project of the burden of maintaining a chrome driver.\
> \
> XgizmoX\
> and that driver is part of the browser?\
> \
> jimevans\
> XgizmoX: not really, but i believe there may be some smarts built into chrome itself that knows when it's being automated via chromedriver. one of the googlers would be a better person to ask about that.\
> anyway, knowing the different in shared library (.dll/.so/.dynlib) loading semantics, the chromium team (with my encouragement) decided to release their chromedriver implementation as a separate executable.\
> fast-forward a couple of years, and you begin to see the effort to make webdriver a w3c standard.\
> a working group with the w3c created a specification (still in progress, but getting close to finished with the first version), which codified the behavior of webdriver, and how a browser should react to its methods. furthermore, it standardized the protocol used to communicate between language bindings and a driver for a particular browser.\
> i can't emphasize how important and groundbreaking this was.\
> because the w3c and the webdriver working group within it are made up of representatives from the browser vendors themselves, it ensures that the solution will be supported directly by the browser vendors.\
> mozilla created their webdriver implementation (geckodriver) for firefox.\
> the most efficient mechanism for distribution of that browser driver, while maintaining the proper semantics for the language bindings, was to ship as a separate executable.\
> note, this is a gross oversimplification of the geckodriver architecture; the actual executable acts as a relatively thin shim, translating from the wire protocol of the spec to their internal marionette protocol\
> but the point still stands.\
> anyway, the landscape is currently evolving regarding browser-vendor-provided driver implementation. microsoft has one for edge, apple has one for safari (10 and above), the chromium team (largely staffed by googlers) has one for chrome, and now mozilla has one for firefox.\
> given the limited utility of the legacy firefox driver going forward, breaking it out into a separate executable would be wasted effort.\
> this is particularly so, since all of the communication bits that are normally handled by the executable (listening for and responding to http requests from the language bindings) are handled entirely by the browser extension. \\\
> there's literally no need for the legacy firefox driver to be a separate executable.\
> moreover, making it independent of a language runtime would be a significant portion of work\
> (because a .NET shop might reasonably balk at being required to install, say, the java runtime just to automate firefox)\
> so historically speaking, noob-einsteinsfo, that's the general reason for why separate executables have become the norm, and why that paradigm wasn't extended to include the legacy firefox driver.\
> does that make sense?\
> okay.\
> now.\
> about geckodriver.\
> the tale of geckodriver is intimately bound with the status of the aforementioned w3c webdriver spec.\
> level 1 of the specification is mostly done, though it took a number of years of effort to get there.\
> it took a large effort from some very smart people (AutomatedTester among them) to mold the initial documentation of what the webdriver open source software (OSS) project did into proper specification language that could be interpreted and turned into actionable stuff by a browser vendor or other implementor.\
> when beginning the geckodriver (nee marionette) project, mozilla decided to base their implementation on the spec, and only the spec, not following the OSS implementation.\
> this created something of a chicken-and-egg problem, in that while the spec language wasn't completed, it couldn't be implemented.\
> it's only been in the last six months or so that the language concerning the advanced user interactions api (the Actions class in java and .NET) has been made robust enough to actually implement.\
> accordingly, that's the single biggest missing chunk of functionality in geckodriver at present. it wasn't implementable via the spec, so it hasn't been implemented.\
> i do know that it's a very high priority for AutomatedTester and his team to get that implementation done and available.\
> as for why geckodriver is mandatory, and the default implementation for automating firefox in 3.x, that also comes down to some decisions made by mozilla.\
> \
> TheSchaf\
> so i guess there is no other choice than to use the old FF as long as required features are missing\
> WhereIsMySpoon\
> TheSchaf: if you need those features, yes\
> or use another browser\
> TheSchaf\
> well, moveTo and sendKeys should be pretty basic :p\
> \
> jimevans\
> TheSchaf: element.sendKeys works just fine. it's Actions.sendKeys that would be broken.\
> in firefox version fortysomething (i misremember the exact version), there was a feature added that blocked browser extensions that hadn't been signed by the mozilla security team.\
> remember that the legacy firefox driver was built as a browser extension? well, with that feature of the browser enabled, the legacy driver couldn't be loaded by the browser.\
> now, for several versions of firefox, it was possible to disable this feature of the browser, and allow unsigned extensions to continue to be loaded.\
> and selenium did this, by virtue of the settings used in the anonymous profile the bindings created when launching firefox.\
> until firefox 48, at which point, it was no longer possible to disable loading of unsigned extensions.\
> at that point, geckodriver was the only way forward for that.\
> now, two more slight points, then i'll be done with story time.\
> first, by nature of what the legacy driver extension does, it's not possible to get it to pass the certification process of the mozilla security team.\
> we asked, were denied, and were told it wouldn't happen ever, full stop.\
> and that's perfectly reasonable, since what that extension does is a security hole big enough to drive a whole fleet of lorries through.\
> second, it turns out there may, in fact, be a way to privately sign the legacy extension so that it can be loaded and used privately by versions of firefox 48 and higher.\
> that's still a less-than-ideal approach, because there's no way that our merry band of open source developers can know how to automate firefox better than the development teams at mozilla, who create the browser in the first place.\
> i totally get the frustration that geckodriver doesn't have the full feature parity of the legacy implementation, especially when it feels like one is being forced to move to it.\
> raging at the selenium project about that decision is directing one's ire in entirely the wrong direction.\
> however, before going off and saying horrible things about mozilla's decisions, do know that mozilla has several people who are constantly engaged in the project, a few of them right here in this very channel (AutomatedTester, davehunt, to name two).\
> i'm sure i've glossed over or mischaracterized some of the historical details of these things, and i'm happy to be corrected. i'm old, after all, and the memory isn't what it used to be.\
> but that, my friends, is the (not so very) short history of why we have separate executables for drivers, and why geckodriver is the way forward, and why a move to it was necessary when the move was made even though some functionality was lacking.\
> \
> jimevans feels like he's become an unofficial historian of the webdriver project

----
url: https://www.selenium.dev/zh-cn/documentation/overview/
----

# 概述

Selenium适合你吗? 请参见不同项目组件的概述.

***

##### [了解组件](/zh-cn/documentation/overview/components/)

##### [深度介绍](/zh-cn/documentation/overview/details/)

Selenium 是一系列工具和库的综合项目，这些工具和库支持 web 浏览器的自动化。

----
url: https://www.selenium.dev/pt-br/documentation/ie_driver_server/
----

# Servidor de drivers do IE

O Internet Explorer Driver é um servidor autónomo que implementa a especificação WebDriver.

| Switch                                                                                                                                                            | Significado                                                                                                                                                      |
| ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Especifica a porta na qual o servidor HTTP do driver IE escutará os comandos das associações de idioma. O padrão é 5555.                                          |                                                                                                                                                                  |
| Especifica o endereço IP do adaptador de anfitrião no qual o servidor HTTP do controlador IE irá escutar os comandos das Language Bindings. O padrão é 127.0.0.1. |                                                                                                                                                                  |
| –log-level=`<logLevel>`                                                                                                                                           | Especifica o nível em que as mensagens de registo são emitidas. Os valores válidos são FATAL, ERROR, WARN, INFO, DEBUG e TRACE. O padrão é FATAL.                |
| –log-file=`<logFile>`                                                                                                                                             | Especifica o caminho completo e o nome do arquivo de log. O padrão é stdout.                                                                                     |
| –extract-path=`<path>`                                                                                                                                            | Especifica o caminho completo para o diretório usado para extrair arquivos de suporte usados pelo servidor. O padrão é o diretório TEMP se não for especificado. |
| –silent                                                                                                                                                           | Suprime a saída de diagnóstico quando o servidor é iniciado.                                                                                                     |

## Propriedades importantes do sistema

As seguintes propriedades do sistema (lidas usando `System.getProperty()` e definidas usando `System.setProperty()` no código Java ou o sinalizador de linha de comando “`-DpropertyName=value`”) são utilizados pelo `InternetExplorerDriver`:

| **Propriedade**                                                                                                                                                  | **O que significa**                                              |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| `webdriver.ie.driver`                                                                                                                                            | A localização do binário do driver do IE.                        |
| Especifica o endereço IP do adaptador do host no qual o driver do IE escutará.                                                                                   |                                                                  |
| Especifica o nível em que as mensagens de registo são emitidas. Os valores válidos são FATAL, ERROR, WARN, INFO, DEBUG e TRACE. O padrão é FATAL.                |                                                                  |
| Especifica o caminho completo e o nome do arquivo de log.                                                                                                        |                                                                  |
| `webdriver.ie.driver.silent`                                                                                                                                     | Suprime a saída de diagnóstico quando o driver do IE é iniciado. |
| Especifica o caminho completo para o diretório usado para extrair arquivos de suporte usados pelo servidor. O padrão é o diretório TEMP se não for especificado. |                                                                  |


***

##### [Internet Explorer Driver Internals](/pt-br/documentation/ie_driver_server/internals/)

More detailed information on the IE Driver.

----
url: https://www.selenium.dev/ja/documentation/webdriver/troubleshooting/
----

# トラブルシューティングの支援

WebDriverの問題を管理する方法。

It is not always obvious the root cause of errors in Selenium.

1. The most common Selenium-related error is a result of poor synchronization. Read about [Waiting Strategies](https://www.selenium.dev/ja/documentation/webdriver/waits/). If you aren’t sure if it is a synchronization strategy you can try *temporarily* hard coding a large sleep where you see the issue, and you’ll know if adding an explicit wait can help.

2. Note that many errors that get reported to the project are actually caused by issues in the underlying drivers that Selenium sends the commands to. You can rule out a driver problem by executing the command in multiple [browsers](https://www.selenium.dev/ja/documentation/webdriver/browsers/).

3. If you have questions about how to do things, check out the [Support options](/support/) for ways get assistance.

4. If you think you’ve found a problem with Selenium code, go ahead and file a [Bug Report](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=I-defect%2Cneeds-triaging\&template=bug-report.yml\&title=%5B%F0%9F%90%9B+Bug%5D%3A+) on GitHub.

***

##### [Understanding Common Errors](/ja/documentation/webdriver/troubleshooting/errors/)

How to solve various problems in your Selenium code.

##### [Logging Selenium commands](/ja/documentation/webdriver/troubleshooting/logging/)

Getting information about Selenium execution.

##### [Selenium4にアップグレードする方法](/ja/documentation/webdriver/troubleshooting/upgrade_to_selenium_4/)

Selenium 4に興味がありますか？ 最新リリースへのアップグレードに役立つこのガイドを確認してください。

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/bidi/cdp/network/
----

```java
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L41-L43)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
        credentials = base64.b64encode("admin:admin".encode()).decode()
        auth = {'authorization': 'Basic ' + credentials}
        await connection.session.execute(connection.devtools.network.set_extra_http_headers(Headers(auth)))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L13-15)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L25-L32)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L9-L11)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      HttpResponse res = next.execute(req);
                      contentType.add(res.getHeader("Content-Type"));
                      return res;
                    })) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L56-L65)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L46-L51)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L20-L24)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    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!"))))) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L75-L85)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L62-L73)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L31-L35)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L97-L110)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L85-L97)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    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
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L42-L46)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L125-L126)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    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())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L26-L28)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L114-L118)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L56-L57)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    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()));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L142-L157)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L37-L44)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L136-L143)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L68-L71)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    devTools.send(
            Browser.setDownloadBehavior(
                    Browser.SetDownloadBehaviorBehavior.ALLOWANDNAME,
                    Optional.empty(),
                    Optional.of(""),
                    Optional.of(true)));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L171-L176)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    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
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L82-L88)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

----
url: https://www.selenium.dev/documentation/webdriver/interactions/navigation/
----

# Browser navigation

```java
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L14-L18)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.get("https://www.selenium.dev/selenium/web/index.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L6)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Convenient
            driver.Url = "https://selenium.dev";
            //Longer
            driver.Navigate().GoToUrl("https://selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class NavigationTest
    {
        [TestMethod]
        public void TestNavigationCommands()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            //Convenient
            driver.Url = "https://selenium.dev";
            //Longer
            driver.Navigate().GoToUrl("https://selenium.dev");
            var title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Back
            driver.Navigate().Back();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Forward
            driver.Navigate().Forward();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Refresh
            driver.Navigate().Refresh();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Quit the browser
            driver.Quit();
        }
    }
}
```

```rb

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L7-L9)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Convenient
      await driver.get('https://www.selenium.dev');
  
      //Longer way
      await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L16-L20)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
  const assert = require("node:assert");
  
  describe('Interactions - Navigation', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser('chrome')
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('Browser navigation test', async function () {
      //Convenient
      await driver.get('https://www.selenium.dev');
  
      //Longer way
      await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
      let title = await driver.getTitle();
      assert.equal(title, "Index of Available Pages");
  
      //Back
      await driver.navigate().back();
      title = await driver.getTitle();
      assert.equal(title, "Selenium");
  
      //Forward
      await driver.navigate().forward();
      title = await driver.getTitle();
      assert.equal(title, "Index of Available Pages");
  
      //Refresh
      await driver.navigate().refresh();
      title = await driver.getTitle();
      assert.equal(title, "Index of Available Pages");
    });
  });
```

```kotlin
//Convenient
driver.get("https://selenium.dev")

//Longer way
driver.navigate().to("https://selenium.dev")
  
```

```java
        //Back
        driver.navigate().back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L22-L23)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.back()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L11)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Back
             driver.Navigate().Back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L24-L25)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
    driver.navigate.to 'https://www.selenium.dev/'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L15)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Back
      await driver.navigate().back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L24-L25)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
  const assert = require("node:assert");
  
  describe('Interactions - Navigation', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser('chrome')
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('Browser navigation test', async function () {
      //Convenient
      await driver.get('https://www.selenium.dev');
  
      //Longer way
      await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
      let title = await driver.getTitle();
      assert.equal(title, "Index of Available Pages");
  
      //Back
      await driver.navigate().back();
      title = await driver.getTitle();
      assert.equal(title, "Selenium");
  
      //Forward
      await driver.navigate().forward();
      title = await driver.getTitle();
      assert.equal(title, "Index of Available Pages");
  
      //Refresh
      await driver.navigate().refresh();
      title = await driver.getTitle();
      assert.equal(title, "Index of Available Pages");
    });
  });
```

```kotlin
driver.navigate().back() 
```

```java
        //Forward
        driver.navigate().forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L27-L28)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.forward()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L15)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Forward
             driver.Navigate().Forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L29-L30)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L23)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Forward
    await driver.navigate().forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L29-L30)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().forward()
```

```java
        //Refresh
        driver.navigate().refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L32-L33)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.refresh()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L19)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Refresh
             driver.Navigate().Refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L34-L35)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
  it 'refreshes the page' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L29)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Refresh
    await driver.navigate().refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L34-L35)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().refresh()
```

----
url: https://www.selenium.dev/zh-cn/documentation/grid/advanced_features/external_datastore/
----

# External datastore

```sql
CREATE TABLE IF NOT EXISTS sessions_map(
    session_ids varchar(256),
    session_caps text,
    session_uri varchar(256),
    session_stereotype text,
    session_start varchar(256)
 );
```

* In the same directory as the `init.sql`, create a file named `docker-compose.yml` with its contents as below:

```yaml
version: '3.8'
services:
  db:
    image: postgres:9.6-bullseye
    restart: always
    environment:
      - POSTGRES_USER=seluser
      - POSTGRES_PASSWORD=seluser
      - POSTGRES_DB=selenium_sessions
    ports:
      - "5432:5432"
    volumes:
    - ./init.sql:/docker-entrypoint-initdb.d/init.sql
```

We can now start our database container by running:

```bash
docker-compose up -d
```

*Our database name is `selenium_sessions` with its username and password set to `seluser`*

If you are working with an already running PostGreSQL DB instance, then you just need to create a database named `selenium_sessions` and the table `sessions_map` using the above mentioned SQL statement.

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
implementation = "org.openqa.selenium.grid.sessionmap.jdbc.JdbcBackedSessionMap"
jdbc-url = "jdbc:postgresql://localhost:5432/selenium_sessions"
jdbc-user = "seluser"
jdbc-password = "seluser"
```

*Note:* If you plan to use an existing PostGreSQL DB instance, then replace `localhost:5432` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed Grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Sessions Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

```yaml
version: '3.8'
services:
  redis:
    image: redis:bullseye
    restart: always
    ports:
      - "6379:6379"
```

We can now start our Redis container by running:

```bash
docker-compose up -d
```

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
scheme = "redis"
implementation = "org.openqa.selenium.grid.sessionmap.redis.RedisBackedSessionMap"
hostname = "localhost"
port = 6379
```

*Note:* If you plan to use an existing Redis Cache instance, then replace `localhost` and `6379` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Session Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

* At this point the current directory should contain the following files:

  * `docker-compose.yml`
  * `sessions.toml`
  * `distributed.sh`

* You can now spawn the Grid by running `distributed.sh` shell script and quickly run a test. You will notice that the Grid now stores session information into the Redis instance. You can perhaps make use of a Redis GUI such as [TablePlus](https://tableplus.com/) to see them (Make sure that you have setup a debug point in your test, because the values will get deleted as soon as the test runs to completion).

In the line which spawns a `SessionMap` on a machine:

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

* The variable names from the above script have been replaced with their actual values for clarity.
* Remember to substitute `localhost` with the actual hostname of the machine where your `Event-Bus` is running.
* The arguments being passed to `coursier` are basically the GAV (Group Artifact Version) Maven co-ordinates of:
  * [selenium-session-map-redis](https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-session-map-redis) which is needed to help us store sessions information in Redis Cache.
* `sessions.toml` is the configuration file that we created earlier.

----
url: https://www.selenium.dev/ja/documentation/webdriver/getting_started/first_script/
----

# 最初のSeleniumスクリプトを書く

```java
        WebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver = webdriver.Chrome()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L4)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L11)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver = Selenium::WebDriver.for :chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L3)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    driver = await new Builder().forBrowser(Browser.CHROME).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L8)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver = ChromeDriver()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L16)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.get("https://www.selenium.dev/selenium/web/web-form.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.get("https://www.selenium.dev/selenium/web/web-form.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L6)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L13)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.get('https://www.selenium.dev/selenium/web/web-form.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L5)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L9)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.get("https://www.selenium.dev/selenium/web/web-form.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L18)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#16)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L8)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var title = driver.Title;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L15)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L7)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let title = await driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L11)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L20)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L18)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.implicitly_wait(0.5)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L10)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L17)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.manage.timeouts.implicit_wait = 500
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L9)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.manage().setTimeouts({implicit: 500});
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L14)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L23)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L20-L21)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L12-L13)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L19-L20)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L11-L12)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L16-L17)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L25-L26)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        textBox.sendKeys("Selenium");
        submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L23-L24)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
text_box.send_keys("Selenium")
submit_button.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L15-L16)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        textBox.SendKeys("Selenium");
        submitButton.Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
text_box.send_keys('Selenium')
submit_button.click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L14-L15)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await textBox.sendKeys('Selenium');
    await submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L19-L20)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        textBox.sendKeys("Selenium")
        submitButton.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L28-L29)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        WebElement message = driver.findElement(By.id("message"));
        message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-27)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
message = driver.find_element(by=By.ID, value="message")
text = message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L18-19)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-26)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
message = driver.find_element(id: 'message')
message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L17-18)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L22-23)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val message = driver.findElement(By.id("message"))
        val value = message.getText()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-32)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```java
        driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L21)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L28)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L20)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L28)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L35)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

```md
mvn exec:java -D"exec.mainClass"="dev.selenium.getting_started.FirstScript" -D"exec.classpathScope"=test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/README.md#L60)

##### /examples/java/README.md

````md
# Running Selenium Java Tests
The following steps will guide you on how to 
run Selenium Java tests using a repository 
of `SeleniumHQ/seleniumhq.github.io` examples.

## Initial Setup

### Prerequisites

Ensure that Java Development Kit (JDK) and Maven 
are installed on your system. If they are not installed, 
you will need to download and install them. You can 
find detailed installation guides for both on their 
respective official sites.

### Clone the repository
First, we need to get the Selenium Java examples 
on your local machine. This can be done by 
cloning the `SeleniumHQ/seleniumhq.github.io` Git repository. 
Run the following command in your terminal:

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```
## Navigate to the java directory
After cloning the repository, navigate into the 
directory where the Selenium Java examples are 
located. Run the following command:

```bash
cd seleniumhq.github.io/examples/java
```

## Running the Tests
### Install dependencies
Before running the tests, we need to install all 
necessary dependencies. Maven, a software 
project management tool, can do this for us. 
Run the following command:

```bash
mvn test-compile
```

### Run all tests
To verify if everything is installed correctly and 
functioning properly, we should run all 
available tests. This can be done with the following command:

```bash
mvn test
```

Please be patient! If this is your first time running these tests, 
it might take a while to download and verify all necessary browser drivers.

## Execute a specific example
To run a specific Selenium Java example, use the following command:
```bash
mvn exec:java -D"exec.mainClass"="dev.selenium.getting_started.FirstScript" -D"exec.classpathScope"=test
```

Make sure to replace `dev.selenium.getting_started.FirstScript` with the path and name of the example you want to run.
````

````md
```
````

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/README.md#L35)

##### /examples/python/README.md

````md
# Running tests from Selenium Python examples

#### 1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

#### 2. Navigate to `python` directory

```
cd seleniumhq.github.io/examples/python
```

#### 3. Create a virtual environment

- On Windows:

```
py -m venv venv
venv\Scripts\activate
```

- On Linux/Mac:

```
python3 -m venv venv
source venv/bin/activate
```

#### 4. Install dependencies:

```
pip install -r requirements.txt
```

> for help, see: https://packaging.python.org/en/latest/tutorials/installing-packages

#### 5. Run tests

- Run all tests with the default Python interpreter:

```
pytest
```

- Run all tests with every installed/supported Python interpreter:

```
tox
```

> Please have some patience - If you are doing it for the first time, it will take a little while to download the browser drivers

- Run a specific example:

```
pytest path/to/test_script.py
```

> Make sure to replace `path/to/test_script.py` with the path and name of the example you want to run
````

```md
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/README.md#L55)

##### /examples/dotnet/README.md

````md

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

## Navigate to the .NET directory
### Change into the .NET examples directory:

```bash
cd seleniumhq.github.io/examples/dotnet/SeleniumDocs
```

## Running the Tests
### Restore dependencies
Install necessary dependencies using the .NET CLI:

```bash
dotnet restore
```

### Run all tests
To run all available tests:

```bash
dotnet test
```

### Run a Specific Test Method
To run a specific test method using its fully qualified name:

```bash
dotnet test --filter "FullyQualifiedName=Namespace.ClassName.MethodName"
```
For example:
```bash
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

You can also filter by test name only (if it's unique):
```bash
dotnet test --filter "Name=EightComponents"
```
````

```md
ruby example_script.rb
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/README.md#L36)

##### /examples/ruby/README.md

````md
# Running all tests from Selenium ruby example

Follow these steps to run all test example from selenium ruby

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `ruby` directory

```
cd seleniumhq.github.io/examples/ruby
```

3. Install dependencies using bundler

```
bundler install
```

4. Run all tests

```
bundle exec rspec
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a ruby script

Use this command to run a ruby script and follow the first script example

```
ruby example_script.rb
```
````

```md
node example_script.spec.js
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/README.md#L36)

##### /examples/javascript/README.md

````md
# Running all tests from Selenium javascript example

Follow these steps to run all test example from selenium javascript

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `javascript` directory

```
cd seleniumhq.github.io/examples/javascript
```

3. Install dependencies using node

```
npm install
```

4. Run all all tests

```
npm test
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a javascript test

Use this command to run a JavaScript and follow the first script example

```
node example_script.spec.js
```
````

[Add Example](/documentation/about/contributing/#creating-examples)

## 次のステップ

ほとんどのSeleniumユーザーは多くのセッションを実行し、重複を最小限に抑え、コードをより保守しやすくするために整理する必要があります。このコードをユースケースのコンテキストに配置する方法については、以下をお読みください [Seleniumの使用](https://www.selenium.dev/ja/documentation/webdriver/getting_started/using_selenium/)。

最終更新 October 30, 2025: [Update "First Script" documentation with C# example from .NET README (#2478) (e55b319492d)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e55b319492d1e4062020fe6c23d46dae22b4b2aa)

## Development Partners

[](https://www.browserstack.com/automate?utm_campaign=open-source-sponsor\&utm_campaigncode=701OW000009sQwVYAU\&utm_medium=partnered\&utm_source=seleniumorg)

[](https://saucelabs.com/resources/topic-hub/selenium?utm_source=selenium\&utm_medium=website\&utm_campaign=selenium-sponsorship-fy25)

[](https://www.testmuai.com)

## Selenium Level Sponsors

[](https://brightdata.com/?utm_source=brand\&utm_campaign=brnd-mkt_partners_selenium)

[](https://applitools.com/)

[](https://www.thordata.com/?ls=waOicIkB\&lk=selenium)

## Support the Selenium Project

Learn more or view the full list of sponsors.

[Learn more**](/sponsors)

----
url: https://www.selenium.dev/documentation/webdriver/drivers/
----

# Driver Sessions

```java
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L23)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L9)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            driver = new ChromeDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BaseTest.cs#L48)

##### /examples/dotnet/SeleniumDocs/BaseTest.cs

```cs
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs
{
    public class BaseTest
    {
        protected IWebDriver driver;
        protected Uri GridUrl;
        private Process _webserverProcess;
        private const string ServerJarName = "selenium-server-4.44.0.jar";
        private static readonly string BaseDirectory = AppContext.BaseDirectory;
        private const string RelativePathToGrid = "../../../../../";
        private readonly string _examplesDirectory = Path.GetFullPath(Path.Combine(BaseDirectory, RelativePathToGrid));

        [TestCleanup]
        public void Cleanup()
        {
            driver?.Quit();

            if (_webserverProcess != null)
            {
                StopServer();
            }
        }

        protected void StartDriver(string browserVersion = null)
        {
            ChromeOptions options = new ChromeOptions();
            if (browserVersion != null)
            {
                options.BrowserVersion = browserVersion;
                string userDataDir = System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetRandomFileName());
                System.IO.Directory.CreateDirectory(userDataDir);
                options.AddArgument($"--user-data-dir={userDataDir}");
                options.AddArgument("--no-sandbox");
                options.AddArgument("--disable-dev-shm-usage");
            }
            driver = new ChromeDriver(options);
        }

        protected async Task StartServer()
        {
            if (_webserverProcess == null || _webserverProcess.HasExited)
            {
                _webserverProcess = new Process();
                _webserverProcess.StartInfo.FileName =
                    RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "java.exe" : "java";
                string port = GetFreeTcpPort().ToString();
                GridUrl = new Uri("http://localhost:" + port + "/wd/hub");
                _webserverProcess.StartInfo.Arguments = " -jar " + ServerJarName +
                                                        " standalone --port " + port +
                                                        " --selenium-manager true --enable-managed-downloads true";
                _webserverProcess.StartInfo.WorkingDirectory = _examplesDirectory;
                _webserverProcess.Start();
                await EnsureGridIsRunningAsync();
            }
        }

        private void StopServer()
        {
            if (_webserverProcess != null && !_webserverProcess.HasExited)
            {
                _webserverProcess.Kill();
                _webserverProcess.Dispose();
                _webserverProcess = null;
            }
        }

        private static int GetFreeTcpPort()
        {
            TcpListener l = new TcpListener(IPAddress.Loopback, 0);
            l.Start();
            int port = ((IPEndPoint)l.LocalEndpoint).Port;
            l.Stop();
            return port;
        }

        private async Task EnsureGridIsRunningAsync()
        {
            DateTime timeout = DateTime.Now.Add(TimeSpan.FromSeconds(240));
            bool isRunning = false;
            HttpClient client = new HttpClient();

            while (!isRunning && DateTime.Now < timeout)
            {
                try
                {
                    HttpResponseMessage response = await client.GetAsync(GridUrl + "/status");
                    if (response.IsSuccessStatusCode)
                    {
                        isRunning = true;
                    }
                    else
                    {
                        await Task.Delay(1000);
                    }
                }
                catch (HttpRequestException)
                {
                    await Task.Delay(1000);
                }
            }

            if (!isRunning)
            {
                throw new TimeoutException("Could not confirm the remote selenium server is running within 30 seconds");
            }
        }
    }
}
```

```rb
      driver = Selenium::WebDriver.for :chrome, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L14)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options)
      .setChromeService(service)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/drivers/service.spec.js#L46-L50)

##### /examples/javascript/test/drivers/service.spec.js

```js
const fs = require('fs');
const os = require('os');
const path = require('path');
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const {getBinaryPaths} = require("selenium-webdriver/common/driverFinder");

describe('Service Test', function () {
  let driver;
  let userDataDir;
  let service;
  let options;

  afterEach(async function () {
    if (driver) {
      await driver.quit();
      driver = null;
    }
    if (userDataDir) {
      fs.rmSync(userDataDir, { recursive: true, force: true });
      userDataDir = null;
    }
  });

  it('Default service', async function () {
    service = new Chrome.ServiceBuilder();
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });

  it('Set Driver Location', async function () {
    options = new Chrome.Options();
    options.setBrowserVersion("stable");
    let paths = getBinaryPaths(options);
    let driverPath = paths.driverPath;
    let browserPath = paths.browserPath;
    options.setChromeBinaryPath(browserPath);
    userDataDir = fs.mkdtempSync(path.join(os.tmpdir(), 'chrome-profile-'));
    options.addArguments(`--user-data-dir=${userDataDir}`);
    options.addArguments('--no-sandbox');
    options.addArguments('--disable-dev-shm-usage');
    service = new Chrome.ServiceBuilder(driverPath);
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });

  it('Set port', async function () {
    service = new Chrome.ServiceBuilder().setPort(1234);
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
        driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L11)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L28)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L16)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L28)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L35)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

***

##### [Browser Options](/documentation/webdriver/drivers/options/)

These capabilities are shared by all browsers.

##### [HTTP Client Configuration](/documentation/webdriver/drivers/http_client/)

##### [Driver Service Class](/documentation/webdriver/drivers/service/)

##### [Remote WebDriver](/documentation/webdriver/drivers/remote_webdriver/)

Last modified October 30, 2025: [Issue 2452- fixed line number for CSharp to show correct line for driver (#2489) (fe610b23e9b)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/fe610b23e9b91b7314fc8ae3c3d24deb73afee22)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/bidi/
----

```java
options.setCapability("webSocketUrl", true);
```

```python
options.enable_bidi = True
```

```csharp
UseWebSocketUrl = true,
```

```ruby
options.web_socket_url = true
```

```javascript
Options().enableBidi();
```

```kotlin
options.setCapability("webSocketUrl", true);
```

This enables the WebSocket connection for bidirectional communication, unlocking the full potential of the WebDriver BiDi protocol.

Note that Selenium is updating its entire implementation from WebDriver Classic to WebDriver BiDi (while maintaining backwards compatibility as much as possible), but this section of documentation focuses on the new functionality that bidirectional communication allows. The low-level BiDi domains will be accessible in the code to the end user, but the goal is to provide high-level APIs that are straightforward methods of real-world use cases. As such, the low-level components will not be documented, and this section will focus only on the user-friendly features that we encourage users to take advantage of.

If there is additional functionality you’d like to see, please raise a [feature request](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=\&template=feature.md).

***

##### [WebDriver BiDi Logging Features](/pt-br/documentation/webdriver/bidi/logging/)

These features are related to logging. Because “logging” can refer to so many different things, these methods are made available via a “script” namespace.

##### [WebDriver BiDi Network Features](/pt-br/documentation/webdriver/bidi/network/)

These features are related to networking, and are made available via a “network” namespace.

##### [WebDriver BiDi Script Features](/pt-br/documentation/webdriver/bidi/script/)

These features are related to scripts, and are made available via a “script” namespace.

##### [Chrome DevTools Protocol](/pt-br/documentation/webdriver/bidi/cdp/)

Examples of working with Chrome DevTools Protocol in Selenium. CDP support is temporary until WebDriver BiDi has been implemented.

##### [BiDirectional API (W3C compliant)](/pt-br/documentation/webdriver/bidi/w3c/)

Última modificação October 18, 2024: [add missing pages for BiDi \[deploy site\] (74652d2ecb4)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/74652d2ecb4db1dd9378c6b7f314ae477108db8c)

----
url: https://www.selenium.dev/documentation/grid/configuration/cli_options/
----

# CLI options in the Selenium Grid

All Grid components configuration CLI options in detail.

Different sections are available to configure a Grid. Each section has options can be configured through command line arguments.

A complete description of the component to section mapping can be seen below.

Note that this documentation could be outdated if an option was modified or added but has not been documented yet. In case you bump into this situation, please check the [“Config help”](https://www.selenium.dev/documentation/grid/configuration/help/) section and feel free to send us a pull request updating this page.

## Sections

|                               | Standalone | Hub | Node | Distributor | Router | Sessions | SessionQueue |
| ----------------------------- | ---------- | --- | ---- | ----------- | ------ | -------- | ------------ |
| [Distributor](#distributor)   | **         | **  |      | **          | **     |          |              |
| [Docker](#docker)             | **         |     | **   |             |        |          |              |
| [Kubernetes](#kubernetes)     | **         |     | **   |             |        |          |              |
| [Events](#events)             |            | **  | **   | **          |        | **       | **           |
| [Logging](#logging)           | **         | **  | **   | **          | **     | **       | **           |
| [Network](#network)           | **         | **  |      |             | **     |          |              |
| [Node](#node)                 | **         |     | **   |             |        |          |              |
| [Router](#router)             | **         | **  |      |             | **     |          |              |
| [Relay](#relay)               | **         |     | **   |             |        |          |              |
| [Server](#server)             | **         | **  | **   | **          | **     | **       | **           |
| [SessionQueue](#sessionqueue) | **         | **  |      | **          | **     |          | **           |
| [Sessions](#sessions)         |            |     |      | **          | **     | **       |              |

### Distributor

| Option                         | Type    | Value/Example                                                       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ------------------------------ | ------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--healthcheck-interval`       | int     | `120`                                                               | How often, in seconds, will the health check run for all Nodes. This ensures the server can ping all the Nodes successfully.                                                                                                                                                                                                                                                                                                                        |
| `--distributor`                | uri     | `http://localhost:5553`                                             | Url of the distributor.                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `--distributor-host`           | string  | `localhost`                                                         | Host on which the distributor is listening.                                                                                                                                                                                                                                                                                                                                                                                                         |
| `--distributor-implementation` | string  | `org.openqa.selenium.grid.distributor.local.LocalDistributor`       | Full class name of non-default distributor implementation                                                                                                                                                                                                                                                                                                                                                                                           |
| `--distributor-port`           | int     | `5553`                                                              | Port on which the distributor is listening.                                                                                                                                                                                                                                                                                                                                                                                                         |
| `--reject-unsupported-caps`    | boolean | `false`                                                             | Allow the Distributor to reject a request immediately if the Grid does not support the requested capability. Rejecting requests immediately is suitable for a Grid setup that does not spin up Nodes on demand.                                                                                                                                                                                                                                     |
| `--slot-matcher`               | string  | `org.openqa.selenium.grid.data.DefaultSlotMatcher`                  | Full class name of non-default slot matcher to use. This is used to determine whether a Node can support a particular session.                                                                                                                                                                                                                                                                                                                      |
| `--slot-selector`              | string  | `org.openqa.selenium.grid.distributor.selector.DefaultSlotSelector` | Full class name of non-default slot selector. This is used to select a slot in a Node once the Node has been matched.                                                                                                                                                                                                                                                                                                                               |
| `--newsession-threadpool-size` | int     | `24`                                                                | The Distributor uses a fixed-sized thread pool to create new sessions as it consumes new session requests from the queue. This allows configuring the size of the thread pool. The default value is no. of available processors \* 3. Note: If the no. of threads is way greater than the available processors it will not always increase the performance. A high number of threads causes more context switching which is an expensive operation. |
| `--purge-nodes-interval`       | int     | `30`                                                                | How often, in seconds, will the Distributor purge Nodes that have been down for a while. This is calculated based on the heartbeat received from a particular node.                                                                                                                                                                                                                                                                                 |

### Docker

| Option                          | Type      | Value/Example                                                     | Description                                                                                                                                                                                                                                                                                 |
| ------------------------------- | --------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--docker-assets-path`          | string    | `/opt/selenium/assets`                                            | Absolute path where assets will be stored                                                                                                                                                                                                                                                   |
| `--docker` / `-D`               | string\[] | `selenium/standalone-firefox:latest '{"browserName": "firefox"}'` | Docker configs which map image name to stereotype capabilities (example: `-D selenium/standalone-firefox:latest '{"browserName": "firefox"}'`)                                                                                                                                              |
| `--docker-devices`              | string\[] | `/dev/kvm:/dev/kvm`                                               | Exposes devices to a container. Each device mapping declaration must have at least the path of the device in both host and container separated by a colon like in this example: /device/path/in/host:/device/path/in/container                                                              |
| `--docker-host`                 | string    | `localhost`                                                       | Host name where the Docker daemon is running                                                                                                                                                                                                                                                |
| `--docker-port`                 | int       | `2375`                                                            | Port where the Docker daemon is running                                                                                                                                                                                                                                                     |
| `--docker-url`                  | string    | `http://localhost:2375`                                           | URL for connecting to the Docker daemon                                                                                                                                                                                                                                                     |
| `--docker-video-image`          | string    | `selenium/video:latest`                                           | Docker image to be used when video recording is enabled                                                                                                                                                                                                                                     |
| `--docker-host-config-keys`     | string\[] | `Dns DnsOptions DnsSearch ExtraHosts Binds`                       | Specify which docker host configuration keys should be passed to browser containers. Keys name can be found in the Docker API [documentation](https://docs.docker.com/engine/api/v1.41/#tag/Container/operation/ContainerCreate), or by running `docker inspect` the node-docker container. |
| `--docker-api-version`          | string    | `1.40`                                                            | Docker API version to use. Pin a specific API version instead of relying on auto-detection by the implementation.                                                                                                                                                                           |
| `--docker-server-start-timeout` | int       | `55`                                                              | Max time (in seconds) to wait for the browser server to successfully start up inside the container, before cancelling the process.                                                                                                                                                          |
| `--docker-grouping-labels`      | string\[] | `azure.container.group aws.ecs.cluster`                           | Custom labels used for grouping dynamic containers. Makes the system more flexible for different platforms and use cases.                                                                                                                                                                   |

### Kubernetes

| Option                                  | Type      | Value/Example                                                     | Description                                                                                                                                                                                                                                                                    |
| --------------------------------------- | --------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--kubernetes-url`                      | string    | `"https://my-k8s-cluster:6443"`                                   | Kubernetes API server URL. When set, connects to a remote cluster instead of using in-cluster or kubeconfig auto-discovery.                                                                                                                                                    |
| `--kubernetes-configs` / `-K`           | string\[] | `selenium/standalone-firefox:latest '{"browserName": "firefox"}'` | Kubernetes configs which map image name to stereotype capabilities (example: `-K selenium/standalone-firefox:latest '{"browserName": "firefox"}'`). Use `configmap:[namespace/]<name>` as the key to load a Job template from a Kubernetes ConfigMap instead of an image name. |
| `--kubernetes-namespace`                | string    | `"selenium"`                                                      | Kubernetes namespace to create browser Jobs in. Auto-detected from the client when running in-cluster if not set.                                                                                                                                                              |
| `--kubernetes-service-account`          | string    | `"selenium-session"`                                              | Override service account for browser Jobs. Auto-inherited from the Node Pod when running in K8s.                                                                                                                                                                               |
| `--kubernetes-image-pull-policy`        | string    | `"IfNotPresent"`                                                  | Override image pull policy for browser containers (`Always`, `IfNotPresent`, `Never`). Auto-inherited from the Node Pod when running in K8s.                                                                                                                                   |
| `--kubernetes-server-start-timeout`     | int       | `120`                                                             | Max time (in seconds) to wait for the browser server to start up in the K8s Pod.                                                                                                                                                                                               |
| `--kubernetes-termination-grace-period` | int       | `30`                                                              | Seconds to wait for containers to shut down gracefully before force-killing them.                                                                                                                                                                                              |
| `--kubernetes-resource-requests`        | string    | `"cpu=500m,memory=512Mi"`                                         | Override resource requests for browser containers (comma-separated `key=value` pairs). Auto-inherited from the Node Pod when running in K8s.                                                                                                                                   |
| `--kubernetes-resource-limits`          | string    | `"cpu=1,memory=1Gi"`                                              | Override resource limits for browser containers (comma-separated `key=value` pairs). Auto-inherited from the Node Pod when running in K8s.                                                                                                                                     |
| `--kubernetes-node-selector`            | string    | `"disktype=ssd,region=us-west"`                                   | Override node selector for scheduling browser Pods (comma-separated `key=value` pairs). Auto-inherited from the Node Pod when running in K8s.                                                                                                                                  |
| `--kubernetes-video-image`              | string    | `"selenium/video:latest"`                                         | Container image to use as a video recording sidecar. Set to `false` to disable video recording (default).                                                                                                                                                                      |
| `--kubernetes-assets-path`              | string    | `"/opt/selenium/assets"`                                          | Absolute path where session assets will be stored.                                                                                                                                                                                                                             |
| `--kubernetes-label-inherit-prefix`     | string    | `"se/"`                                                           | Prefix filter for inheriting labels/annotations from the Node Pod to browser Jobs. Only labels/annotations whose keys start with this prefix are inherited. An empty string inherits all.                                                                                      |

### Events

| Option                        | Type    | Value/Example                                      | Description                                                                                                                                                                                                                                                                         |
| ----------------------------- | ------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--bind-bus`                  | boolean | `false`                                            | Whether the connection string should be bound or connected. When true, the component will be bound to the Event Bus (as in the Event Bus will also be started by the component, typically by the Distributor and the Hub). When false, the component will connect to the Event Bus. |
| `--events-implementation`     | string  | `org.openqa.selenium.events.zeromq.ZeroMqEventBus` | Full class name of non-default event bus implementation                                                                                                                                                                                                                             |
| `--publish-events`            | string  | `tcp://*:4442`                                     | Connection string for publishing events to the event bus                                                                                                                                                                                                                            |
| `--subscribe-events`          | string  | `tcp://*:4443`                                     | Connection string for subscribing to events from the event bus                                                                                                                                                                                                                      |
| `--eventbus-heartbeat-period` | int     | `30`                                               | How often, in seconds, will the EventBus socket send heartbeats.                                                                                                                                                                                                                    |

### Logging

| Option                   | Type    | Value/Example                                                                                                                                              | Description                                                                                                                                                            |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--http-logs`            | boolean | `false`                                                                                                                                                    | Enable http logging. Tracing should be enabled to log http logs.                                                                                                       |
| `--log-encoding`         | string  | `UTF-8`                                                                                                                                                    | Log encoding                                                                                                                                                           |
| `--log`                  | string  | Windows path example : `'\path\to\file\gridlog.log'` or `'C:\path\path\to\file\gridlog.log'` Linux/Unix/MacOS path example : `'/path/to/file/gridlog.log'` | File to write out logs. Ensure the file path is compatible with the operating system’s file path.                                                                      |
| `--log-level`            | string  | `“INFO”`                                                                                                                                                   | Log level. Default logging level is INFO. Log levels are described here <https://docs.oracle.com/en/java/javase/11/docs/api/java.logging/java/util/logging/Level.html> |
| `--plain-logs`           | boolean | `true`                                                                                                                                                     | Use plain log lines                                                                                                                                                    |
| `--structured-logs`      | boolean | `false`                                                                                                                                                    | Use structured logs                                                                                                                                                    |
| `--tracing`              | boolean | `true`                                                                                                                                                     | Enable trace collection                                                                                                                                                |
| `--log-timestamp-format` | string  | `HH:mm:ss.SSS`                                                                                                                                             | Allows the configure log timestamp format                                                                                                                              |

### Network

| Option           | Type    | Value/Example | Description                                                                                                          |
| ---------------- | ------- | ------------- | -------------------------------------------------------------------------------------------------------------------- |
| `--relax-checks` | boolean | `false`       | Relax checks on origin header and content type of incoming requests, in contravention of strict W3C spec compliance. |

### Node

| Option                           | Type      | Value/Example                                                                                                                                                                                                                                                              | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| -------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--detect-drivers`               | boolean   | `true`                                                                                                                                                                                                                                                                     | Autodetect which drivers are available on the current system, and add them to the Node.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `--driver-configuration`         | string\[] | `display-name="Firefox Nightly" max-sessions=2 webdriver-path="/usr/local/bin/geckodriver" stereotype="{\"browserName\": \"firefox\", \"browserVersion\": \"86\", \"moz:firefoxOptions\": {\"binary\":\"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"` | List of configured drivers a Node supports. It is recommended to provide this type of configuration through a toml config file to improve readability                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `--driver-factory`               | string\[] | `org.openqa.selenium.example.LynxDriverFactory '{"browserName": "lynx"}'`                                                                                                                                                                                                  | Mapping of fully qualified class name to a browser configuration that this matches against.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `--driver-implementation`        | string\[] | `"firefox"`                                                                                                                                                                                                                                                                | Drivers that should be checked. If specified, will skip autoconfiguration.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `--node-implementation`          | string    | `"org.openqa.selenium.grid.node.local.LocalNodeFactory"`                                                                                                                                                                                                                   | Full classname of non-default Node implementation. This is used to manage a session’s lifecycle.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `--grid-url`                     | string    | `https://grid.example.com`                                                                                                                                                                                                                                                 | Public URL of the Grid as a whole (typically the address of the Hub or the Router)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `--heartbeat-period`             | int       | `60`                                                                                                                                                                                                                                                                       | How often, in seconds, will the Node send heartbeat events to the Distributor to inform it that the Node is up.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `--max-sessions`                 | int       | `8`                                                                                                                                                                                                                                                                        | Maximum number of concurrent sessions. Default value is the number of available processors.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `--override-max-sessions`        | boolean   | `false`                                                                                                                                                                                                                                                                    | The # of available processors is the recommended max sessions value (1 browser session per processor). Setting this flag to true allows the recommended max value to be overwritten. Session stability and reliability might suffer as the host could run out of resources.                                                                                                                                                                                                                                                                                                                             |
| `--register-cycle`               | int       | `10`                                                                                                                                                                                                                                                                       | How often, in seconds, the Node will try to register itself for the first time to the Distributor.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `--register-period`              | int       | `120`                                                                                                                                                                                                                                                                      | How long, in seconds, will the Node try to register to the Distributor for the first time. After this period is completed, the Node will not attempt to register again.                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `--session-timeout`              | int       | `300`                                                                                                                                                                                                                                                                      | Let X be the session-timeout in seconds. The Node will automatically kill a session that has not had any activity in the last X seconds. This will release the slot for other tests.                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `--vnc-env-var`                  | string\[] | `SE_START_XVFB SE_START_VNC SE_START_NO_VNC`                                                                                                                                                                                                                               | Environment variable to check in order to determine if a vnc stream is available or not.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `--no-vnc-port`                  | int       | `7900`                                                                                                                                                                                                                                                                     | If VNC is available, sets the port where the local noVNC stream can be obtained                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `--drain-after-session-count`    | int       | `1`                                                                                                                                                                                                                                                                        | Drain and shutdown the Node after X sessions have been executed. Useful for environments like Kubernetes. A value higher than zero enables this feature.                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `--hub`                          | string    | `http://localhost:4444`                                                                                                                                                                                                                                                    | The address of the Hub in a Hub-and-Node configuration. Can be a hostname or IP address (`hostname`), in which case the Hub will be assumed to be `http://hostname:4444`, the `--grid-url` will be the same `--publish-events` will be `tcp://hostname:4442` and `--subscribe-events` will be `tcp://hostname:4443`. If `hostname` contains a port number, that will be used for `--grid-url` but the URIs for the event bus will remain the same. Any of these default values may be overridden but setting the correct flags. If the hostname has a protocol (such as `https`) that will be used too. |
| `--enable-cdp`                   | boolean   | `true`                                                                                                                                                                                                                                                                     | Enable CDP proxying in Grid. A Grid admin can disable CDP if the network does not allow websockets. True by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `--enable-bidi`                  | boolean   | `true`                                                                                                                                                                                                                                                                     | Enable BiDi proxying in Grid. A Grid admin can disable BiDi if the network does not allow websockets. True by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `--enable-managed-downloads`     | boolean   | `false`                                                                                                                                                                                                                                                                    | This causes the Node to auto manage files downloaded for a given session on the Node.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `--selenium-manager`             | boolean   | `false`                                                                                                                                                                                                                                                                    | When drivers are not available on the current system, use Selenium Manager. False by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `--connection-limit-per-session` | int       | `10`                                                                                                                                                                                                                                                                       | Let X be the maximum number of websocket connections per session. This will ensure one session is not able to exhaust the connection limit of the host.                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `--delete-session-on-ui`         | boolean   | `false`                                                                                                                                                                                                                                                                    | Enable capability to support deleting a session via the Grid UI. False by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `--register-shutdown-on-failure` | boolean   | `false`                                                                                                                                                                                                                                                                    | If enabled, the Node will shut down after the register period is completed without a successful registration. Useful in container environments to trigger a restart.                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `--node-down-failure-threshold`  | int       | `3`                                                                                                                                                                                                                                                                        | Maximum number of consecutive session creation failures before the Node is marked as DOWN. A value of `0` (default) disables this feature and allows unlimited retries.                                                                                                                                                                                                                                                                                                                                                                                                                                 |

### Relay

| Option                       | Type      | Value/Example                                                                                                     | Description                                                                                                                                                              |
| ---------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--service-url`              | string    | `http://localhost:4723`                                                                                           | URL for connecting to the service that supports WebDriver commands like an Appium server or a cloud service.                                                             |
| `--service-host`             | string    | `localhost`                                                                                                       | Host name where the service that supports WebDriver commands is running                                                                                                  |
| `--service-port`             | int       | `4723`                                                                                                            | Port where the service that supports WebDriver commands is running                                                                                                       |
| `--service-status-endpoint`  | string    | `/status`                                                                                                         | Optional, endpoint to query the WebDriver service status, an HTTP 200 response is expected                                                                               |
| `--service-protocol-version` | string    | `HTTP/1.1`                                                                                                        | Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status                                                          |
| `--service-configuration`    | string\[] | `max-sessions=2 stereotype='{"browserName": "safari", "platformName": "iOS", "appium:platformVersion": "14.5"}}'` | Configuration for the service where calls will be relayed to. It is recommended to provide this type of configuration through a toml config file to improve readability. |

### Router

| Option         | Type    | Value/Example              | Description                                                                                                         |
| -------------- | ------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `--password`   | string  | `myStrongPassword`         | Password clients must use to connect to the server. Both this and the username need to be set in order to be used.  |
| `--username`   | string  | `admin`                    | User name clients must use to connect to the server. Both this and the password need to be set in order to be used. |
| `--sub-path`   | string  | `my_company/selenium_grid` | A sub-path that should be considered for all user facing routes on the Hub/Router/Standalone.                       |
| `--disable-ui` | boolean | `true`                     | Disable the Grid UI.                                                                                                |

### Server

| Option                  | Type    | Value/Example           | Description                                                                                                                                                                                                                                                                           |
| ----------------------- | ------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--external-url`        | string  | `http://10.0.1.1:33333` | External URL where component is generally available. Useful on complex network topologies when components are on different networks and proxy servers are involved.                                                                                                                   |
| `--allow-cors`          | boolean | `true`                  | Whether the Selenium server should allow web browser connections from any host                                                                                                                                                                                                        |
| `--host`                | string  | `localhost`             | Server IP or hostname: usually determined automatically.                                                                                                                                                                                                                              |
| `--bind-host`           | boolean | `true`                  | Whether the server should bind to the host address/name, or only use it to" report its reachable url. Helpful in complex network topologies where the server cannot report itself with the current IP/hostname but rather an external IP or hostname (e.g. inside a Docker container) |
| `--https-certificate`   | path    | `/path/to/cert.pem`     | Server certificate for https. Get more detailed information by running “java -jar selenium-server.jar info security”                                                                                                                                                                  |
| `--https-private-key`   | path    | `/path/to/key.pkcs8`    | Private key for https. Get more detailed information by running “java -jar selenium-server.jar info security”                                                                                                                                                                         |
| `--max-threads`         | int     | `24`                    | Maximum number of listener threads. Default value is: (available processors) \* 3.                                                                                                                                                                                                    |
| `--port`                | int     | `4444`                  | Port to listen on. There is no default as this parameter is used by different components, for example, Router/Hub/Standalone will use 4444 and Node will use 5555.                                                                                                                    |
| `--registration-secret` | string  | `"Hunter2"`             | Shared secret used to authenticate Node registration requests. Must match the value set on the Hub/Distributor.                                                                                                                                                                       |

### SessionQueue

| Option                             | Type   | Value/Example           | Description                                                                                                                                                                            |
| ---------------------------------- | ------ | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--sessionqueue` / `--sq`          | uri    | `http://localhost:1237` | Address of the session queue server.                                                                                                                                                   |
| `--sessionqueue-host`              | string | `localhost`             | Host on which the session queue server is listening.                                                                                                                                   |
| `--sessionqueue-port`              | int    | `1234`                  | Port on which the session queue server is listening.                                                                                                                                   |
| `--session-request-timeout`        | int    | `300`                   | Timeout in seconds. A new incoming session request is added to the queue. Requests sitting in the queue for longer than the configured time will timeout.                              |
| `--session-request-timeout-period` | int    | `10`                    | How often, in seconds, the timeout for queued new session requests is checked.                                                                                                         |
| `--session-retry-interval`         | int    | `15`                    | Retry interval in milliseconds. If all slots are busy, new session request will be retried after the given interval.                                                                   |
| `--sessionqueue-batch-size`        | int    | `20`                    | Maximum number of session requests that can be consumed from the queue at a time, based on the available slots.                                                                        |
| `--maximum-response-delay`         | int    | `8`                     | How often, in seconds, will the SessionQueue respond in case there is no data, to reduce the http requests while polling for new session requests. (Config file only; not a CLI flag.) |

### Sessions

| Option            | Type   | Value/Example           | Description                                        |
| ----------------- | ------ | ----------------------- | -------------------------------------------------- |
| `--sessions`      | uri    | `http://localhost:1234` | Address of the session map server.                 |
| `--sessions-host` | string | `localhost`             | Host on which the session map server is listening. |
| `--sessions-port` | int    | `1234`                  | Port on which the session map server is listening. |

## Configuration examples

All the options mentioned above can be used when starting the Grid components. They are a good way of exploring the Grid options, and trying out values to find a suitable configuration.

We recommend the use of [Toml files](https://www.selenium.dev/documentation/grid/configuration/toml_options/) to configure a Grid. Configuration files improve readability, and you can also check them in source control.

When needed, you can combine a Toml file configuration with CLI arguments.

### Command-line flags

To pass config options as command-line flags, identify the valid options for the component and follow the template below.

```
java -jar selenium-server-<version>.jar <component> --<option> value
```

#### Standalone, setting max sessions and main port

```
java -jar selenium-server-<version>.jar standalone --max-sessions 4 --port 4444
```

#### Hub, setting a new session request timeout, a main port, and disabling tracing

```
java -jar selenium-server-<version>.jar hub --session-request-timeout 500 --port 3333 --tracing false
```

#### Node, with 4 max sessions, with debug(fine) log, 7777 as port, and only with Firefox and Edge

```
java -jar selenium-server-<version>.jar node --max-sessions 4 --log-level "fine" --port 7777 --driver-implementation "firefox" --driver-implementation "edge"
```

#### Distributor, setting Session Map server url, Session Queue server url, and disabling bus

```
java -jar selenium-server-<version>.jar distributor --sessions http://localhost:5556 --sessionqueue http://localhost:5559 --bind-bus false
```

#### Setting custom capabilities for matching specific Nodes

**Important:** Custom capabilities need to be set in the configuration in all Nodes. They also need to be included always in every session request.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node A with custom cap set to `true`

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":true}' --port 6161
```

##### Start the Node B with custom cap set to `false`

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":false}' --port 6262
```

##### Matching Node A

```java
ChromeOptions options = new ChromeOptions();
options.setCapability("gsg:customcap", true);
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

Set the custom capability to `false` in order to match the Node B.

#### Enabling Managed downloads by the Node

At times a test may need to access files that were downloaded by it on the Node. To retrieve such files, following can be done.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node with manage downloads enabled

```
java -jar selenium-server-<version>.jar node --enable-managed-downloads true
```

##### Set the capability at the test level

Tests that want to use this feature should set the capability `"se:downloadsEnabled"`to `true`

```java
options.setCapability("se:downloadsEnabled", true);
```

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

In the response the list of file names appear under the key `names`.

##### Dowloading a file:

* The endpoint to `POST` from is `/session/<sessionId>/se/files` with a payload of the form `{"name": "fileNameGoesHere}`
* The session needs to be active in order for the command to work.
* The raw response looks like below:

```json
{
	"value": {
		"filename": "Red-blue-green-channel.jpg",
		"contents": "Base64EncodedStringContentsOfDownloadedFileAsZipGoesHere"
	}
}
```

* The response blob contains two keys,

  * `filename` - The file name that was downloaded.
  * `contents` - Base64 encoded zipped contents of the file.

* The file contents are Base64 encoded and they need to be unzipped.

##### List files that can be downloaded

The below mentioned `curl` example can be used to list all the files that were downloaded by the current session in the Node, and which can be retrieved locally.

```bash
curl -X GET "http://localhost:4444/session/90c0149a-2e75-424d-857a-e78734943d4c/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

##### Retrieve a downloaded file

Assuming the downloaded file is named `Red-blue-green-channel.jpg`, and using `curl`, the file could be downloaded with the following command:

```bash
curl -H "Accept: application/json" \
-H "Content-Type: application/json; charset=utf-8" \
-X POST -d '{"name":"Red-blue-green-channel.jpg"}' \
"http://localhost:4444/session/18033434-fa4f-4d11-a7df-9e6d75920e19/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "UEsDBBQACAgIAJpagVYAAAAAAAAAAAAAAAAaAAAAUmVkLWJsAAAAAAAAAAAAUmVkLWJsdWUtZ3JlZW4tY2hhbm5lbC5qcGdQSwUGAAAAAAEAAQBIAAAAcNkAAAAA"
  }
}
```

##### Complete sample code in Java

Below is an example in Java that does the following:

* Sets the capability to indicate that the test requires automatic managing of downloaded files.
* Triggers a file download via a browser.
* Lists the files that are available for retrieval from the remote node (These are essentially files that were downloaded in the current session)
* Picks one file and downloads the file from the remote node to the local machine.

```java
import com.google.common.collect.ImmutableMap;

import org.openqa.selenium.By;
import org.openqa.selenium.io.Zip;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.io.File;
import java.net.URL;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import static org.openqa.selenium.remote.http.Contents.asJson;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.HttpMethod.GET;
import static org.openqa.selenium.remote.http.HttpMethod.POST;

public class DownloadsSample {

  public static void main(String[] args) throws Exception {
    // Assuming the Grid is running locally.
    URL gridUrl = new URL("http://localhost:4444");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("se:downloadsEnabled", true);
    RemoteWebDriver driver = new RemoteWebDriver(gridUrl, options);
    try {
      demoFileDownloads(driver, gridUrl);
    } finally {
      driver.quit();
    }
  }

	private static void demoFileDownloads(RemoteWebDriver driver, URL gridUrl) throws Exception {
		driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
		// Download the two available files on the page
		driver.findElement(By.id("file-1")).click();
		driver.findElement(By.id("file-2")).click();

		// The download happens in a remote Node, which makes it difficult to know when the file
		// has been completely downloaded. For demonstration purposes, this example uses a
		// 10-second sleep which should be enough time for a file to be downloaded.
		// We strongly recommend to avoid hardcoded sleeps, and ideally, to modify your
		// application under test, so it offers a way to know when the file has been completely
		// downloaded.
		TimeUnit.SECONDS.sleep(10);

		//This is the endpoint which will provide us with list of files to download and also to
		//let us download a specific file.
		String downloadsEndpoint = String.format("/session/%s/se/files", driver.getSessionId());

		String fileToDownload;

		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To list all files that are were downloaded on the remote node for the current session
			// we trigger GET request.
			HttpRequest request = new HttpRequest(GET, downloadsEndpoint);
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			@SuppressWarnings("unchecked")
			List<String> names = (List<String>) value.get("names");
			// Let's say there were "n" files downloaded for the current session, we would like
			// to retrieve ONLY the first file.
			fileToDownload = names.get(0);
		}

		// Now, let's download the file
		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To retrieve a specific file from one or more files that were downloaded by the current session
			// on a remote node, we use a POST request.
			HttpRequest request = new HttpRequest(POST, downloadsEndpoint);
			request.setContent(asJson(ImmutableMap.of("name", fileToDownload)));
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			// The returned map would contain 2 keys,
			// filename - This represents the name of the file (same as what was provided by the test)
			// contents - Base64 encoded String which contains the zipped file.
			String zippedContents = value.get("contents").toString();
			// The file contents would always be a zip file and has to be unzipped.
			File downloadDir = Zip.unzipToTempDir(zippedContents, "download", "");
			// Read the file contents
			File downloadedFile = Optional.ofNullable(downloadDir.listFiles()).orElse(new File[]{})[0];
			String fileContent = String.join("", Files.readAllLines(downloadedFile.toPath()));
			System.out.println("The file which was "
					+ "downloaded in the node is now available in the directory: "
					+ downloadDir.getAbsolutePath() + " and has the contents: " + fileContent);
		}
	}


}
```

Last modified March 2, 2026: [Update list CLI Options of Selenium Grid align to version 4.41.0 (#2596) (597090a26aa)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/597090a26aafe68dd8148d525416f6e5c3a32623)

----
url: https://www.selenium.dev/zh-cn/documentation/grid/components/
----

# 服务网格的组件

最后修改 May 20, 2025: [docs: Update toml Doc for zh-cn (#2313) (01482d256be)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/01482d256be2764aadc821b120d7d16a00854970)

----
url: https://www.selenium.dev/_print/documentation/webdriver/elements/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/webdriver/elements/).

# Web elements

Identifying and working with element objects in the DOM.

* 1: [Locator strategies](#pg-d540646b1f4f7de028c70df2ded09aaf)
* 2: [Finding web elements](#pg-6bbf3e616099caa9ac048d795e8b5111)
* 3: [Interacting with web elements](#pg-fb14e71e8a9627b07e76fae74adf4f7a)
* 4: [Information about web elements](#pg-7e9cf1eef7ff6e43335f6f3977c47347)
* 5: [File Upload](#pg-9c73e03480273235f3ddb01c3a3a854a)

The majority of most people’s Selenium code involves working with web elements.

# 1 - Locator strategies

Ways to identify one or more specific elements in the DOM.

A locator is a way to identify elements on a page. It is the argument passed to the [Finding element](https://www.selenium.dev/documentation/webdriver/elements/finders/) methods.

Check out our [encouraged test practices](https://www.selenium.dev/documentation/test_practices/encouraged/) for tips on [locators](https://www.selenium.dev/documentation/test_practices/encouraged/locators/), including which to use when and why to declare locators separately from the finding methods.

## Traditional Locators

Selenium provides support for these 8 traditional location strategies in WebDriver:

| Locator           | Description                                                                                                                                   |
| ----------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
| class name        | Locates elements whose class name contains the search value (compound class names are not permitted)                                          |
| css selector      | Locates elements matching a CSS selector                                                                                                      |
| id                | Locates elements whose ID attribute matches the search value                                                                                  |
| name              | Locates elements whose NAME attribute matches the search value                                                                                |
| link text         | Locates anchor elements whose visible text matches the search value                                                                           |
| partial link text | Locates anchor elements whose visible text contains the search value. If multiple elements are matching, only the first one will be selected. |
| tag name          | Locates elements whose tag name matches the search value                                                                                      |
| xpath             | Locates elements matching an XPath expression                                                                                                 |

## Creating Locators

To work on a web element using Selenium, we need to first locate it on the web page. Selenium provides us above mentioned ways, using which we can locate element on the page. To understand and create locator we will use the following HTML snippet.

```html
<html>
<body>
<style>
.information {
  background-color: white;
  color: black;
  padding: 10px;
}
</style>
<h2>Contact Selenium</h2>

<form>
  <input type="radio" name="gender" value="m" />Male &nbsp;
  <input type="radio" name="gender" value="f" />Female <br>
  <br>
  <label for="fname">First name:</label><br>
  <input class="information" type="text" id="fname" name="fname" value="Jane"><br><br>
  <label for="lname">Last name:</label><br>
  <input class="information" type="text" id="lname" name="lname" value="Doe"><br><br>
  <label for="newsletter">Newsletter:</label>
  <input type="checkbox" name="newsletter" value="1" /><br><br>
  <input type="submit" value="Submit">
</form> 

<p>To know more about Selenium, visit the official page 
<a href ="www.selenium.dev">Selenium Official Page</a> 
</p>

</body>
</html>
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L31" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L7-L9)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.ClassName("information"));
  
```

```rb
    driver.find_element(class: 'information')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L7)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.className('information'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.className("information"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L38" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L17-L19)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.CssSelector("#fname"));
  
```

```rb
    driver.find_element(css: '#fname')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L11)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.css('#fname'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.css("#fname"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L45" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L27-L29)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.Id("lname"));
  
```

```rb
    driver.find_element(id: 'lname')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L15)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.id('lname'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.id("lname"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L52" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L37-L39)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.Name("newsletter"));
  
```

```rb
    driver.find_element(name: 'newsletter')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L19)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.name('newsletter'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.name("newsletter"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L59" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L47-L49)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.LinkText("Selenium Official Page"));
  
```

```rb
    driver.find_element(link_text: 'Selenium Official Page')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L23)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.linkText('Selenium Official Page'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.linkText("Selenium Official Page"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L66" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L57-L59)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.PartialLinkText("Official Page"));
  
```

```rb
    driver.find_element(partial_link_text: 'Official Page')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L27)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.partialLinkText('Official Page'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.partialLinkText("Official Page"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L73" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L67-L69)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.TagName("a"));
  
```

```rb
    driver.find_element(tag_name: 'a')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L31)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.tagName('a'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.tagName("a"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L80" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L77-L79)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	  driver.FindElement(By.Xpath("//input[@value='f']"));
  
```

```rb
    driver.find_element(xpath: "//input[@value='f']")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L35)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.xpath('//input[@value='f']'));
  
```

```kotlin
    import org.openqa.selenium.By
    val driver = ChromeDriver()
	  val loc: WebElement = driver.findElement(By.xpath('//input[@value='f']'))
  
```

```java
    import org.openqa.selenium.By;
    WebDriver driver = new ChromeDriver();
	driver.findElement(By.className("information"));
  
```

```python
    from selenium.webdriver.common.by import By
    driver = webdriver.Chrome()
	driver.find_element(By.CLASS_NAME, "information")
  
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.ClassName("information"));
  
```

```rb
    driver.find_element(class: 'information')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L7)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.className('information'));
  
```

```kotlin
    import org.openqa.selenium.By
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.className("information"))
  
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java#L37-L38)

##### /examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java

```java
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java#L22-L23)

##### /examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java

```java
```

```java
By emailLocator = RelativeLocator.with(By.tagName("input")).above(By.id("password"));
```

```python
email_locator = locate_with(By.TAG_NAME, "input").above({By.ID: "password"})
```

```csharp
var emailLocator = RelativeBy.WithLocator(By.TagName("input")).Above(By.Id("password"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L40)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let emailLocator = locateWith(By.tagName('input')).above(By.id('password'));
```

```kotlin
val emailLocator = RelativeLocator.with(By.tagName("input")).above(By.id("password"))
```

```java
By passwordLocator = RelativeLocator.with(By.tagName("input")).below(By.id("email"));
```

```python
password_locator = locate_with(By.TAG_NAME, "input").below({By.ID: "email"})
```

```csharp
var passwordLocator = RelativeBy.WithLocator(By.TagName("input")).Below(By.Id("email"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L44)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let passwordLocator = locateWith(By.tagName('input')).below(By.id('email'));
```

```kotlin
val passwordLocator = RelativeLocator.with(By.tagName("input")).below(By.id("email"))
```

```java
By cancelLocator = RelativeLocator.with(By.tagName("button")).toLeftOf(By.id("submit"));
```

```python
cancel_locator = locate_with(By.TAG_NAME, "button").to_left_of({By.ID: "submit"})
```

```csharp
var cancelLocator = RelativeBy.WithLocator(By.tagName("button")).LeftOf(By.Id("submit"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L48)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let cancelLocator = locateWith(By.tagName('button')).toLeftOf(By.id('submit'));
```

```kotlin
val cancelLocator = RelativeLocator.with(By.tagName("button")).toLeftOf(By.id("submit"))
```

```java
By submitLocator = RelativeLocator.with(By.tagName("button")).toRightOf(By.id("cancel"));
```

```python
submit_locator = locate_with(By.TAG_NAME, "button").to_right_of({By.ID: "cancel"})
```

```csharp
var submitLocator = RelativeBy.WithLocator(By.tagName("button")).RightOf(By.Id("cancel"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L52)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let submitLocator = locateWith(By.tagName('button')).toRightOf(By.id('cancel'));
```

```kotlin
val submitLocator = RelativeLocator.with(By.tagName("button")).toRightOf(By.id("cancel"))
```

```java
By emailLocator = RelativeLocator.with(By.tagName("input")).near(By.id("lbl-email"));
```

```python
email_locator = locate_with(By.TAG_NAME, "input").near({By.ID: "lbl-email"})
```

```csharp
var emailLocator = RelativeBy.WithLocator(By.tagName("input")).Near(By.Id("lbl-email"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L56)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let emailLocator = locateWith(By.tagName('input')).near(By.id('lbl-email'));
```

```kotlin
val emailLocator = RelativeLocator.with(By.tagName("input")).near(By.id("lbl-email"));
```

```java
By submitLocator = RelativeLocator.with(By.tagName("button")).below(By.id("email")).toRightOf(By.id("cancel"));
```

```python
submit_locator = locate_with(By.TAG_NAME, "button").below({By.ID: "email"}).to_right_of({By.ID: "cancel"})
```

```csharp
var submitLocator = RelativeBy.WithLocator(By.tagName("button")).Below(By.Id("email")).RightOf(By.Id("cancel"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L60)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let submitLocator = locateWith(By.tagName('button')).below(By.id('email')).toRightOf(By.id('cancel'));
```

```kotlin
val submitLocator = RelativeLocator.with(By.tagName("button")).below(By.id("email")).toRightOf(By.id("cancel"))
```

# 2 - Finding web elements

Locating the elements based on the provided locator values.

One of the most fundamental aspects of using Selenium is obtaining element references to work with. Selenium offers a number of built-in [locator strategies](https://www.selenium.dev/documentation/webdriver/elements/locators/) to uniquely identify an element. There are many ways to use the locators in very advanced scenarios. For the purposes of this documentation, let’s consider this HTML snippet:

```html
<ol id="vegetables">
 <li class="potatoes">…
 <li class="onions">…
 <li class="tomatoes"><span>Tomato is a Vegetable</span>…
</ol>
<ul id="fruits">
  <li class="bananas">…
  <li class="apples">…
  <li class="tomatoes"><span>Tomato is a Fruit</span>…
</ul>
```

```java
WebElement vegetable = driver.findElement(By.className("tomatoes"));
  
```

```python
vegetable = driver.find_element(By.CLASS_NAME, "tomatoes")
  
```

```csharp
var vegetable = driver.FindElement(By.ClassName("tomatoes"));
  
```

```rb
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L14-L15)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const vegetable = await driver.findElement(By.className('tomatoes'));
  
```

```kotlin
val vegetable: WebElement = driver.findElement(By.className("tomatoes"))
  
```

```java
WebElement fruits = driver.findElement(By.id("fruits"));
WebElement fruit = fruits.findElement(By.className("tomatoes"));
  
```

```python
fruits = driver.find_element(By.ID, "fruits")
fruit = fruits.find_element(By.CLASS_NAME,"tomatoes")
  
```

```csharp
IWebElement fruits = driver.FindElement(By.Id("fruits"));
IWebElement fruit = fruits.FindElement(By.ClassName("tomatoes"));
  
```

```rb
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L14-L15)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const fruits = await driver.findElement(By.id('fruits'));
const fruit = fruits.findElement(By.className('tomatoes'));
  
```

```kotlin
val fruits = driver.findElement(By.id("fruits"))
val fruit = fruits.findElement(By.className("tomatoes"))
  
```

```java
WebElement shadowHost = driver.findElement(By.cssSelector("#shadow_host"));
SearchContext shadowRoot = shadowHost.getShadowRoot();
WebElement shadowContent = shadowRoot.findElement(By.cssSelector("#shadow_content"));
```

```python
shadow_host = driver.find_element(By.CSS_SELECTOR, '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(By.CSS_SELECTOR, '#shadow_content')
```

```csharp
var shadowHost = _driver.FindElement(By.CssSelector("#shadow_host"));
var shadowRoot = shadowHost.GetShadowRoot();
var shadowContent = shadowRoot.FindElement(By.CssSelector("#shadow_content"));
```

```ruby
shadow_host = @driver.find_element(css: '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(css: '#shadow_content')
```

```java
WebElement fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"));
  
```

```python
fruit = driver.find_element(By.CSS_SELECTOR,"#fruits .tomatoes")
  
```

```csharp
var fruit = driver.FindElement(By.CssSelector("#fruits .tomatoes"));
  
```

```rb
      driver.find_element(css: '#fruits .tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L19)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const fruit = await driver.findElement(By.css('#fruits .tomatoes'));
  
```

```kotlin
val fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"))
  
```

```java
List<WebElement> plants = driver.findElements(By.tagName("li"));
  
```

```python
plants = driver.find_elements(By.TAG_NAME, "li")
  
```

```csharp
IReadOnlyList<IWebElement> plants = driver.FindElements(By.TagName("li"));
  
```

```rb
      driver.find_elements(tag_name: 'li')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L23)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const plants = await driver.findElements(By.tagName('li'));
  
```

```kotlin
val plants: List<WebElement> = driver.findElements(By.tagName("li"))
  
```

```java
List<WebElement> elements = driver.findElements(By.tagName("li"));

for (WebElement element : elements) {
    System.out.println("Paragraph text:" + element.getText());
}
  
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Firefox()

    # Navigate to Url
driver.get("https://www.example.com")

    # Get all the elements available with tag name 'p'
elements = driver.find_elements(By.TAG_NAME, 'p')

for e in elements:
    print(e.text)
  
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using System.Collections.Generic;

namespace FindElementsExample {
 class FindElementsExample {
  public static void Main(string[] args) {
   IWebDriver driver = new FirefoxDriver();
   try {
    // Navigate to Url
    driver.Navigate().GoToUrl("https://example.com");

    // Get all the elements available with tag name 'p'
    IList < IWebElement > elements = driver.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }

   } finally {
    driver.Quit();
   }
  }
 }
}
  
```

```rb
      elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L27-L28)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
   
   require 'spec_helper'
   
   RSpec.describe 'Element Finders' do
     let(:driver) { start_session }
   
     context 'without executing finders', skip: 'these are just examples, not actual tests' do
       it 'finds the first matching element' do
         driver.find_element(class: 'tomatoes')
       end
   
       it 'uses a subset of the dom to find an element' do
         fruits = driver.find_element(id: 'fruits')
         fruits.find_element(class: 'tomatoes')
       end
   
       it 'uses an optimized locator' do
         driver.find_element(css: '#fruits .tomatoes')
       end
   
       it 'finds all matching elements' do
         driver.find_elements(tag_name: 'li')
       end
   
       it 'gets an element from a collection' do
         elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'finds element from element' do
         element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'find active element' do
         driver.find_element(css: '[name="q"]').send_keys('webElement')
         driver.switch_to.active_element.attribute('title')
       end
     end
   end
   
```

```javascript
const {Builder, By} = require('selenium-webdriver');
(async function example() {
    let driver = await new Builder().forBrowser('firefox').build();
    try {
        // Navigate to Url
        await driver.get('https://www.example.com');

        // Get all the elements available with tag 'p'
        let elements = await driver.findElements(By.css('p'));
        for(let e of elements) {
            console.log(await e.getText());
        }
    }
    finally {
        await driver.quit();
    }
})();
  
```

```kotlin
import org.openqa.selenium.By
import org.openqa.selenium.firefox.FirefoxDriver

fun main() {
    val driver = FirefoxDriver()
    try {
        driver.get("https://example.com")
        // Get all the elements available with tag name 'p'
        val elements = driver.findElements(By.tagName("p"))
        for (element in elements) {
            println("Paragraph text:" + element.text)
        }
    } finally {
        driver.quit()
    }
}
  
```

```java
  import org.openqa.selenium.By;
  import org.openqa.selenium.WebDriver;
  import org.openqa.selenium.WebElement;
  import org.openqa.selenium.chrome.ChromeDriver;
  import java.util.List;

  public class findElementsFromElement {
      public static void main(String[] args) {
          WebDriver driver = new ChromeDriver();
          try {
              driver.get("https://example.com");

              // Get element with tag name 'div'
              WebElement element = driver.findElement(By.tagName("div"));

              // Get all the elements available with tag name 'p'
              List<WebElement> elements = element.findElements(By.tagName("p"));
              for (WebElement e : elements) {
                  System.out.println(e.getText());
              }
          } finally {
              driver.quit();
          }
      }
  }
  
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()
driver.get("https://www.example.com")
##get elements from parent element using TAG_NAME

    # Get element with tag name 'div'
element = driver.find_element(By.TAG_NAME, 'div')

    # Get all the elements available with tag name 'p'
elements = element.find_elements(By.TAG_NAME, 'p')
for e in elements:
    print(e.text)

##get elements from parent element using XPATH
##NOTE: in order to utilize XPATH from current element, you must add "." to beginning of path

    # Get first element of tag 'ul'
element = driver.find_element(By.XPATH, '//ul')

    # get children of tag 'ul' with tag 'li'
elements  = element.find_elements(By.XPATH, './/li')
for e in elements:
    print(e.text)
  
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace FindElementsFromElement {
 class FindElementsFromElement {
  public static void Main(string[] args) {
   IWebDriver driver = new ChromeDriver();
   try {
    driver.Navigate().GoToUrl("https://example.com");

    // Get element with tag name 'div'
    IWebElement element = driver.FindElement(By.TagName("div"));

    // Get all the elements available with tag name 'p'
    IList < IWebElement > elements = element.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }
   } finally {
    driver.Quit();
   }
  }
 }
}
  
```

```rb
      element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L32-L34)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
   
   require 'spec_helper'
   
   RSpec.describe 'Element Finders' do
     let(:driver) { start_session }
   
     context 'without executing finders', skip: 'these are just examples, not actual tests' do
       it 'finds the first matching element' do
         driver.find_element(class: 'tomatoes')
       end
   
       it 'uses a subset of the dom to find an element' do
         fruits = driver.find_element(id: 'fruits')
         fruits.find_element(class: 'tomatoes')
       end
   
       it 'uses an optimized locator' do
         driver.find_element(css: '#fruits .tomatoes')
       end
   
       it 'finds all matching elements' do
         driver.find_elements(tag_name: 'li')
       end
   
       it 'gets an element from a collection' do
         elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'finds element from element' do
         element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'find active element' do
         driver.find_element(css: '[name="q"]').send_keys('webElement')
         driver.switch_to.active_element.attribute('title')
       end
     end
   end
   
```

```javascript
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = new Builder()
          .forBrowser('chrome')
          .build();

      await driver.get('https://www.example.com');

      // Get element with tag name 'div'
      let element = driver.findElement(By.css("div"));

      // Get all the elements available with tag name 'p'
      let elements = await element.findElements(By.css("p"));
      for(let e of elements) {
          console.log(await e.getText());
      }
  })();
  
```

```kotlin
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://example.com")

          // Get element with tag name 'div'
          val element = driver.findElement(By.tagName("div"))

          // Get all the elements available with tag name 'p'
          val elements = element.findElements(By.tagName("p"))
          for (e in elements) {
              println(e.text)
          }
      } finally {
          driver.quit()
      }
  }
  
```

```java
  import org.openqa.selenium.*;
  import org.openqa.selenium.chrome.ChromeDriver;

  public class activeElementTest {
    public static void main(String[] args) {
      WebDriver driver = new ChromeDriver();
      try {
        driver.get("http://www.google.com");
        driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement");

        // Get attribute of current active element
        String attr = driver.switchTo().activeElement().getAttribute("title");
        System.out.println(attr);
      } finally {
        driver.quit();
      }
    }
  }
  
```

```python
  from selenium import webdriver
  from selenium.webdriver.common.by import By

  driver = webdriver.Chrome()
  driver.get("https://www.google.com")
  driver.find_element(By.CSS_SELECTOR, '[name="q"]').send_keys("webElement")

    # Get attribute of current active element
  attr = driver.switch_to.active_element.get_attribute("title")
  print(attr)
  
```

```csharp
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;

    namespace ActiveElement {
     class ActiveElement {
      public static void Main(string[] args) {
       IWebDriver driver = new ChromeDriver();
       try {
        // Navigate to Url
        driver.Navigate().GoToUrl("https://www.google.com");
        driver.FindElement(By.CssSelector("[name='q']")).SendKeys("webElement");

        // Get attribute of current active element
        string attr = driver.SwitchTo().ActiveElement().GetAttribute("title");
        System.Console.WriteLine(attr);
       } finally {
        driver.Quit();
       }
      }
     }
    }
  
```

```rb
      driver.find_element(css: '[name="q"]').send_keys('webElement')
        driver.switch_to.active_element.attribute('title')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L38-L39)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
  
  require 'spec_helper'
  
  RSpec.describe 'Element Finders' do
    let(:driver) { start_session }
  
    context 'without executing finders', skip: 'these are just examples, not actual tests' do
      it 'finds the first matching element' do
        driver.find_element(class: 'tomatoes')
      end
  
      it 'uses a subset of the dom to find an element' do
        fruits = driver.find_element(id: 'fruits')
        fruits.find_element(class: 'tomatoes')
      end
  
      it 'uses an optimized locator' do
        driver.find_element(css: '#fruits .tomatoes')
      end
  
      it 'finds all matching elements' do
        driver.find_elements(tag_name: 'li')
      end
  
      it 'gets an element from a collection' do
        elements = driver.find_elements(:tag_name, 'p')
        elements.each { |e| puts e.text }
      end
  
      it 'finds element from element' do
        element = driver.find_element(:tag_name, 'div')
        elements = element.find_elements(:tag_name, 'p')
        elements.each { |e| puts e.text }
      end
  
      it 'find active element' do
        driver.find_element(css: '[name="q"]').send_keys('webElement')
        driver.switch_to.active_element.attribute('title')
      end
    end
  end
  
```

```javascript
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = await new Builder().forBrowser('chrome').build();
      await driver.get('https://www.google.com');
      await  driver.findElement(By.css('[name="q"]')).sendKeys("webElement");

      // Get attribute of current active element
      let attr = await driver.switchTo().activeElement().getAttribute("title");
      console.log(`${attr}`)
  })();
  
```

```kotlin
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://www.google.com")
          driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement")

          // Get attribute of current active element
          val attr = driver.switchTo().activeElement().getAttribute("title")
          print(attr)
      } finally {
          driver.quit()
      }
  }
  
```

# 3 - Interacting with web elements

```java
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L18-L22)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L12-L17)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L17-L21)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'color_input').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L11)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
    await submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L20)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
  const assert = require("assert");
  
  (async function firstTest() {
    let driver;
    
    try {
      driver = await new Builder().forBrowser(Browser.CHROME).build();
      await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
    
      let title = await driver.getTitle();
      assert.equal("Web form", title);
    
      await driver.manage().setTimeouts({implicit: 500});
    
      let textBox = await driver.findElement(By.name('my-text'));
      let submitButton = await driver.findElement(By.css('button'));
    
      await textBox.sendKeys('Selenium');
      await submitButton.click();
    
      let message = await driver.findElement(By.id('message'));
      let value = await message.getText();
      assert.equal("Received!", value);
    } catch (e) {
      console.log(e)
    } finally {
      await driver.quit();
    }
  }())
  
```

```kotlin
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    // Click the element
    driver.findElement(By.name("color_input")).click();
  
  
```

```java
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L27-L32)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L22-L27)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L27-L33)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L16)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
      let inputField = await driver.findElement(By.name('no_type'));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/interactions.spec.js#L21)

##### /examples/javascript/test/elements/interactions.spec.js

```js

  const {By, Browser, Builder} = require('selenium-webdriver');
  const assert = require("node:assert");
  
  
  describe('Element Interactions', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('should Clear input and send keys into input field', async function () {
  
      try {
        await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
        let inputField = await driver.findElement(By.name('no_type'));
        await inputField.clear();
        await inputField.sendKeys('Selenium');
        const text = await inputField.getAttribute('value');
        assert.strictEqual(text, "Selenium");
      } catch (e) {
        console.log(e)
      }
    });
  });
```

```kotlin
  
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

	//Clear field to empty it from any previous data
	driver.findElement(By.name("email_input")).clear()
	
    // Enter text 
    driver.findElement(By.name("email_input")).sendKeys("admin@localhost.dev")
  
  
```

```java
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L38-L40)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    email_input.clear()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L34)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L40-L43)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'email_input').clear
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L15)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
      await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/interactions.spec.js#L20)

##### /examples/javascript/test/elements/interactions.spec.js

```js

  const {By, Browser, Builder} = require('selenium-webdriver');
  const assert = require("node:assert");
  
  
  describe('Element Interactions', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('should Clear input and send keys into input field', async function () {
  
      try {
        await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
        let inputField = await driver.findElement(By.name('no_type'));
        await inputField.clear();
        await inputField.sendKeys('Selenium');
        const text = await inputField.getAttribute('value');
        assert.strictEqual(text, "Selenium");
      } catch (e) {
        console.log(e)
      }
    });
  });
```

```kotlin
  
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

	//Clear field to empty it from any previous data
	driver.findElement(By.name("email_input")).clear()
	
  
  
```

## Submit

In Selenium 4 this is no longer implemented with a separate endpoint and functions by executing a script. As such, it is recommended not to use this method and to click the applicable form submission button instead.

# 4 - Information about web elements

```java
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L27-L29)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L12-L15)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L18-L22)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    displayed_value = driver.find_element(name: 'email_input').displayed?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L12)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L16-L17)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
 //navigates to url
 driver.get("https://www.selenium.dev/selenium/web/inputs.html")

 //returns true if element is displayed else returns false
 val flag = driver.findElement(By.name("email_input")).isDisplayed()
```

```java
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L32-L34)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L19)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L25-L27)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    enabled_value = driver.find_element(name: 'email_input').enabled?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L17)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L23-L24)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
 //navigates to url
 driver.get("https://www.selenium.dev/selenium/web/inputs.html")

 //returns true if element is enabled else returns false
 val attr = driver.findElement(By.name("button_input")).isEnabled()
  
```

```java
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L37-L39)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L23)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
  from selenium.webdriver.common.by import By
  
  import pytest
  
  
  def test_informarion():
      # Initialize WebDriver
      driver = webdriver.Chrome()
      driver.implicitly_wait(0.5)
  
      driver.get("https://www.selenium.dev/selenium/web/inputs.html")
  
      # isDisplayed
      is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
      assert is_email_visible == True
  
      # isEnabled
      is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
      assert is_enabled_button == True
  
      # isSelected
      is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
      assert is_selected_check == True
  
      # TagName
      tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
      assert tag_name_inp == "input"
  
      # GetRect
      rect = driver.find_element(By.NAME, "range_input").rect
      assert rect["x"] == 10
  
      # CSS Value
      css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
          "font-size"
      )
      assert css_value == "13.3333px"
  
      # GetText
      text = driver.find_element(By.TAG_NAME, "h1").text
      assert text == "Testing Inputs"
  
      # FetchAttributes
      email_txt = driver.find_element(By.NAME, "email_input")
      value_info = email_txt.get_attribute("value")
      assert value_info == "admin@localhost"
  
```

```cs
            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L30-L32)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    selected_value = driver.find_element(name: 'email_input').selected?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L22)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L30-L31)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
 //navigates to url
 driver.get("https://www.selenium.dev/selenium/web/inputs.html")

 //returns true if element is checked else returns false
 val attr =  driver.findElement(By.name("checkbox_input")).isSelected()
  
```

```java
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L42-L44)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L27)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L35-L37)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    tag_name = driver.find_element(name: 'email_input').tag_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L27)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L37-L38)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
 //navigates to url
 driver.get("https://www.selenium.dev/selenium/web/inputs.html")

 //returns TagName of the element
 val attr =  driver.findElement(By.name("email_input")).getTagName()
  
```

```java
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L47-L50)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    rect = driver.find_element(By.NAME, "range_input").rect
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L31)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L40-L43)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    size = driver.find_element(name: 'email_input').size
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L32)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    let object = await driver.findElement(By.name('range_input')).getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L45)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

// Returns height, width, x and y coordinates referenced element
val res = driver.findElement(By.name("range_input")).rect

// Rectangle class provides getX,getY, getWidth, getHeight methods
println(res.getX())
  
```

```java
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L52-L54)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L35-L37)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L49-L50)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L38)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true
  
  require 'spec_helper'
  
  RSpec.describe 'Element Information' do
    let(:driver) { start_session }
    let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }
  
    before { driver.get(url) }
  
    it 'checks if an element is displayed' do
      displayed_value = driver.find_element(name: 'email_input').displayed?
      expect(displayed_value).to be_truthy
    end
  
    it 'checks if an element is enabled' do
      enabled_value = driver.find_element(name: 'email_input').enabled?
      expect(enabled_value).to be_truthy
    end
  
    it 'checks if an element is selected' do
      selected_value = driver.find_element(name: 'email_input').selected?
      expect(selected_value).to be_falsey
    end
  
    it 'gets the tag name of an element' do
      tag_name = driver.find_element(name: 'email_input').tag_name
      expect(tag_name).not_to be_empty
    end
  
    it 'gets the size and position of an element' do
      size = driver.find_element(name: 'email_input').size
      expect(size.width).to be_positive
      expect(size.height).to be_positive
    end
  
    it 'gets the css value of an element' do
      css_value = driver.find_element(name: 'email_input').css_value('background-color')
      expect(css_value).not_to be_empty
    end
  
    it 'gets the text of an element' do
      text = driver.find_element(xpath: '//h1').text
      expect(text).to eq('Testing Inputs')
    end
  
    it 'gets the attribute value of an element' do
      attribute_value = driver.find_element(name: 'number_input').attribute('value')
      expect(attribute_value).not_to be_empty
    end
  end
  
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
      // Returns background color of the element
      let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L76-L78)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
  const assert = require("assert");
  
  describe('Element Information Test', function () {
    let driver;
    
    before(async function () {
      driver = await new Builder().forBrowser('chrome').build();
    });
    
    beforeEach(async ()=> {
      await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
    })
    
    it('Check if element is displayed', async function () {
      // Resolves Promise and returns boolean value
      let result =  await driver.findElement(By.name("email_input")).isDisplayed();
      
      assert.equal(result,true);
    });
    
    it('Check if button is enabled', async function () {
      // Resolves Promise and returns boolean value
      let element =  await driver.findElement(By.name("button_input")).isEnabled();
    
      assert.equal(element, true);
    });
    
    it('Check if checkbox is selected', async function () {
      // Returns true if element ins checked else returns false
      let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
    
      assert.equal(isSelected, true);
    });
    
    it('Should return the tagname', async function () {
      // Returns TagName of the element
      let value = await driver.findElement(By.name('email_input')).getTagName();
    
      assert.equal(value, "input");
    });
    
    it('Should be able to fetch element size and position ', async function () {
      // Returns height, width, x and y position of the element
      let object = await driver.findElement(By.name('range_input')).getRect();
      
      assert.ok(object.height!==null)
      assert.ok(object.width!==null)
      assert.ok(object.y!==null)
      assert.ok(object.x!==null)
      
    });
    
    it('Should be able to fetch attributes and properties ', async function () {
      // identify the email text box
      const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
      
      //fetch the attribute "name" associated with the textbox
      const nameAttribute = await emailElement.getAttribute("name");
    
      assert.equal(nameAttribute, "email_input")
    });
    
    after(async () => await driver.quit());
  });
  
  
  describe('Element Information Test', function () {
    let driver;
    
    before(async function () {
      driver = await new Builder().forBrowser('chrome').build();
    });
    
    it('Should return the css specified CSS value', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
      // Returns background color of the element
      let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
      
      assert.equal(value, "rgba(0, 128, 0, 1)");
    });
    
    it('Should return the css specified CSS value', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
      // Returns text of the element
      let text = await driver.findElement(By.id('justanotherLink')).getText();
      
      assert.equal(text, "Just another link.");
    });
    
    after(async () => await driver.quit());
  });
```

```kotlin
// Navigate to Url
driver.get("https://www.selenium.dev/selenium/web/colorPage.html")

// Retrieves the computed style property 'color' of linktext
val cssValue = driver.findElement(By.id("namedColor")).getCssValue("background-color")

  
```

```java
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L58-L60)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    text = driver.find_element(By.TAG_NAME, "h1").text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L41)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L53-L55)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    text = driver.find_element(xpath: '//h1').text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L43)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L84-L86)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to URL
driver.get("https://www.selenium.dev/selenium/web/linked_image.html")

// retrieves the text of the element
val text = driver.findElement(By.id("justanotherlink")).getText()
  
```

```java
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L64-L68)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L44-L46)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L58-L62)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L48)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L55-L59)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to URL
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//fetch the value property associated with the textbox
val attr = driver.findElement(By.name("email_input")).getAttribute("value")
  
```

```java
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/FileUploadTest.java#L17-L19)

##### /examples/java/src/test/java/dev/selenium/elements/FileUploadTest.java

```java
package dev.selenium.elements;

import dev.selenium.BaseChromeTest;
import java.io.File;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

public class FileUploadTest extends BaseChromeTest {

  @Test
  public void fileUploadTest() {
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }
}
```

```py
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_file_upload.py#L12-L14)

##### /examples/python/tests/elements/test\_file\_upload.py

```py
import os

from selenium import webdriver
from selenium.webdriver.common.by import By


def test_uploads(driver):
    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"
```

```cs
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/FileUploadTest.cs#L21-L23)

##### /examples/dotnet/SeleniumDocs/Elements/FileUploadTest.cs

```cs
using System;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;

namespace SeleniumDocs.Elements
{
    [TestClass]
    public class FileUploadTest : BaseChromeTest
    {
        [TestMethod]
        public void Uploads()
        {
            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }
    }
}
```

```rb
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/file_upload_spec.rb#L12-L14)

##### /examples/ruby/spec/elements/file\_upload\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'File Upload' do
  let(:driver) { start_session }

  it 'uploads' do
    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    file_name = driver.find_element(id: 'uploaded-files')
    expect(file_name.text).to eq 'selenium-snapshot.png'
  end
end
```

```js
    await driver.get('https://the-internet.herokuapp.com/upload');
    // Upload snapshot
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/fileUpload.spec.js#L24-L25)

##### /examples/javascript/test/elements/fileUpload.spec.js

```js

const {Browser, By, until, Builder} = require("selenium-webdriver");
const path = require("path");
const assert = require('node:assert');


describe('File Upload Test', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async() => await driver.quit());

  it('Should be able to upload a file successfully', async function() {
    const image = path.resolve('./test/resources/selenium-snapshot.png')

    await driver.manage().setTimeouts({implicit: 5000});

    // Navigate to URL
    await driver.get('https://the-internet.herokuapp.com/upload');
    // Upload snapshot
    await driver.findElement(By.id("file-upload")).sendKeys(image);
    await driver.findElement(By.id("file-submit")).submit();

    const revealed = await driver.findElement(By.id('uploaded-files'))
    await driver.wait(until.elementIsVisible(revealed), 2000);
    const data = await driver.findElement(By.css('h3'));

    assert.equal(await data.getText(), `File Uploaded!`);
  });
});
```

----
url: https://www.selenium.dev/documentation/webdriver/browsers/edge/
----

# Edge specific functionality

```java

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L38-L39)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options = get_default_edge_options()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L9-L10)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        {
            var options = new EdgeOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L30-L31)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let options = new edge.Options();
    driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/openEdgeTest.spec.js#L11-L15)

##### /examples/javascript/test/getting\_started/openEdgeTest.spec.js

```js
const {Browser, Builder} = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');


describe('Open Edge', function () {
  let driver;



  before(async function () {
    let options = new edge.Options();
    driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options)
      .build();
  });

  after(async () => await driver.quit());

  it('Basic Edge test', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
  public void arguments() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L46)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L18)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L39)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.args << '--start-maximized'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L17)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.addArguments('--headless=new'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L12)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```java
  public void setBrowserLocation() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L55)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L29)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L49)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.binary = edge_location
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L25)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L66)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L40)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L61)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.add_extension(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L34)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L55)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L51)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

**Note**: This is already the default behavior in .NET.

```rb
      options.detach = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L45)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.detachDriver(true))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L32)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```java
  public void excludeSwitches() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L79)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L62)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L76)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.exclude_switches << 'disable-popup-blocking'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L53)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L22)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```java
  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L101)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY`\
Property value: String representing path to log file

```py
def test_log_to_file(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L71)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L86)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L67)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    File logLocation = getTempFile("logsToConsole", ".log");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L114)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
def test_log_to_stdout(capfd):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L82)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

`$stdout` and `$stderr` are both valid values

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L76)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L127-L128)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY`\
Property value: String representation of `ChromiumDriverLogLevel` enum

```py
def test_log_level(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L93)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '--log-level=DEBUG'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L87)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L143-L144)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows toggling these features by System Property:\
Property keys: `EdgeDriverService.EDGE_DRIVER_APPEND_LOG_PROPERTY` and `EdgeDriverService.EDGE_DRIVER_READABLE_TIMESTAMP`\
Property value: `"true"` or `"false"`

```py
def test_log_features(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L104)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << '--append-log'
      service.args << '--readable-timestamp'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L97-L98)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L161-L162)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows disabling build checks by System Property:\
Property key: `EdgeDriverService.EDGE_DRIVER_DISABLE_BUILD_CHECK`\
Property value: `"true"` or `"false"`

```py
def test_build_checks(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L115)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L155)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << '--disable-build-check'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L108)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L225-L230)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L170-L174)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L119-L123)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L198-L204)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L129-L135)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L129)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    consoleLogButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L242)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L186)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      sleep 1
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L141)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    EdgeDriver driver = new EdgeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L184)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L149)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L149-L150)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### DevTools

See the [Chrome DevTools](https://www.selenium.dev/documentation/webdriver/bidi/cdp/) section for more information about using DevTools in Edge

----
url: https://www.selenium.dev/documentation/test_practices/discouraged/two_factor_authentication/
----

# Two Factor Authentication

Two Factor Authentication (2FA) is an authorization mechanism where a One Time Password (OTP) is generated using “Authenticator” mobile apps such as “Google Authenticator”, “Microsoft Authenticator” etc., or by SMS, e-mail to authenticate. Automating this seamlessly and consistently is a big challenge in Selenium. There are some ways to automate this process. But that will be another layer on top of our Selenium tests and not as secure. So, you should avoid automating 2FA.

There are few options to get around 2FA checks:

* If you want the functionality to still be tested, one option is to ask your team to create a “special token” that will work in test environment. That won’t require usage of a mobile device, and will ensure the test journey is covered.
* Disable 2FA for certain Users in the test environment, so that you can use those user credentials in the automation.
* Disable 2FA in your test environment.
* Disable 2FA if you login from certain IPs. That way we can configure our test machine IPs to avoid this.

Last modified February 18, 2024: [Changes proposed to fix issue (#1280) (d18dcbc6958)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/d18dcbc6958a18a475d49b9dc178b6395a9d6bbf)

----
url: https://www.selenium.dev/zh-cn/documentation/legacy/selenium_1/
----

# Selenium RC (Selenium 1)

```shell
    java -jar selenium-server-standalone-<version-number>.jar
```

通过创建包含上述命令的批处理或Shell可执行文件 (Windows上为.bat, Linux上为.sh), 可以简化此操作. 然后在桌面上对该可执行文件创建快捷方式, 只需双击该图标即可启动服务器.

为了使服务器运行, 您需要安装Java并正确配置PATH环境变量才能从控制台运行它. 您可以通过在控制台上运行以下命令来检查是否正确安装了Java.

```shell
       java -version
```

|                   |                            |             |
| ----------------- | -------------------------- | ----------- |
| open              | /                          |             |
| type              | q                          | selenium rc |
| clickAndWait      | btnG                       |             |
| assertTextPresent | Results \* for selenium rc |             |

注意：此示例适用于Google搜索页面 <http://www.google.com>

### Selenese作为编程代码

这是(通过Selenium-IDE)导出到每种支持的编程语言的测试脚本. 如果您具有基本的面向对象编程语言的基础知识, 则可以通过阅读以下示例之一 来了解Selenium如何运行Selenese命令. 要查看特定语言的示例, 请选择以下按钮之一.

#### CSharp

```csharp

        using System;
        using System.Text;
        using System.Text.RegularExpressions;
        using System.Threading;
        using NUnit.Framework;
        using Selenium;

        namespace SeleniumTests
        {
            [TestFixture]
            public class NewTest
            {
                private ISelenium selenium;
                private StringBuilder verificationErrors;
                
                [SetUp]
                public void SetupTest()
                {
                    selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
                    selenium.Start();
                    verificationErrors = new StringBuilder();
                }
                
                [TearDown]
                public void TeardownTest()
                {
                    try
                    {
                        selenium.Stop();
                    }
                    catch (Exception)
                    {
                        // Ignore errors if unable to close the browser
                    }
                    Assert.AreEqual("", verificationErrors.ToString());
                }
                
                [Test]
                public void TheNewTest()
                {
                    selenium.Open("/");
                    selenium.Type("q", "selenium rc");
                    selenium.Click("btnG");
                    selenium.WaitForPageToLoad("30000");
                    Assert.AreEqual("selenium rc - Google Search", selenium.GetTitle());
                }
            }
        }
```

#### Java

```java
      
	  /** Add JUnit framework to your classpath if not already there 
	   *  for this example to work
	  */
      package com.example.tests;

      import com.thoughtworks.selenium.*;
      import java.util.regex.Pattern;

      public class NewTest extends SeleneseTestCase {
          public void setUp() throws Exception {
              setUp("http://www.google.com/", "*firefox");
          }
            public void testNew() throws Exception {
                selenium.open("/");
                selenium.type("q", "selenium rc");
                selenium.click("btnG");
                selenium.waitForPageToLoad("30000");
                assertTrue(selenium.isTextPresent("Results * for selenium rc"));
          }
      }
```

#### Php

```php
      <?php

      require_once 'PHPUnit/Extensions/SeleniumTestCase.php';

      class Example extends PHPUnit_Extensions_SeleniumTestCase
      {
        function setUp()
        {
          $this->setBrowser("*firefox");
          $this->setBrowserUrl("http://www.google.com/");
        }

        function testMyTestCase()
        {
          $this->open("/");
          $this->type("q", "selenium rc");
          $this->click("btnG");
          $this->waitForPageToLoad("30000");
          $this->assertTrue($this->isTextPresent("Results * for selenium rc"));
        }
      }
      ?>
```

#### Python

```python

     from selenium import selenium
      import unittest, time, re

      class NewTest(unittest.TestCase):
          def setUp(self):
              self.verificationErrors = []
              self.selenium = selenium("localhost", 4444, "*firefox",
                      "http://www.google.com/")
              self.selenium.start()
         
          def test_new(self):
              sel = self.selenium
              sel.open("/")
              sel.type("q", "selenium rc")
              sel.click("btnG")
              sel.wait_for_page_to_load("30000")
              self.failUnless(sel.is_text_present("Results * for selenium rc"))
         
          def tearDown(self):
              self.selenium.stop()
              self.assertEqual([], self.verificationErrors)
```

#### Ruby

```ruby

      require "selenium/client"
      require "test/unit"

      class NewTest < Test::Unit::TestCase
        def setup
          @verification_errors = []
          if $selenium
            @selenium = $selenium
          else
            @selenium =  Selenium::Client::Driver.new("localhost", 4444, "*firefox", "http://www.google.com/", 60);
            @selenium.start
          end
          @selenium.set_context("test_new")
        end

        def teardown
          @selenium.stop unless $selenium
          assert_equal [], @verification_errors
        end

        def test_new
          @selenium.open "/"
          @selenium.type "q", "selenium rc"
          @selenium.click "btnG"
          @selenium.wait_for_page_to_load "30000"
          assert @selenium.is_text_present("Results * for selenium rc")
        end
      end
```

```java
    selenium = new DefaultSelenium("localhost", 4444, "*iehta", "http://www.google.com/");
```

Selenium-IDE生成的代码将如下所示. 此示例具有手动添加的注释, 以提高清晰度.

```java
   package com.example.tests;
   // We specify the package of our tests

   import com.thoughtworks.selenium.*;
   // This is the driver's import. You'll use this for instantiating a
   // browser and making it do what you need.

   import java.util.regex.Pattern;
   // Selenium-IDE add the Pattern module because it's sometimes used for 
   // regex validations. You can remove the module if it's not used in your 
   // script.

   public class NewTest extends SeleneseTestCase {
   // We create our Selenium test case

         public void setUp() throws Exception {
           setUp("http://www.google.com/", "*firefox");
                // We instantiate and start the browser
         }

         public void testNew() throws Exception {
              selenium.open("/");
              selenium.type("q", "selenium rc");
              selenium.click("btnG");
              selenium.waitForPageToLoad("30000");
              assertTrue(selenium.isTextPresent("Results * for selenium rc"));
              // These are the real test steps
        }
   }
```

### `C#`

.NET客户端驱动程序可与Microsoft.NET一起使用. 它可以与任何.NET测试框架( 如NUnit或Visual Studio 2005 Team System)一起使用.

Selenium-IDE假定您将使用NUnit作为测试框架. 您可以在下面的生成的代码中看到这一点. 它包含NUnit的using语句以及相应的NUnit属性, 这些属性标识测试类的每个成员函数的角色.

您可能必须将测试类从" NewTest"重命名为您自己选择的名称. 另外, 您将需要在语句中更改浏览器打开参数:

```csharp
    selenium = new DefaultSelenium("localhost", 4444, "*iehta", "http://www.google.com/");
```

生成的代码将类似于此.

```csharp

    using System;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading;
    using NUnit.Framework;
    using Selenium;
    
    namespace SeleniumTests

    {
        [TestFixture]

        public class NewTest

        {
        private ISelenium selenium;

        private StringBuilder verificationErrors;

        [SetUp]

        public void SetupTest()

        {
            selenium = new DefaultSelenium("localhost", 4444, "*iehta",
            "http://www.google.com/");

            selenium.Start();

            verificationErrors = new StringBuilder();
        }

        [TearDown]

        public void TeardownTest()
        {
            try
            {
            selenium.Stop();
            }

            catch (Exception)
            {
            // Ignore errors if unable to close the browser
            }

            Assert.AreEqual("", verificationErrors.ToString());
        }
        [Test]

        public void TheNewTest()
        {
            // Open Google search engine.        
            selenium.Open("http://www.google.com/"); 
            
            // Assert Title of page.
            Assert.AreEqual("Google", selenium.GetTitle());
            
            // Provide search term as "Selenium OpenQA"
            selenium.Type("q", "Selenium OpenQA");
            
            // Read the keyed search term and assert it.
            Assert.AreEqual("Selenium OpenQA", selenium.GetValue("q"));
            
            // Click on Search button.
            selenium.Click("btnG");
            
            // Wait for page to load.
            selenium.WaitForPageToLoad("5000");
            
            // Assert that "www.openqa.org" is available in search results.
            Assert.IsTrue(selenium.IsTextPresent("www.openqa.org"));
            
            // Assert that page title is - "Selenium OpenQA - Google Search"
            Assert.AreEqual("Selenium OpenQA - Google Search", 
                         selenium.GetTitle());
        }
        }
    }
```

您可以允许NUnit管理测试的执行. 或者, 您可以编写一个简单的 `main()` 程序, 该程序实例化测试对象并依次运行三个方法 `SetupTest()`, `TheNewTest()`和 `TeardownTest()` .

### Python

Pyunit是用于Python的测试框架.

基本测试结构是:

```python

   from selenium import selenium
   # This is the driver's import.  You'll use this class for instantiating a
   # browser and making it do what you need.

   import unittest, time, re
   # This are the basic imports added by Selenium-IDE by default.
   # You can remove the modules if they are not used in your script.

   class NewTest(unittest.TestCase):
   # We create our unittest test case

       def setUp(self):
           self.verificationErrors = []
           # This is an empty array where we will store any verification errors
           # we find in our tests

           self.selenium = selenium("localhost", 4444, "*firefox",
                   "http://www.google.com/")
           self.selenium.start()
           # We instantiate and start the browser

       def test_new(self):
           # This is the test code.  Here you should put the actions you need
           # the browser to do during your test.
            
           sel = self.selenium
           # We assign the browser to the variable "sel" (just to save us from 
           # typing "self.selenium" each time we want to call the browser).
            
           sel.open("/")
           sel.type("q", "selenium rc")
           sel.click("btnG")
           sel.wait_for_page_to_load("30000")
           self.failUnless(sel.is_text_present("Results * for selenium rc"))
           # These are the real test steps

       def tearDown(self):
           self.selenium.stop()
           # we close the browser (I'd recommend you to comment this line while
           # you are creating and debugging your tests)

           self.assertEqual([], self.verificationErrors)
           # And make the test fail if we found that any verification errors
           # were found
```

### Ruby

Selenium-IDE的旧版本(2.0之前的版本)生成 需要旧Selenium gem的Ruby代码. 因此, 建议如下更新IDE生成的所有Ruby脚本:

1. 在第一行, 修改 `require "selenium"` 为 `require "selenium/client"`

2. 在第十一行, 修改 `Selenium::SeleniumDriver.new` 为 `Selenium::Client::Driver.new`

您可能还希望将类名更改为比"无标题"更具信息性的名称, 并将测试方法的名称更改为 “test\_untitled"以外的名称.

这是一个通过修改Selenium IDE 生成的Ruby代码创建的简单示例, 如上所述.

```ruby

   # load the Selenium-Client gem
   require "selenium/client"

   # Load Test::Unit, Ruby's default test framework.
   # If you prefer RSpec, see the examples in the Selenium-Client
   # documentation.
   require "test/unit"

   class Untitled < Test::Unit::TestCase

     # The setup method is called before each test.
     def setup

       # This array is used to capture errors and display them at the
       # end of the test run.
       @verification_errors = []

       # Create a new instance of the Selenium-Client driver.
       @selenium = Selenium::Client::Driver.new \
         :host => "localhost",
         :port => 4444,
         :browser => "*chrome",
         :url => "http://www.google.com/",
         :timeout_in_second => 60

       # Start the browser session
       @selenium.start

       # Print a message in the browser-side log and status bar
       # (optional).
       @selenium.set_context("test_untitled")

     end

     # The teardown method is called after each test.
     def teardown

       # Stop the browser session.
       @selenium.stop

       # Print the array of error messages, if any.
       assert_equal [], @verification_errors
     end

     # This is the main body of your test.
     def test_untitled
     
       # Open the root of the site we specified when we created the
       # new driver instance, above.
       @selenium.open "/"

       # Type 'selenium rc' into the field named 'q'
       @selenium.type "q", "selenium rc"

       # Click the button named "btnG"
       @selenium.click "btnG"

       # Wait for the search results page to load.
       # Note that we don't need to set a timeout here, because that
       # was specified when we created the new driver instance, above.
       @selenium.wait_for_page_to_load

       begin

          # Test whether the search results contain the expected text.
	  # Notice that the star (*) is a wildcard that matches any
	  # number of characters.
	  assert @selenium.is_text_present("Results * for selenium rc")
	  
       rescue Test::Unit::AssertionFailedError
       
          # If the assertion fails, push it onto the array of errors.
	  @verification_errors << $!

       end
     end
   end
```

### Perl, PHP

文档团队的成员尚未将Selenium RC与Perl或PHP一起使用. 如果您将Selenium RC和这两种语言一起使用, 请联系文档团队(请参阅贡献一章). 我们很乐意提供一些您的经验和示例, 以支持Perl和PHP用户.

## 学习 API

Selenium RC API使用命名约定, 假设您了解Selenese, 则大部分接口将是不言自明的. 但是, 在这里, 我们解释了最关键且可能不太明显的方面.

### 启动浏览器

#### CSharp

```csharp
      selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
      selenium.Start();
```

#### Java

```java

      setUp("http://www.google.com/", "*firefox");
```

#### Perl

```perl
      my $sel = Test::WWW::Selenium->new( host => "localhost", 
                                          port => 4444, 
                                          browser => "*firefox", 
                                          browser_url => "http://www.google.com/" );
```

#### Php

```php
      $this->setBrowser("*firefox");
      $this->setBrowserUrl("http://www.google.com/");
```

#### Python

```python
      self.selenium = selenium("localhost", 4444, "*firefox",
                               "http://www.google.com/")
      self.selenium.start()
```

#### Ruby

```ruby
      @selenium = Selenium::ClientDriver.new("localhost", 4444, "*firefox", "http://www.google.com/", 10000);
      @selenium.start
```

```
    selenium.type("field-id","string to type")
```

|                   |                              |               |
| ----------------- | ---------------------------- | ------------- |
| open              | /                            |               |
| type              | q                            | selenium rc   |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium rc   |               |
| type              | q                            | selenium ide  |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium ide  |               |
| type              | q                            | selenium grid |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium grid |               |

该代码已重复执行3次相同的步骤. 但是, 同一代码的多个副本不是良好的编程习惯, 因为维护起来需要做更多的工作. 通过使用编程语言, 我们可以遍历搜索结果以提供更灵活和可维护的解决方案.

#### 在 `C#` 中

```csharp
   // Collection of String values.
   String[] arr = {"ide", "rc", "grid"};    
        
   // Execute loop for each String in array 'arr'.
   foreach (String s in arr) {
       sel.open("/");
       sel.type("q", "selenium " +s);
       sel.click("btnG");
       sel.waitForPageToLoad("30000");
       assertTrue("Expected text: " +s+ " is missing on page."
       , sel.isTextPresent("Results * for selenium " + s));
    }
```

### 条件陈述

为了说明在测试中的使用条件, 我们将从一个示例开始. 当页面上没有预期的元素时, 会发生运行Selenium测试时遇到的常见问题. 例如, 当运行以下行时:

```
   selenium.type("q", "selenium " +s);
```

如果页面上没有元素"q", 则抛出异常:

```java
   com.thoughtworks.selenium.SeleniumException: ERROR: Element q not found
```

这可能会导致测试中止. 对于某些测试, 这就是您想要的. 但是通常这是不希望的, 因为您的测试脚本还有许多其他后续测试需要执行.

更好的方法是先验证元素是否确实存在, 然后在元素不存在时采取替代方法. 让我们用Java看一下

```java
   // If element is available on page then perform type operation.
   if(selenium.isElementPresent("q")) {
       selenium.type("q", "Selenium rc");
   } else {
       System.out.printf("Element: " +q+ " is not available on page.")
   }
```

这种方法的优点是即使页面上某些UI元素不可用, 也可以继续执行测试.

### 从测试中执行JavaScript

在执行Selenium不直接支持的应用程序时, JavaScript非常方便. Selenium API的 **getEval** 方法.

考虑具有复选框的应用程序, 该复选框没有静态标识符. 在这种情况下, 可以评估Selenium RC中的JavaScript以获取所有复选框的ID, 然后执行它们.

```java
   public static String[] getAllCheckboxIds () { 
		String script = "var inputId  = new Array();";// Create array in java script.
		script += "var cnt = 0;"; // Counter for check box ids.  
		script += "var inputFields  = new Array();"; // Create array in java script.
		script += "inputFields = window.document.getElementsByTagName('input');"; // Collect input elements.
		script += "for(var i=0; i<inputFields.length; i++) {"; // Loop through the collected elements.
		script += "if(inputFields[i].id !=null " +
		"&& inputFields[i].id !='undefined' " +
		"&& inputFields[i].getAttribute('type') == 'checkbox') {"; // If input field is of type check box and input id is not null.
		script += "inputId[cnt]=inputFields[i].id ;" + // Save check box id to inputId array.
		"cnt++;" + // increment the counter.
		"}" + // end of if.
		"}"; // end of for.
		script += "inputId.toString();" ;// Convert array in to string.			
		String[] checkboxIds = selenium.getEval(script).split(","); // Split the string.
		return checkboxIds;
    }
```

计算页面上的图像数量:

```java
   selenium.getEval("window.document.images.length;");
```

记住要在DOM表达式的情况下使用window对象, 因为默认情况下是指Selenium窗口, 而不是测试窗口.

## 服务器选项

启动服务器时, 命令行选项可用于更改默认服务器行为.

回想一下, 通过运行以下命令来启动服务器.

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar
```

要查看选项列表, 请使用 `-h` 选项运行服务器.

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar -h
```

您会看到服务器可以使用的所有选项的列表 以及每个选项的简要说明. 提供的描述并不总是足够的, 因此我们提供了一些更重要选项的解释.

### 代理配置

如果您的AUT在需要身份验证的HTTP代理后面, 则应使用以下命令配置http.proxyHost, http.proxyPort, http.proxyUser 和http.proxyPassword.

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar -Dhttp.proxyHost=proxy.com -Dhttp.proxyPort=8080 -Dhttp.proxyUser=username -Dhttp.proxyPassword=password
```

### 多窗口模式

如果您使用的是Selenium 1.0, 则可能会跳过本节, 因为多窗口模式是默认行为. 但是, 在版本1.0之前, Selenium默认在子frame中运行测试中的应用程序, 如下所示.

某些应用程序无法在子框架中正常运行, 需要将其加载到窗口的顶部框架中. 多窗口模式选项允许AUT在单独的窗口中运行, 而不是在默认帧中运行, 然后在默认帧中可以拥有所需的顶部帧.

对于旧版本的Selenium, 您必须使用以下选项明确指定多窗口模式:

```bash
   -multiwindow 
```

从Selenium RC 1.0开始, 如果您想在一个框架内运行测试(即使用早期Selenium版本的标准), 则可以使用选项将此状态指定给Selenium服务器

```bash
   -singlewindow 
```

### 指定Firefox配置文件

除非您为每个实例分别指定一个配置文件, 否则Firefox将不会同时运行两个实例. Selenium RC 1.0和更高版本会自动在单独的配置文件中运行, 因此, 如果您使用的是Selenium 1.0, 则可以跳过本节. 但是, 如果您使用的是旧版本的Selenium, 或者需要使用特定的配置文件进行测试 (例如添加https证书或安装了一些插件), 则需要明确指定配置文件.

首先, 要创建一个单独的Firefox配置文件, 请遵循以下步骤. 打开Windows"开始"菜单, 选择"运行", 然后键入并输入以下内容之一:

```bash
   firefox.exe -profilemanager 
```

```bash
   firefox.exe -P 
```

使用对话框创建新的配置文件. 然后, 当您运行Selenium服务器时, 告诉它使用带有服务器命令行选项 *-firefoxProfileTemplate* 的 新Firefox配置文件, 并使用其文件名和目录路径指定配置文件的路径.

```bash
   -firefoxProfileTemplate "path to the profile" 
```

**注意**: 确保将您的个人资料放在默认文件夹之外的新文件夹中！！！！ 如果删除配置文件, 则Firefox配置文件管理器工具将删除文件夹中的所有文件, 无论它们是否是配置文件.

有关Firefox配置文件的更多信息, 请参见 [Mozilla的知识库](http://support.mozilla.com/en/kb/Managing+profiles)

### 使用-htmlSuite在服务器内直接运行Selenese

通过将html文件传递到服务器的命令行, 可以直接在Selenium 服务器中运行Selenese html文件. 例如:

```bash
   java -jar selenium-server-standalone-<version-number>.jar -htmlSuite "*firefox" 
   "http://www.google.com" "c:\absolute\path\to\my\HTMLSuite.html" 
   "c:\absolute\path\to\my\results.html"
```

这将自动启动您的HTML套件, 运行所有测试并保存带有结果的漂亮HTML报告.

*注意:* 使用此选项时, 服务器将启动测试并等待指定的秒数以完成测试； 否则, 服务器将停止测试. 如果在这段时间内未完成测试, 则该命令将以非零的退出代码退出, 并且不会生成任何结果文件.

此命令行很长, 因此在键入时要小心. 请注意, 这要求您传递HTML Selenese套件, 而不是单个测试. 另请注意-htmlSuite选项与 `-interactive`不兼容, 您不能同时运行两者e.

### Selenium 服务器日志

#### 服务端日志

启动Selenium服务器时, **-log** 选项可用于 将Selenium服务器报告的有价值的调试信息 记录到文本文件中.

```bash
   java -jar selenium-server-standalone-<version-number>.jar -log selenium.log
```

该日志文件比标准控制台日志更详细 (它包含DEBUG级别的日志消息). 日志文件还包括记录器名称和记录消息的线程的ID号. 例如:

```bash
   20:44:25 DEBUG [12] org.openqa.selenium.server.SeleniumDriverResourceHandler - 
   Browser 465828/:top frame1 posted START NEW
```

消息格式为

```bash
   TIMESTAMP(HH:mm:ss) LEVEL [THREAD] LOGGER - MESSAGE
```

此消息可能是多行.

#### 浏览器端日志

浏览器端的JavaScript(Selenium Core)也记录重要消息. 在许多情况下, 这些对于最终用户比常规的Selenium 服务器日志更有用. 要访问浏览器端日志, 请将 **-browserSideLog**参数传递给Selenium服务器.

```bash
   java -jar selenium-server-standalone-<version-number>.jar -browserSideLog
```

**-browserSideLog** 必须与 **-log** 参数结合使用, 以将browserSideLogs(以及所有其他DEBUG级别的日志记录消息)记录到文件中.

## 指定特定浏览器的路径

您可以为Selenium RC指定到特定浏览器的路径. 如果您使用同一浏览器的不同版本, 并且希望使用特定的浏览器, 这将很有用. 另外, 它用于允许您的测试在Selenium RC不直接支持的浏览器上运行. 在指定运行模式时, 请使用\*custom说明符, 后跟浏览器可执行文件的完整路径:

```bash
   *custom <path to browser> 
```

```bash
   cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\MyBrowser.exe&2=http://www.google.com
```

### 使用不同的浏览器配置运行测试

通常, Selenium RC自动配置浏览器, 但是如果您使用”\*custom"运行模式启动浏览器, 则可以强制Selenium RC照原样启动浏览器, 而无需使用自动配置.

例如, 您可以使用这样的自定义配置启动Firefox:

```bash
   cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\firefox.exe&2=http://www.google.com
```

请注意, 以这种方式启动浏览器时, 必须手动配置浏览器以将Selenium服务器用作代理. 通常, 这仅意味着打开浏览器首选项并将"localhost:4444"指定为HTTP代理, 但是不同浏览器的说明可能会有根本不同. 有关详细信息, 请查阅浏览器的文档.

请注意, Mozilla浏览器的启动和停止方式可能会有所不同. 可能需要设置MOZ\_NO\_REMOTE环境变量, 以使Mozilla浏览器的行为更加可预测. Unix用户应避免使用Shell脚本启动浏览器. 通常最好直接使用二进制可执行文件(例如firefox-bin).

## 解决常见问题

在开始使用Selenium RC时, 通常会遇到一些潜在的问题. 我们在这里介绍它们及其解决方案.

### 无法连接到服务器

当您的测试程序无法连接到Selenium 服务器时, Selenium会在您的测试程序中引发异常. 它应该显示此消息或类似的消息:

```bash
    "Unable to connect to remote server (Inner Exception Message: 
	No connection could be made because the target machine actively 
	refused it )"
    
	(using .NET and XP Service Pack 2) 
```

如果看到这样的消息, 请确保已启动Selenium服务器. 如果是这样, 则Selenium客户端库和Selenium服务器之间的连接存在问题.

从Selenium RC开始时, 大多数人开始是在同一台计算机上运行测试程序(带有Selenium客户端库) 和Selenium服务器. 为此, 请使用"localhost"作为连接参数. 我们建议您以这种方式开始, 因为它可以减少您入门时可能出现的网络问题的影响. 假设您的操作系统具有典型的网络和TCP/IP设置, 那么您应该没有什么困难. 实际上, 许多人选择以这种方式运行测试.

但是, 如果您确实想在远程计算机上运行Selenium服务器, 则假设两台计算机之间具有有效的TCP/IP连接, 则连接应该很好.

如果连接困难, 可以使用常用的网络工具, 例如*ping*, *telnet*, *ifconfig(Unix)/ipconfig* (Windows) 等, 以确保您具有有效的网络连接. 如果不熟悉这些, 则系统管理员可以为您提供帮助.

### 无法加载浏览器

好的, 这并非友好的错误消息, 很抱歉, 但是如果Selenium服务器无法加载浏览器, 您可能会看到此错误.

```bash
    (500) Internal Server Error
```

```bash
    Error:  java.lang.RuntimeException: Firefox refused shutdown while 
    preparing a profile 
```

以下是来自服务器的完整错误消息:

```bash
    16:20:03.919 INFO - Preparing Firefox profile... 
    16:20:27.822 WARN - GET /selenium-server/driver/?cmd=getNewBrowserSession&1=*fir 
    efox&2=http%3a%2f%2fsage-webapp1.qa.idc.com HTTP/1.1 
    java.lang.RuntimeException: Firefox refused shutdown while preparing a profile 
            at org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLaunc 
    her.waitForFullProfileToBeCreated(FirefoxCustomProfileLauncher.java:277) 
    ... 
    Caused by: org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLaunc 
    her$FileLockRemainedException: Lock file still present! C:\DOCUME~1\jsvec\LOCALS 
    ~1\Temp\customProfileDir203138\parent.lock 
```

要解决此问题, 请参阅"指定单独的Firefox配置文件"部分

### 版本问题

确保您的Selenium版本支持您的浏览器版本. 例如, Selenium RC 0.92不支持Firefox3. 有时您可能很幸运(例如我). 但不要忘记检查您使用的Selenium版本支持哪些浏览器版本. 如有疑问, 请使用最新版本的Selenium和浏览器使用最广泛的版本.

### 启动服务器时出现错误消息: “(不支持的major.minor版本49.0)”

此错误表明您使用的Java版本不正确. Selenium服务器需要Java 1.5或更高版本.

要检查您的Java版本, 请从命令行运行.

```bash
   java -version
```

您应该看到一条消息, 显示Java版本.

```bash
   java version "1.5.0_07"
   Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03)
   Java HotSpot(TM) Client VM (build 1.5.0_07-b03, mixed mode)
```

```bash
   cmd=getNewBrowserSession&1=*firefox /usr/local/firefox/firefox-bin&2=http://www.google.com
```

```bash
   /usr/lib/firefox-x.x.x/ 
```

其中x.x.x是您当前拥有的版本号. 因此, 要将该路径添加到用户的路径. 您将必须将以下内容添加到您的.bashrc文件中:

```bash
   export PATH="$PATH:/usr/lib/firefox-x.x.x/"
```

如有必要, 您可以在测试中直接指定firefox-bin的路径, 如下所示:

```bash
   "*firefox /usr/lib/firefox-x.x.x/firefox-bin"
```

### IE和样式属性

如果您在Internet Explorer上运行测试, 则无法使用其 `style` 属性来查找元素. 例如:

```bash
    //td[@style="background-color:yellow"]
```

这将在Firefox, Opera或Safari中完美运行, 但不适用于IE. IE将 `@style` 中的键解释为大写. 因此, 即使源代码是小写的, 您也应该使用:

```bash
    //td[@style="BACKGROUND-COLOR:yellow"]
```

如果您的测试打算在多个浏览器上运行, 那么这将是一个问题, 但是您可以轻松地对测试进行编码以检测情况 并尝试仅在IE中运行的替代定位器.

### 遇到错误-随着\*googlechrome浏览器的关闭, “无法将对象转换为原始值”

为避免此错误, 您必须使用禁用 同源策略检查的选项启动浏览器:

```bash
   selenium.start("commandLineFlags=--disable-web-security");
```

### IE中遇到的错误-“无法打开应用程序窗口；弹出窗口阻止程序已启用？”

为避免此错误, 您必须配置浏览器： 禁用弹出窗口阻止程序, 并取消选中工具»选项»安全中的"启用保护模式"选项.

***

1. 代理人是中间的第三人, 两人之间传球. 它充当将AUT传送到浏览器的"网络服务器". 作为代理, Selenium服务器可以"说谎"AUT的真实URL. [↩︎](#fnref:1)

2. 启动浏览器时使用的配置文件将localhost:4444设置为HTTP代理, 这就是为什么浏览器执行的任何HTTP请求都将通过Selenium服务器并且响应将通过它而不是真实服务器通过的原因. [↩︎](#fnref:2)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/bidi/w3c/network/
----

# Network

```java
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L36-L38)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    assert.notEqual(intercept, null)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L29)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L46-L50)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L34-L35)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                    responseDetails ->
                            network.continueWithAuth(
                                    responseDetails.getRequest().getRequestId(),
                                    new UsernameAndPassword("admin", "admin")));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L57-L64)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L42-L46)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                            // Does not handle the alert
                            network.continueWithAuthNoCredentials(responseDetails.getRequest().getRequestId()));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L74-L80)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L56-L60)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
                            network.cancelAuth(responseDetails.getRequest().getRequestId()));
            driver.get("https://the-internet.herokuapp.com/basic_auth");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L90-L96)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_commands.spec.js#L71-L75)

##### /examples/javascript/test/bidirectional/network\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const { Network } = require('selenium-webdriver/bidi/network')
const {until, By, Builder} = require('selenium-webdriver')
const {AddInterceptParameters} = require("selenium-webdriver/bidi/addInterceptParameters");
const {InterceptPhase} = require("selenium-webdriver/bidi/interceptPhase");

describe('Network commands', function () {
  let driver
  let network


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()

    network = await Network(driver)
  })

  afterEach(async function () {
    await network.close()
    await driver.quit()
  })

  it('can add intercept', async function () {
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)
  })

  it('can remove intercept', async function () {
    const network = await Network(driver)
    const intercept = await network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT))
    assert.notEqual(intercept, null)

    await network.removeIntercept(intercept)
  })

  it('can continue with auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuth(event.request.request, 'admin','admin')
    })
    await driver.get('https://the-internet.herokuapp.com/basic_auth')

    const successMessage = 'Congratulations! You must have the proper credentials.'

    let elementMessage = await driver.findElement(By.tagName('p')).getText()
    assert.equal(elementMessage, successMessage)
  })

  it('can continue without auth credentials ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.continueWithAuthNoCredentials(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    const alert = await driver.wait(until.alertIsPresent())
    await alert.dismiss()

    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })

  it('can cancel auth ', async function () {
    await network.addIntercept(new AddInterceptParameters(InterceptPhase.AUTH_REQUIRED))

    await network.authRequired(async (event) => {
      await network.cancelAuth(event.request.request)
    })

    await driver.get('https://the-internet.herokuapp.com/basic_auth')
    let source = await driver.getPageSource()
    assert.equal(source.includes('Not authorized'), true)
  })
})
```

```java
            }
    }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkCommandsTest.java#L104-L108)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkCommandsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.time.Duration;
import java.time.temporal.ChronoUnit;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.TimeoutException;
import org.openqa.selenium.UsernameAndPassword;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.AddInterceptParameters;
import org.openqa.selenium.bidi.network.InterceptPhase;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

class NetworkCommandsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    void canAddIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
        }
    }

    @Test
    void canRemoveIntercept() {
        try (Network network = new Network(driver)) {
            String intercept =
                    network.addIntercept(new AddInterceptParameters(InterceptPhase.BEFORE_REQUEST_SENT));
            Assertions.assertNotNull(intercept);
            network.removeIntercept(intercept);
        }
    }

    @Test
    void canContinueWithAuthCredentials() {
        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");
            String successMessage = "Congratulations! You must have the proper credentials.";
            WebElement elementMessage = driver.findElement(By.tagName("p"));
            Assertions.assertEquals(successMessage, elementMessage.getText());
        }
    }

    @Test
    void canContinueWithoutAuthCredentials() {
        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");
            Alert alert = wait.until(ExpectedConditions.alertIsPresent());
            alert.dismiss();
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canCancelAuth() {
        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");
            Assertions.assertTrue(driver.getPageSource().contains("Not authorized"));
        }
    }

    @Test
    void canFailRequest() {
        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));
            Assertions.assertThrows(TimeoutException.class, () -> driver.get("https://the-internet.herokuapp.com/basic_auth"));
            }
    }
}
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L30-L35)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L23-L29)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L45-L51)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L82-L88)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L62-L68)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/network_events.spec.js#L96-L102)

##### /examples/javascript/test/bidirectional/network\_events.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const { Network } = require("selenium-webdriver/bidi/network");
const {until, Builder} = require("selenium-webdriver");


describe('Network events', function () {
  let driver


  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to event before request is sent', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')

    const currentUrl = await driver.getCurrentUrl()
    const currentUrlFound = beforeRequestEvent.some(event => event.request.url.includes(currentUrl))
    assert(currentUrlFound, `${currentUrl} was not requested`)
  })

  it('can request cookies', async function () {
    const network = await Network(driver)
    let beforeRequestEvent = null
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent = event
    })

    await driver.get('https://www.selenium.dev/selenium/web/blank.html')
    await driver.manage().addCookie({
      name: 'north',
      value: 'biryani',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.method, 'GET')
    assert.equal(beforeRequestEvent.request.cookies[0].name, 'north')
    assert.equal(beforeRequestEvent.request.cookies[0].value.value, 'biryani')

    await driver.manage().addCookie({
      name: 'south',
      value: 'dosa',
    })
    await driver.navigate().refresh()

    assert.equal(beforeRequestEvent.request.cookies[1].name, 'south')
    assert.equal(beforeRequestEvent.request.cookies[1].value.value, 'dosa')
  })

  it('can redirect http equiv', async function () {
    let beforeRequestEvent = []
    const network = await Network(driver)
    await network.beforeRequestSent(function (event) {
      beforeRequestEvent.push(event)
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/redirected_http_equiv.html')
    await driver.wait(until.urlContains('redirected.html'), 1000)

    assert.equal(beforeRequestEvent[0].request.method, 'GET')
    let redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected.html'))
    assert(redirectedFound, 'redirected.html was not requested')
    redirectedFound = beforeRequestEvent.some(event => event.request.url.includes('redirected_http_equiv.html'))
    assert(redirectedFound, 'redirected_http_equiv.html was not requested')
  })

  it('can subscribe to response started', async function () {
    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')

    assert.equal(onResponseStarted[0].request.method, 'GET')
    assert.equal(onResponseStarted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseStarted[0].response.url, await driver.getCurrentUrl())
  })

  it('can subscribe to response completed', async function () {
    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')

    assert.equal(onResponseCompleted[0].request.method, 'GET')
    assert.equal(onResponseCompleted[0].request.url, await driver.getCurrentUrl())
    assert.equal(onResponseCompleted[0].response.fromCache, false)
    assert.equal(onResponseCompleted[0].response.status, 200)
  })
})
```

```java
        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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/NetworkEventsTest.java#L101-L106)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/NetworkEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.bidi.module.Network;
import org.openqa.selenium.bidi.network.BeforeRequestSent;
import org.openqa.selenium.bidi.network.ResponseDetails;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class NetworkEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canListenToBeforeRequestSentEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());
        }
    }

    @Test
    void canListenToResponseStartedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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();

            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(200L, response.getResponseData().getStatus());
        }
    }

    @Test
    void canListenToResponseCompletedEventWithCookie()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (Network network = new Network(driver)) {
            CompletableFuture<BeforeRequestSent> future = new CompletableFuture<>();

            driver.get("https://www.selenium.dev/selenium/web/blankPage");
            driver.manage().addCookie(new Cookie("foo", "bar"));
            network.onBeforeRequestSent(future::complete);
            driver.navigate().refresh();

            BeforeRequestSent requestSent = future.get(5, TimeUnit.SECONDS);
            String windowHandle = driver.getWindowHandle();

            Assertions.assertEquals(windowHandle, requestSent.getBrowsingContextId());
            Assertions.assertEquals("get", requestSent.getRequest().getMethod().toLowerCase());

            Assertions.assertEquals("foo", requestSent.getRequest().getCookies().get(0).getName());
            Assertions.assertEquals("bar", requestSent.getRequest().getCookies().get(0).getValue().getValue());
        }
    }

    @Test
    void canListenToOnAuthRequiredEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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);
            String windowHandle = driver.getWindowHandle();
            Assertions.assertEquals(windowHandle, response.getBrowsingContextId());
            Assertions.assertEquals("get", response.getRequest().getMethod().toLowerCase());
            Assertions.assertEquals(401L, response.getResponseData().getStatus());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

Última modificação May 27, 2025: [Update dependency selenium-webdriver to v4.33.0 (#2316) (5f5285aba17)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/5f5285aba177977a839ac8377929dc999623a4bb)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/bidi/cdp/
----

# Chrome DevTools 协议

使用 Selenium 操作 Chrome DevTools 协议的示例。 CDP 的支持是临时的，直到 WebDriver BiDi 实现为止。

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/CdpTest.java#L22-L27)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/CdpTest.java

```java
package dev.selenium.bidi.cdp;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chromium.HasCdp;

import java.util.HashMap;
import java.util.Map;

public class CdpTest extends BaseTest {
  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
  }

  @Test
  public void setCookie() {
    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);

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }
}
```

```py
    cookie = {'name': 'cheese',
              'value': 'gouda',
              'domain': 'www.selenium.dev',
              'secure': True}

    driver.execute_cdp_cmd('Network.setCookie', cookie)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_cdp.py#L2-L7)

##### /examples/python/tests/bidi/cdp/test\_cdp.py

```py
def test_set_cookie(driver):
    cookie = {'name': 'cheese',
              'value': 'gouda',
              'domain': 'www.selenium.dev',
              'secure': True}

    driver.execute_cdp_cmd('Network.setCookie', cookie)

    driver.get('https://www.selenium.dev')
    cheese = driver.get_cookie(cookie['name'])

    assert cheese['value'] == 'gouda'
```

```cs
            var cookie = new Dictionary<string, object>
            {
                { "name", "cheese" },
                { "value", "gouda" },
                { "domain", "www.selenium.dev" },
                { "secure", true }
            };
            ((ChromeDriver)driver).ExecuteCdpCommand("Network.setCookie", cookie);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/CDPTest.cs#L14-L21)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/CDPTest.cs

```cs
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class CDPTest : BaseChromeTest
    {
        [TestMethod]
        public void SetCookie()
        {
            var cookie = new Dictionary<string, object>
            {
                { "name", "cheese" },
                { "value", "gouda" },
                { "domain", "www.selenium.dev" },
                { "secure", true }
            };
            ((ChromeDriver)driver).ExecuteCdpCommand("Network.setCookie", cookie);
            
            driver.Url = "https://www.selenium.dev";
            Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);

        }
    }
}
```

```rb
    driver.execute_cdp('Network.setCookie',
                       name: 'cheese',
                       value: 'gouda',
                       domain: 'www.selenium.dev',
                       secure: true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/cdp_spec.rb#L9-L13)

##### /examples/ruby/spec/bidi/cdp/cdp\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'sets cookie' do
    driver.execute_cdp('Network.setCookie',
                       name: 'cheese',
                       value: 'gouda',
                       domain: 'www.selenium.dev',
                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end
end
```

***

##### [Chrome DevTools Logging Features](/zh-cn/documentation/webdriver/bidi/cdp/logging/)

Logging features using CDP.

##### [Chrome DevTools Network Features](/zh-cn/documentation/webdriver/bidi/cdp/network/)

Network features using CDP.

##### [Chrome DevTools Script Features](/zh-cn/documentation/webdriver/bidi/cdp/script/)

Script features using CDP.

最后修改 September 19, 2024: [Update \_index.zh-cn.md (#1942) (97537ea1f59)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/97537ea1f59f112d0e5a8c2fd66cb39345116ca3)

----
url: https://www.selenium.dev/ja/documentation/test_practices/encouraged/avoid_sharing_state/
----

# 状態を共有しない

いくつかの場所で言及されていますが、再度言及する価値があります。 テストが互いに分離されていることを確認してください。

* テストデータを共有しないでください。 アクションを実行する1つを選択する前に、それぞれが有効な注文をデータベースに照会するいくつかのテストを想像してください。 2つのテストで同じ順序を選択すると、予期しない動作が発生する可能性があります。

* 別のテストで取得される可能性のあるアプリケーション内の古いデータを削除します。 例: 無効な注文レコード

* テストごとに新しいWebDriverインスタンスを作成します。 これにより、テストの分離が保証され、並列化がより簡単になります。

  * If you choose [pytest](https://pytest.org/) as your test runner, this can be easily done by yielding your driver in a global fixture. This way each test gets its own driver instance, and you can ensure that drivers always quit after a test is finished (pass or fail).

最終更新 September 23, 2024: [Added more detail to Avoid Sharing State Documentation (#1948)\[deploy site\] (e1fa2da1696)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e1fa2da1696971bd7e22f613dce09a8934fd56ff)

----
url: https://www.selenium.dev/ja/documentation/grid/components/
----

# Selenium Grid のコンポーネント

最終更新 April 30, 2025: [fix: correct typo in title of Japanese documentation for Selenium Grid components (#2287) (477248d401d)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/477248d401d51a426ef66bc89cc29bdd04586869)

----
url: https://www.selenium.dev/documentation/legacy/selenium_ide/
----

# Legacy Selenium IDE

```html
<tr>
    <td>Command</td>
    <td>target (locator)</td>
    <td>Value</td>
</tr>
```

|            |              |       |
| ---------- | ------------ | ----- |
| verifyText | //div//a\[2] | Login |

The parameters are not always required; it depends on the command. In some cases both are required, in others one parameter is required, and in still others the command may take no parameters at all. Here are a couple more examples:

|                   |             |                         |
| ----------------- | ----------- | ----------------------- |
| goBackAndWait     |             |                         |
| verifyTextPresent |             | Welcome to My Home Page |
| type              | id=phone    | (555) 666-7066          |
| type              | id=address1 | ${myVariableAddress}    |

```html
<table>
    <tr><td>open</td><td>/download/</td><td></td></tr>
    <tr><td>assertTitle</td><td></td><td>Downloads</td></tr>
    <tr><td>verifyText</td><td>//h2</td><td>Downloads</td></tr>
</table>
```

Rendered as a table in a browser this would look like the following:

|             |            |           |
| ----------- | ---------- | --------- |
| open        | /download/ |           |
| assertTitle |            | Downloads |
| verifyText  | //h2       | Downloads |

The Selenese HTML syntax can be used to write and run tests without requiring knowledge of a programming language. With a basic knowledge of selenese and Selenium-IDE you can quickly produce and run testcases.

## Test Suites

A test suite is a collection of tests. Often one will run all the tests in a test suite as one continuous batch-job.

When using Selenium-IDE, test suites also can be defined using a simple HTML file. The syntax again is simple. An HTML table defines a list of tests where each row defines the filesystem path to each test. An example tells it all.

```html
<html>
<head>
<title>Test Suite Function Tests - Priority 1</title>
</head>
<body>
<table>
  <tr><td><b>Suite Of Tests</b></td></tr>
  <tr><td><a href="./Login.html">Login</a></td></tr>
  <tr><td><a href="./SearchValues.html">Test Searching for Values</a></td></tr>
  <tr><td><a href="./SaveValues.html">Test Save</a></td></tr>
</table>
</body>
</html>
```

| Command     | Target     | Value        |
| ----------- | ---------- | ------------ |
| open        | /download/ |              |
| assertTitle |            | Downloads    |
| verifyText  | //h2       | Downloads    |
| assertTable | 1.2.1      | Selenium IDE |
| verifyTable | 1.2.2      | June 3, 2008 |
| verifyTable | 1.2.3      | 1.0 beta 2   |

The above example first opens a page and then “asserts” that the correct page is loaded by comparing the title with the expected value. Only if this passes will the following command run and “verify” that the text is present in the expected location. The test case then “asserts” the first column in the second row of the first table contains the expected value, and only if this passed will the remaining cells in that row be “verified”.

### **verifyTextPresent**

The command `verifyTextPresent` is used to verify specific text exists somewhere on the page. It takes a single argument–the text pattern to be verified. For example:

| Command           | Target             | Value |
| ----------------- | ------------------ | ----- |
| verifyTextPresent | Marketing Analysis |       |

This would cause Selenium to search for, and verify, that the text string “Marketing Analysis” appears somewhere on the page currently being tested. Use verifyTextPresent when you are interested in only the text itself being present on the page. Do not use this when you also need to test where the text occurs on the page.

### **verifyElementPresent**

Use this command when you must test for the presence of a specific UI element, rather than its content. This verification does not check the text, only the HTML tag. One common use is to check for the presence of an image.

| Command              | Target      | Value |
| -------------------- | ----------- | ----- |
| verifyElementPresent | //div/p/img |       |

This command verifies that an image, specified by the existence of an HTML tag, is present on the page, and that it follows a

tag and a

tag. The first (and only) parameter is a locator for telling the Selenese command how to find the element. Locators are explained in the next section.

`verifyElementPresent` can be used to check the existence of any HTML tag within the page. You can check the existence of links, paragraphs, divisions

, etc. Here are a few more examples.

| Command              | Target                        | Value |
| -------------------- | ----------------------------- | ----- |
| verifyElementPresent | //div/p                       |       |
| verifyElementPresent | //div/a                       |       |
| verifyElementPresent | id=Login                      |       |
| verifyElementPresent | link=Go to Marketing Research |       |
| verifyElementPresent | //a\[2]                       |       |
| verifyElementPresent | //head/title                  |       |

These examples illustrate the variety of ways a UI element may be tested. Again, locators are explained in the next section.

### **verifyText**

Use `verifyText` when both the text and its UI element must be tested. verifyText must use a locator. If you choose an *XPath* or *DOM* locator, you can verify that specific text appears at a specific location on the page relative to other UI components on the page.

| Command    | Target              | Value                                                               |
| ---------- | ------------------- | ------------------------------------------------------------------- |
| verifyText | //table/tr/td/div/p | This is my text and it occurs right after the div inside the table. |

## Locating Elements

For many Selenium commands, a target is required. This target identifies an element in the content of the web application, and consists of the location strategy followed by the location in the format `locatorType=location`. The locator type can be omitted in many cases. The various locator types are explained below with examples for each.

### Locating by Identifier

This is probably the most common method of locating elements and is the catch-all default when no recognized locator type is used. With this strategy, the first element with the id attribute value matching the location will be used. If no element has a matching id attribute, then the first element with a name attribute matching the location will be used.

For instance, your page source could have id and name attributes as follows:

```html
  <html>
   <body>
    <form id="loginForm">
     <input name="username" type="text" />
     <input name="password" type="password" />
     <input name="continue" type="submit" value="Login" />
    </form>
   </body>
  <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
    </body>
   <html>
```

* `id=loginForm` (3)

### Locating by Name

The name locator type will locate the first element with a matching name attribute. If multiple elements have the same value for a name attribute, then you can use filters to further refine your location strategy. The default filter type is value (matching the value attribute).

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
  <html>
   <body>
    <p>Are you sure you want to do this?</p>
    <a href="continue.html">Continue</a> 
    <a href="cancel.html">Cancel</a>
  </body>
  <html>
```

* `link=Continue` (4)
* `link=Cancel` (5)

### Locating by DOM

The Document Object Model represents an HTML document and can be accessed using JavaScript. This location strategy takes JavaScript that evaluates to an element on the page, which can be simply the element’s location using the hierarchical dotted notation.

Since only `dom` locators start with “document”, it is not necessary to include the `dom=` label when specifying a DOM locator.

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input class="required" name="username" type="text" />
      <input class="required passfield" name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | glob:\*Film\*Television\*             |       |

The actual title of the page reached by clicking on the link was “De Anza Film And Television Department - Menu”. By using a pattern rather than the exact text, the `verifyTitle` will pass as long as the two words “Film” and “Television” appear (in that order) anywhere in the page’s title. For example, if the page’s owner should shorten the title to just “Film & Television Department,” the test would still pass. Using a pattern for both a link and a simple test that the link worked (such as the `verifyTitle` above does) can greatly reduce the maintenance for such test cases.

#### Regular Expression Patterns

*Regular expression* patterns are the most powerful of the three types of patterns that Selenese supports. Regular expressions are also supported by most high-level programming languages, many text editors, and a host of tools, including the Linux/Unix command-line utilities **grep**, **sed**, and **awk**. In Selenese, regular expression patterns allow a user to perform many tasks that would be very difficult otherwise. For example, suppose your test needed to ensure that a particular table cell contained nothing but a number. `regexp: [0-9]+` is a simple pattern that will match a decimal number of any length.

Whereas Selenese globbing patterns support only the **\*** and **\[ ]** (character class) features, Selenese regular expression patterns offer the same wide array of special characters that exist in JavaScript. Below are a subset of those special characters:

| PATTERN | MATCH                                                                            |
| ------- | -------------------------------------------------------------------------------- |
| .       | any single character                                                             |
| \[ ]    | character class: any single character that appears inside the brackets           |
| \*      | quantifier: 0 or more of the preceding character (or group)                      |
| +       | quantifier: 1 or more of the preceding character (or group)                      |
| ?       | quantifier: 0 or 1 of the preceding character (or group)                         |
| {1,5}   | quantifier: 1 through 5 of the preceding character (or group)                    |
| \|      | alternation: the character/group on the left or the character/group on the right |
| ( )     | grouping: often used with alternation and/or quantifier                          |

Regular expression patterns in Selenese need to be prefixed with either `regexp:` or `regexpi:`. The former is case-sensitive; the latter is case-insensitive.

A few examples will help clarify how regular expression patterns can be used with Selenese commands. The first one uses what is probably the most commonly used regular expression pattern–**.\*** (“dot star”). This two-character sequence can be translated as “0 or more occurrences of any character” or more simply, “anything or nothing.” It is the equivalent of the one-character globbing pattern **\*** (a single asterisk).

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | regexp:.\*Film.\*Television.\*        |       |

The example above is functionally equivalent to the earlier example that used globbing patterns for this same test. The only differences are the prefix (**regexp:** instead of **glob:**) and the “anything or nothing” pattern (**.\*** instead of just **\***).

The more complex example below tests that the Yahoo! Weather page for Anchorage, Alaska contains info on the sunrise time:

| Command           | Target                                            | Value |
| ----------------- | ------------------------------------------------- | ----- |
| open              | <http://weather.yahoo.com/forecast/USAK0012.html> |       |
| verifyTextPresent | regexp:Sunrise: \*\[0-9]{1,2}:\[0-9]{2} \[ap]m    |       |

Let’s examine the regular expression above one part at a time:

|              |                                                      |
| ------------ | ---------------------------------------------------- |
| `Sunrise: *` | The string **Sunrise:** followed by 0 or more spaces |
| `[0-9]{1,2}` | 1 or 2 digits (for the hour of the day)              |
| `:`          | The character **:** (no special characters involved) |
| `[0-9]{2}`   | 2 digits (for the minutes) followed by a space       |
| `[ap]m`      | “a” or “p” followed by “m” (am or pm)                |

#### Exact Patterns

The **exact** type of Selenium pattern is of marginal usefulness. It uses no special characters at all. So, if you needed to look for an actual asterisk character (which is special for both globbing and regular expression patterns), the **exact** pattern would be one way to do that. For example, if you wanted to select an item labeled “Real \*” from a dropdown, the following code might work or it might not. The asterisk in the `glob:Real *` pattern will match anything or nothing. So, if there was an earlier select option labeled “Real Numbers,” it would be the option selected rather than the “Real \*” option.

| Command | Target   | Value        |
| ------- | -------- | ------------ |
| select  | //select | glob:Real \* |

In order to ensure that the “Real \*” item would be selected, the `exact:` prefix could be used to create an **exact** pattern as shown below:

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| select  | //select | exact:Real \* |

But the same effect could be achieved via escaping the asterisk in a regular expression pattern:

| Command | Target   | Value            |
| ------- | -------- | ---------------- |
| select  | //select | regexp:Real \\\* |

| Command | Target            | Value |
| ------- | ----------------- | ----- |
| store   | <paul@mysite.org> |       |

Later in your script, you’ll want to use the stored value of your variable. To access the value of a variable, enclose the variable in curly brackets ({}) and precede it with a dollar sign like this.

| Command    | Target  | Value         |
| ---------- | ------- | ------------- |
| verifyText | //div/p | \\${userName} |

A common use of variables is for storing input for an input field.

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| type    | id=login | \\${userName} |

| Command         | Target                                         | Value       |
| --------------- | ---------------------------------------------- | ----------- |
| store           | 10                                             | hits        |
| storeXpathCount | //blockquote                                   | blockquotes |
| storeEval       | storedVars\[‘hits’].storedVars\[‘blockquotes’] | paragraphs  |

This next example illustrates how a JavaScript snippet can include calls to methods, in this case the JavaScript String object’s `toUpperCase` method and `toLowerCase` method.

| Command   | Target                            | Value |
| --------- | --------------------------------- | ----- |
| store     | Edith Wharton                     | name  |
| storeEval | storedVars\[’name’].toUpperCase() | uc    |
| storeEval | storedVars\[’name’].toUpperCase() | lc    |

#### JavaScript Usage with Non-Script Parameters

JavaScript can also be used to help generate values for parameters, even when the parameter is not specified to be of type **script**.\
However, in this case, special syntax is required–the *entire* parameter value must be prefixed by `javascript{` with a trailing `}`, which encloses the JavaScript snippet, as in `javascript{*yourCodeHere*}`. Below is an example in which the `type` command’s second parameter `value` is generated via JavaScript code using this special syntax:

| Command | Target            | Value                                                 |
| ------- | ----------------- | ----------------------------------------------------- |
| store   | league of nations | searchString                                          |
| type    | q                 | javascript{storedVars\[‘searchString’].toUpperCase()} |

## *echo* - The Selenese Print Command

Selenese has a simple command that allows you to print text to your test’s output. This is useful for providing informational progress notes in your test which display on the console as your test is running. These notes also can be used to provide context within your test result reports, which can be useful for finding where a defect exists on a page in the event your test finds a problem. Finally, echo statements can be used to print the contents of Selenium variables.

| Command | Target                    | Value |
| ------- | ------------------------- | ----- |
| echo    | Testing page footer now.  |       |
| echo    | Username is \\${userName} |       |

## Alerts, Popups, and Multiple Windows

Suppose that you are testing a page that looks like this.

```html
  <!DOCTYPE HTML>
  <html>
  <head>
    <script type="text/javascript">
      function output(resultText){
        document.getElementById('output').childNodes[0].nodeValue=resultText;
      }

      function show_confirm(){
        var confirmation=confirm("Chose an option.");
        if (confirmation==true){
          output("Confirmed.");
        }
        else{
          output("Rejected!");
        }
      }
      
      function show_alert(){
        alert("I'm blocking!");
        output("Alert is gone.");
      }
      function show_prompt(){
        var response = prompt("What's the best web QA tool?","Selenium");
        output(response);
      }
      function open_window(windowName){
        window.open("newWindow.html",windowName);
      }
      </script>
  </head>
  <body>

    <input type="button" id="btnConfirm" onclick="show_confirm()" value="Show confirm box" />
    <input type="button" id="btnAlert" onclick="show_alert()" value="Show alert" />
    <input type="button" id="btnPrompt" onclick="show_prompt()" value="Show prompt" />
    <a href="newWindow.html" id="lnkNewWindow" target="_blank">New Window Link</a>
    <input type="button" id="btnNewNamelessWindow" onclick="open_window()" value="Open Nameless Window" />
    <input type="button" id="btnNewNamedWindow" onclick="open_window('Mike')" value="Open Named Window" />

    <br />
    <span id="output">
    </span>
  </body>
  </html>
```

The user must respond to alert/confirm boxes, as well as moving focus to newly opened popup windows. Fortunately, Selenium can cover JavaScript pop-ups.

But before we begin covering alerts/confirms/prompts in individual detail, it is helpful to understand the commonality between them. Alerts, confirmation boxes and prompts all have variations of the following

| Command                   | Description                                                           |
| ------------------------- | --------------------------------------------------------------------- |
| assertFoo(pattern)        | throws error if pattern doesn’t match the text of the pop-up          |
| assertFooPresent          | throws error if pop-up is not available                               |
| assertFooNotPresent       | throws error if any pop-up is present                                 |
| storeFoo(variable)        | stores the text of the pop-up in a variable                           |
| storeFooPresent(variable) | stores the text of the pop-up in a variable and returns true or false |

When running under Selenium, JavaScript pop-ups will not appear. This is because the function calls are actually being overridden at runtime by Selenium’s own JavaScript. However, just because you cannot see the pop-up doesn’t mean you don’t have to deal with it. To handle a pop-up, you must call its `assertFoo(pattern)` function. If you fail to assert the presence of a pop-up your next command will be blocked and you will get an error similar to the following `[error] Error: There was an unexpected Confirmation! [Chose an option.]`

### Alerts

Let’s start with alerts because they are the simplest pop-up to handle. To begin, open the HTML sample above in a browser and click on the “Show alert” button. You’ll notice that after you close the alert the text “Alert is gone.” is displayed on the page. Now run through the same steps with Selenium IDE recording, and verify the text is added after you close the alert. Your test will look something like this:

| Command           | Target         | Value |
| ----------------- | -------------- | ----- |
| open              | /              |       |
| click             | btnAlert       |       |
| assertAlert       | I’m blocking!  |       |
| verifyTextPresent | Alert is gone. |       |

You may be thinking “That’s odd, I never tried to assert that alert.” But this is Selenium-IDE handling and closing the alert for you. If you remove that step and replay the test you will get the following error `[error] Error: There was an unexpected Alert! [I'm blocking!]`. You must include an assertion of the alert to acknowledge its presence.

If you just want to assert that an alert is present but either don’t know or don’t care what text it contains, you can use `assertAlertPresent`. This will return true or false, with false halting the test.

### Confirmations

Confirmations behave in much the same way as alerts, with `assertConfirmation` and `assertConfirmationPresent` offering the same characteristics as their alert counterparts. However, by default Selenium will select OK when a confirmation pops up. Try recording clicking on the “Show confirm box” button in the sample page, but click on the “Cancel” button in the popup, then assert the output text. Your test may look something like this:

| Command                        | Target            | Value |
| ------------------------------ | ----------------- | ----- |
| open                           | /                 |       |
| click                          | btnConfirm        |       |
| chooseCancelOnNextConfirmation |                   |       |
| assertConfirmation             | Choose an option. |       |
| verifyTextPresent              | Rejected          |       |

The `chooseCancelOnNextConfirmation` function tells Selenium that all following confirmation should return false. It can be reset by calling chooseOkOnNextConfirmation.

You may notice that you cannot replay this test, because Selenium complains that there is an unhandled confirmation. This is because the order of events Selenium-IDE records causes the click and chooseCancelOnNextConfirmation to be put in the wrong order (it makes sense if you think about it, Selenium can’t know that you’re cancelling before you open a confirmation) Simply switch these two commands and your test will run fine.

### Prompts

Prompts behave in much the same way as alerts, with `assertPrompt` and `assertPromptPresent` offering the same characteristics as their alert counterparts. By default, Selenium will wait for you to input data when the prompt pops up. Try recording clicking on the “Show prompt” button in the sample page and enter “Selenium” into the prompt. Your test may look something like this:

| Command            | Target                       | Value |
| ------------------ | ---------------------------- | ----- |
| open               | /                            |       |
| answerOnNextPrompt | Selenium!                    |       |
| click              | id=btnPrompt                 |       |
| assertPrompt       | What’s the best web QA tool? |       |
| verifyTextPresent  | Selenium!                    |       |

```html
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Sample Selenium Test Suite</title>
    </head>
    <body>
        <table cellpadding="1" cellspacing="1" border="1">
            <thead>
                <tr><td>Test Cases for De Anza A-Z Directory Links</td></tr>
            </thead>
        <tbody>
            <tr><td><a href="./a.html">A Links</a></td></tr>
            <tr><td><a href="./b.html">B Links</a></td></tr>
            <tr><td><a href="./c.html">C Links</a></td></tr>
            <tr><td><a href="./d.html">D Links</a></td></tr>
        </tbody>
        </table>
    </body>
</html>
```

***

*error loading test case: no command found*

You’ve used **File=>Open** to try to open a test suite file. Use **File=>Open Test Suite** instead.

An enhancement request has been raised to improve this error message. See [issue 1010](http://code.google.com/p/selenium/issues/detail?id=1010).

***

This type of **error** may indicate a timing problem, i.e., the element specified by a locator in your command wasn’t fully loaded when the command was executed. Try putting a **pause 5000** before the command to determine whether the problem is indeed related to timing. If so, investigate using an appropriate **waitFor\*** or **\*AndWait** command before the failing command.

***

Whenever your attempt to use variable substitution fails as is the case for the **open** command above, it indicates that you haven’t actually created the variable whose value you’re trying to access. This is sometimes due to putting the variable in the **Value** field when it should be in the **Target** field or vice versa. In the example above, the two parameters for the **store** command have been erroneously placed in the reverse order of what is required. For any Selenese command, the first required parameter must go in the **Target** field, and the second required parameter (if one exists) must go in the **Value** field.

***

*error loading test case: \[Exception… “Component returned failure code: 0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND) \[nsIFileInputStream.init]” nresult: “0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND)” location: “JS frame :: chrome://selenium-ide/content/file-utils.js :: anonymous :: line 48” data: no]*

One of the test cases in your test suite cannot be found. Make sure that the test case is indeed located where the test suite indicates it is located. Also, make sure that your actual test case files have the .html extension both in their filenames, and in the test suite file where they are referenced.

An enhancement request has been raised to improve this error message. See [issue 1011](http://code.google.com/p/selenium/issues/detail?id=1011).

***

Your extension file’s contents have not been read by Selenium-IDE. Be sure you have specified the proper pathname to the extensions file via **Options=>Options=>General** in the **Selenium Core extensions** field. Also, Selenium-IDE must be restarted after any change to either an extensions file *or* to the contents of the **Selenium Core extensions** field.

***

##### [HTML runner](/documentation/legacy/selenium_ide/html_runner/)

Execute HTML Selenium IDE exports from command line

##### [Legacy Selenium IDE Release Notes](/documentation/legacy/selenium_ide/releases/)

Selenium IDE was the original Firefox extension for Record and Playback. Version 2.x was updated to support WebDriver.

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/actions_api/keyboard/
----

# 键盘操作

```java
        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L17-L20)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L10-L13)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L13-L16)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L17-L20)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L19-L22)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L30-L35)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L21-L26)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L30-L35)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L25-L30)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L32-L37)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L32-L37)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .sendKeys("abc")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L45-L47)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L34-L36)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs

            new Actions(driver)
                .SendKeys("abc")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L45-L47)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .send_keys('abc')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L39-L41)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .sendKeys('abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L48-L50)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .sendKeys("abc")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L47-L49)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L59-L62)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L45-L48)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L58-L61)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L51-L54)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L59-L63)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L60-L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L70-L84)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L56-L67)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L72-L82)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L64-L74)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L73-L85)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L74-L86)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

----
url: https://www.selenium.dev/zh-cn/_print/documentation/test_practices/encouraged/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/test_practices/encouraged/).

# 指南和建议

Selenium项目的一些测试指南和建议.

* 1: [PO设计模式](#pg-a07d818fdd319e2c92a8acc85ef8a3e8)
* 2: [领域特定语言](#pg-eff46b072335747496ab495afaa216a4)
* 3: [生成应用程序状态](#pg-7c284c8ef2a809f491abaacf4bc8174e)
* 4: [模拟外部服务](#pg-17499bca0a70e7307770deb1aeed0396)
* 5: [改善报告](#pg-7ac05e3d898ebefa61aea590b371bb90)
* 6: [避免共享状态](#pg-771c393afbab1342a428f0976ae22ab2)
* 7: [使用定位器的提示](#pg-fa48c36df684f7be6ce81e5e93388b9e)
* 8: [测试的独立性](#pg-dfe07108b6d0f913b964fe6e4338d5ba)
* 9: [考虑使用Fluent API](#pg-40d1fd2b426846ea61f9362119eb7b4b)
* 10: [每次测试都刷新浏览器](#pg-3ce2b89debe65906eae5f1da85962607)

关于"最佳实践"的注解：我们有意在本文档中避免使用"最佳实践"的说辞. 没有一种方法可以适用于所有情况. 我们更喜欢"指南和建议"的想法. 我们鼓励您通读这些内容, 并仔细地确定哪种方法适用于您的特定环境.

由于许多原因, 功能测试很难正确完成. 即便应用程序的状态, 复杂性, 依赖还不够让测试变得 足够复杂, 操作浏览器（特别是跨浏览器的兼容性测试）就已经使得写一个好的测试变成一种挑战.

Selenium提供了一些工具使得功能测试用户更简单的操作浏览器, 但是这些工具并不能帮助你来写一个好的 架构的测试套件. 这章我们会针对怎么来做web页面的功能测试的自动化给出一些忠告, 指南和建议.

这章记录了很多历年来成功的使用Selenium的用户的常用的软件设计模式.

# 1 - PO设计模式

```java
/***
 * Tests login feature
 */
public class Login {

  public void testLogin() {
    // fill login data on sign-in page
    driver.findElement(By.name("user_name")).sendKeys("userName");
    driver.findElement(By.name("password")).sendKeys("my supersecret password");
    driver.findElement(By.name("sign-in")).click();

    // verify h1 tag is "Hello userName" after login
    driver.findElement(By.tagName("h1")).isDisplayed();
    assertThat(driver.findElement(By.tagName("h1")).getText(), is("Hello userName"));
  }
}
```

There are two problems with this approach.

* There is no separation between the test method and the AUT’s locators (IDs in this example); both are intertwined in a single method. If the AUT’s UI changes its identifiers, layout, or how a login is input and processed, the test itself must change.
* The ID-locators would be spread in multiple tests, in all tests that had to use this login page.

Applying the page object model, this example could be rewritten like this in the following example of a page object for a Sign-in page.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Sign-in page.
 */
public class SignInPage {
  protected WebDriver driver;

  // <input name="user_name" type="text" value="">
  private By usernameBy = By.name("user_name");
  // <input name="password" type="password" value="">
  private By passwordBy = By.name("password");
  // <input name="sign_in" type="submit" value="SignIn">
  private By signinBy = By.name("sign_in");

  public SignInPage(WebDriver driver){
    this.driver = driver;
     if (!driver.getTitle().equals("Sign In Page")) {
      throw new IllegalStateException("This is not Sign In Page," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Login as valid user
    *
    * @param userName
    * @param password
    * @return HomePage object
    */
  public HomePage loginValidUser(String userName, String password) {
    driver.findElement(usernameBy).sendKeys(userName);
    driver.findElement(passwordBy).sendKeys(password);
    driver.findElement(signinBy).click();
    return new HomePage(driver);
  }
}
```

and page object for a Home page could look like this.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Home Page
 */
public class HomePage {
  protected WebDriver driver;

  // <h1>Hello userName</h1>
  private By messageBy = By.tagName("h1");

  public HomePage(WebDriver driver){
    this.driver = driver;
    if (!driver.getTitle().equals("Home Page of logged in user")) {
      throw new IllegalStateException("This is not Home Page of logged in user," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Get message (h1 tag)
    *
    * @return String message text
    */
  public String getMessageText() {
    return driver.findElement(messageBy).getText();
  }

  public HomePage manageProfile() {
    // Page encapsulation to manage profile functionality
    return new HomePage(driver);
  }
  /* More methods offering the services represented by Home Page
  of Logged User. These methods in turn might return more Page Objects
  for example click on Compose mail button could return ComposeMail class object */
}
```

So now, the login test would use these two page objects as follows.

```java
/***
 * Tests login feature
 */
public class TestLogin {

  @Test
  public void testLogin() {
    SignInPage signInPage = new SignInPage(driver);
    HomePage homePage = signInPage.loginValidUser("userName", "password");
    assertThat(homePage.getMessageText(), is("Hello userName"));
  }

}
```

```html
<!-- Products Page -->
<div class="header_container">
    <span class="title">Products</span>
</div>

<div class="inventory_list">
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
</div>
```

Each product is a component of the Products page.

```html
<!-- Inventory Item -->
<div class="inventory_item">
    <div class="inventory_item_name">Backpack</div>
    <div class="pricebar">
        <div class="inventory_item_price">$29.99</div>
        <button id="add-to-cart-backpack">Add to cart</button>
    </div>
</div>
```

The Products page HAS-A list of products. This object relationship is called Composition. In simpler terms, something is *composed of* another thing.

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

// Page Object
public class ProductsPage extends BasePage {
    public ProductsPage(WebDriver driver) {
        super(driver);
        // No assertions, throws an exception if the element is not loaded
        new WebDriverWait(driver, Duration.ofSeconds(3))
            .until(d -> d.findElement(By.className​("header_container")));
    }

    // Returning a list of products is a service of the page
    public List<Product> getProducts() {
        return driver.findElements(By.className​("inventory_item"))
            .stream()
            .map(e -> new Product(e)) // Map WebElement to a product component
            .toList();
    }

    // Return a specific product using a boolean-valued function (predicate)
    // This is the behavioral Strategy Pattern from GoF
    public Product getProduct(Predicate<Product> condition) {
        return getProducts()
            .stream()
            .filter(condition) // Filter by product name or price
            .findFirst()
            .orElseThrow(() -> new RuntimeException("Product not found")); // Error thrown during actual test run
    }
}
```

The Product component object is used inside the Products page object.

```java
public abstract class BaseComponent {
    protected WebElement root;

    public BaseComponent(WebElement root) {
        this.root = root;
    }
}

// Page Component Object
public class Product extends BaseComponent {
    // The root element contains the entire component
    public Product(WebElement root) {
        super(root); // inventory_item
    }

    public String getName() {
        // Locating an element begins at the root of the component
        return root.findElement(By.className("inventory_item_name")).getText();
    }

    public BigDecimal getPrice() {
        return new BigDecimal(
                root.findElement(By.className("inventory_item_price"))
                    .getText()
                    .replace("$", "")
            ).setScale(2, RoundingMode.UNNECESSARY); // Sanitation and formatting
    }

    public void addToCart() {
        root.findElement(By.id("add-to-cart-backpack")).click();
    }
}
```

So now, the products test would use the page object and the page component object as follows.

```java
public class ProductsTest {
    @Test
    public void testProductInventory() {
        var productsPage = new ProductsPage(driver); // page object
        var products = productsPage.getProducts();
        assertEquals(6, products.size()); // expected, actual
    }
    
    @Test
    public void testProductPrices() {
        var productsPage = new ProductsPage(driver);

        // Pass a lambda expression (predicate) to filter the list of products
        // The predicate or "strategy" is the behavior passed as parameter
        var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); // page component object
        var bikeLight = productsPage.getProduct(p -> p.getName().equals("Bike Light"));

        assertEquals(new BigDecimal("29.99"), backpack.getPrice());
        assertEquals(new BigDecimal("9.99"), bikeLight.getPrice());
    }
}
```

```java
public class LoginPage {
    public HomePage loginAs(String username, String password) {
        // ... clever magic happens here
    }
    
    public LoginPage loginAsExpectingError(String username, String password) {
        //  ... failed login here, maybe because one or both of the username and password are wrong
    }
    
    public String getErrorMessage() {
        // So we can verify that the correct error is shown
    }
}
```

The code presented above shows an important point: the tests, not the Page Objects, should be responsible for making assertions about the state of a page. For example:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    inbox.assertMessageWithSubjectIsUnread("I like cheese");
    inbox.assertMessageWithSubjectIsNotUnread("I'm not fond of tofu");
}
```

could be re-written as:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    assertTrue(inbox.isMessageWithSubjectIsUnread("I like cheese"));
    assertFalse(inbox.isMessageWithSubjectIsUnread("I'm not fond of tofu"));
}
```

```java
public class LoginPage {
    private final WebDriver driver;

    public LoginPage(WebDriver driver) {
        this.driver = driver;

        // Check that we're on the right page.
        if (!"Login".equals(driver.getTitle())) {
            // Alternatively, we could navigate to the login page, perhaps logging out first
            throw new IllegalStateException("This is not the login page");
        }
    }

    // The login page contains several HTML elements that will be represented as WebElements.
    // The locators for these elements should only be defined once.
        By usernameLocator = By.id("username");
        By passwordLocator = By.id("passwd");
        By loginButtonLocator = By.id("login");

    // The login page allows the user to type their username into the username field
    public LoginPage typeUsername(String username) {
        // This is the only place that "knows" how to enter a username
        driver.findElement(usernameLocator).sendKeys(username);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to type their password into the password field
    public LoginPage typePassword(String password) {
        // This is the only place that "knows" how to enter a password
        driver.findElement(passwordLocator).sendKeys(password);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to submit the login form
    public HomePage submitLogin() {
        // This is the only place that submits the login form and expects the destination to be the home page.
        // A seperate method should be created for the instance of clicking login whilst expecting a login failure. 
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the login page ever
        // go somewhere else (for example, a legal disclaimer) then changing the method signature
        // for this method will mean that all tests that rely on this behaviour won't compile.
        return new HomePage(driver);	
    }

    // The login page allows the user to submit the login form knowing that an invalid username and / or password were entered
    public LoginPage submitLoginExpectingFailure() {
        // This is the only place that submits the login form and expects the destination to be the login page due to login failure.
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the user ever be navigated to the home page after submiting a login with credentials 
        // expected to fail login, the script will fail when it attempts to instantiate the LoginPage PageObject.
        return new LoginPage(driver);	
    }

    // Conceptually, the login page offers the user the service of being able to "log into"
    // the application using a user name and password. 
    public HomePage loginAs(String username, String password) {
        // The PageObject methods that enter username, password & submit login have already defined and should not be repeated here.
        typeUsername(username);
        typePassword(password);
        return submitLogin();
    }
}
```

# 2 - 领域特定语言

```java
/**
 * Takes a username and password, fills out the fields, and clicks "login".
 * @return An instance of the AccountPage
 */
public AccountPage loginAsUser(String username, String password) {
  WebElement loginField = driver.findElement(By.id("loginField"));
  loginField.clear();
  loginField.sendKeys(username);

  // Fill out the password field. The locator we're using is "By.id", and we should
  // have it defined elsewhere in the class.
  WebElement passwordField = driver.findElement(By.id("password"));
  passwordField.clear();
  passwordField.sendKeys(password);

  // Click the login button, which happens to have the id "submit".
  driver.findElement(By.id("submit")).click();

  // Create and return a new instance of the AccountPage (via the built-in Selenium
  // PageFactory).
  return PageFactory.newInstance(AccountPage.class);
}
```

此方法完全从测试代码中抽象出输入字段, 按钮, 单击甚至页面的概念. 使用这种方法, 测试人员要做的就是调用此方法. 这给您带来了维护方面的优势: 如果登录字段曾经更改过, 则只需更改此方法-而非您的测试.

```java
public void loginTest() {
    loginAsUser("cbrown", "cl0wn3");

    // Now that we're logged in, do some other stuff--since we used a DSL to support
    // our testers, it's as easy as choosing from available methods.
    do.something();
    do.somethingElse();
    Assert.assertTrue("Something should have been done!", something.wasDone());

    // Note that we still haven't referred to a button or web control anywhere in this
    // script...
}
```

郑重强调: 您的主要目标之一应该是编写一个API, 该API允许您的测试解决 **当前的问题, 而不是UI的问题**. 用户界面是用户的次要问题–用户并不关心用户界面, 他们只是想完成工作. 您的测试脚本应该像用户希望做的事情以及他们想知道的事情的完整清单那样易于阅读. 测试不应该考虑UI如何要求您去做.

\***AUT**: 待测系统

# 3 - 生成应用程序状态

Selenium不应用于准备测试用例. 测试用例中所有重复性动作和准备工作, 都应通过其他方法来完成.\
例如, 大多数Web UI都具有身份验证 (诸如一个登录表单) . 在每次测试之前通过Web浏览器进行登录的消除, 将提高测试的速度和稳定性. 应该创建一种方法来获取对 AUT\* 的访问权限 (例如, 使用API登录并设置Cookie) . 此外, 不应使用Selenium创建预加载数据来进行测试的方法.\
如前所述, 应利用现有的API为 AUT\* 创建数据. \***AUT**: 待测系统

# 4 - 模拟外部服务

消除对外部服务的依赖性将大大提高测试的速度和稳定性.

# 5 - 改善报告

Selenium并非旨在报告测试用例的运行状态. 利用单元测试框架的内置报告功能是一个好的开始. 大多数单元测试框架都有可以生成xUnit或HTML格式的报告. xUnit报表很受欢迎, 可以将其结果导入到持续集成（CI）服务器, 例如Jenkins、Travis、Bamboo等. 以下是一些链接, 可获取关于几种语言报表输出的更多信息.

[NUnit 3 Console Runner](//github.com/nunit/docs/wiki/Console-Runner)

[NUnit 3 Console Command Line](//github.com/nunit/docs/wiki/Console-Command-Line)

[xUnit getting test results in TeamCity](//xunit.net/docs/getting-test-results-in-teamcity)

[xUnit getting test results in CruiseControl.NET](//xunit.net/docs/getting-test-results-in-ccnet)

[xUnit getting test results in Azure DevOps](//xunit.net/docs/getting-test-results-in-azure-devops)

# 6 - 避免共享状态

尽管在多个地方都提到过, 但这点仍值得被再次提及. 确保测试相互隔离.

* 不要共享测试数据. 想象一下有几个测试, 每个测试都会在选择操作执行之前查询数据库中的有效订单. 如果两个测试采用相同的顺序, 则很可能会出现意外行为.

* 清理应用程序中过时的数据, 这些数据可能会被其他测试. 例如无效的订单记录.

* 每次测试都创建一个新的WebDriver实例. 这在确保测试隔离的同时可以保障并行化更为简单.

  * If you choose [pytest](https://pytest.org/) as your test runner, this can be easily done by yielding your driver in a global fixture. This way each test gets its own driver instance, and you can ensure that drivers always quit after a test is finished (pass or fail).

# 7 - 使用定位器的提示

# 8 - 测试的独立性

将每个测试编写为独立的单元. 以不依赖于其他测试完成的方式编写测试:

例如有一个内容管理系统, 您可以借助其创建一些自定义内容, 这些内容在发布后作为模块显示在您的网站上, 并且CMS和应用程序之间的同步可能需要一些时间.

测试模块的一种错误方法是在测试中创建并发布内容, 然后在另一测试中检查该模块. 这是不可取的, 因为发布后内容可能无法立即用于其他测试.

与之相反的事, 您可以创建在受影响的测试中打开和关闭的打桩内容, 并将其用于验证模块. 而且, 对于内容的创建, 您仍然可以进行单独的测试.

# 9 - 考虑使用Fluent API

Martin Fowler创造了术语 [“Fluent API”](//www.martinfowler.com/bliki/FluentInterface.html). Selenium已经在其 `FluentWait` 类中实现了类似的东西, 这是对标准 `Wait` 类的替代. 您可以在页面对象中启用Fluent API设计模式, 然后使用如下代码段查询Google搜索页面:

```java
driver.get( "http://www.google.com/webhp?hl=en&amp;tab=ww" );
GoogleSearchPage gsp = new GoogleSearchPage(driver);
gsp.setSearchString().clickSearchButton();
```

Google页面对象类具有这种流畅行为后可能看起来像这样:

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

public class GoogleSearchPage extends BasePage {
    public GoogleSearchPage(WebDriver driver) {
        super(driver);
        // Generally do not assert within pages or components.
        // Effectively throws an exception if the lambda condition is not met.
        new WebDriverWait(driver, Duration.ofSeconds(3)).until(d -> d.findElement(By.id("logo")));
    }

    public GoogleSearchPage setSearchString(String sstr) {
        driver.findElement(By.id("gbqfq")).sendKeys(sstr);
        return this;
    }

    public void clickSearchButton() {
        driver.findElement(By.id("gbqfb")).click();
    }
}
```

# 10 - 每次测试都刷新浏览器

每次测试都从一个干净的已知状态开始. 理想情况下, 为每次测试打开一个新的虚拟机. 如果打开新虚拟机不切实际, 则至少应为每次测试启动一个新的WebDriver. 对于Firefox, 请使用您已知的配置文件去启动WebDriver. 大多数浏览器驱动器，像GeckoDriver和ChromeDriver那样，默认都会以干净的已知状态和一个新的用户配置文件开始。

```java
WebDriver driver = new FirefoxDriver();
```

----
url: https://www.selenium.dev/documentation/webdriver/browsers/firefox/
----

# Firefox specific functionality

```java
    driver = new FirefoxDriver(options);
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L36-L37)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L10-L11)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
        public void BasicOptions()
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L34-L35)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/openFirefoxTest.spec.js#L10-L13)

##### /examples/javascript/test/getting\_started/openFirefoxTest.spec.js

```js
const {Browser, Builder} = require('selenium-webdriver');
const firefox = require('selenium-webdriver/firefox');


describe('Open Firefox', function () {
  let driver;

  before(async function () {
    let options = new firefox.Options();
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options)
      .build();
  });

  after(async () => await driver.quit());

  it('Basic Firefox test', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options.add_argument("-headless")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L19)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            var options = new FirefoxOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L43)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options.args << '-headless'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L17)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
      .setFirefoxOptions(options.addArguments('--headless'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L12)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L54)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options.binary_location = firefox_bin
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L28)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            var options = new FirefoxOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L53)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options.binary = firefox_location
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L25)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
    driver = new FirefoxDriver(options);
  }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L211-L216)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L160-L168)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```csharp
var options = new FirefoxOptions();
var profile = new FirefoxProfile();
options.Profile = profile;
var driver = new FirefoxDriver(options);
  
```

```rb
      profile = Selenium::WebDriver::Firefox::Profile.new
        profile['browser.download.dir'] = '/tmp/webdriver-downloads'
        options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L139-L141)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true
  
  require 'spec_helper'
  
  RSpec.describe 'Firefox' do
    describe 'Options' do
      let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }
  
      it 'basic options' do
        options = Selenium::WebDriver::Options.firefox
        @driver = Selenium::WebDriver.for :firefox, options: options
      end
  
      it 'add arguments' do
        options = Selenium::WebDriver::Options.firefox
  
        options.args << '-headless'
  
        @driver = Selenium::WebDriver.for :firefox, options: options
      end
  
      it 'sets location of binary' do
        options = Selenium::WebDriver::Options.firefox
  
        options.binary = firefox_location
  
        @driver = Selenium::WebDriver.for :firefox, options: options
      end
    end
  
    describe 'Service' do
      let(:file_name) { Tempfile.new('geckodriver').path }
      let(:root_directory) { Dir.mktmpdir }
  
      after do
        FileUtils.rm_f(file_name)
        FileUtils.rm_rf(root_directory)
      end
  
      it 'logs to file' do
        service = Selenium::WebDriver::Service.firefox
  
        service.log = file_name
  
        @driver = Selenium::WebDriver.for :firefox, service: service
        expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
      end
  
      it 'logs to console' do
        service = Selenium::WebDriver::Service.firefox
  
        service.log = $stdout
  
        expect {
          @driver = Selenium::WebDriver.for :firefox, service: service
        }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
      end
  
      it 'sets log level' do
        service = Selenium::WebDriver::Service.firefox
        service.log = file_name
  
        service.args += %w[--log debug]
  
        @driver = Selenium::WebDriver.for :firefox, service: service
        expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
      end
  
      it 'stops truncating log lines' do
        service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])
  
        service.args << '--log-no-truncate'
  
        @driver = Selenium::WebDriver.for :firefox, service: service
        expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
      end
  
      it 'sets default profile location' do
        service = Selenium::WebDriver::Service.firefox
  
        service.args += ['--profile-root', root_directory]
  
        @driver = Selenium::WebDriver.for :firefox, service: service
        profile_location = Dir.new(@driver.capabilities['moz:profile'])
        expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
      end
    end
  
    describe 'Features' do
      let(:driver) { start_firefox }
  
      it 'installs addon' do
        extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
  
        driver.install_addon(extension_file_path)
  
        driver.get 'https://www.selenium.dev/selenium/web/blank.html'
        injected = driver.find_element(id: 'webextensions-selenium-example')
        expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
      end
  
      it 'uninstalls addon' do
        extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
        extension_id = driver.install_addon(extension_file_path)
  
        driver.uninstall_addon(extension_id)
  
        driver.get 'https://www.selenium.dev/selenium/web/blank.html'
        expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
      end
  
      it 'installs unsigned addon' do
        extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)
  
        driver.install_addon(extension_dir_path, true)
  
        driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
        injected = driver.find_element(id: 'webextensions-selenium-example')
        expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
      end
  
      it 'takes full page screenshot' do
        driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
        Dir.mktmpdir('screenshot_test') do |dir|
          screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))
  
          expect(screenshot).to be_a File
        end
      end
  
      it 'sets the context' do
        driver.context = 'content'
        expect(driver.context).to eq 'content'
      end
    end
  
    describe 'Profile' do
      it 'creates a new profile' do
        profile = Selenium::WebDriver::Firefox::Profile.new
        profile['browser.download.dir'] = '/tmp/webdriver-downloads'
        options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
        expect(options.profile).to eq(profile)
      end
    end
  
    def driver_finder
      options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
      service = Selenium::WebDriver::Service.firefox
      finder = Selenium::WebDriver::DriverFinder.new(options, service)
      ENV['GECKODRIVER_BIN'] = finder.driver_path
      ENV['FIREFOX_BIN'] = finder.browser_path
    end
  end
  
```

```javascript
const { Builder } = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');

const options = new firefox.Options();
let profile = '/path to custom profile';
options.setProfile(profile);
const driver = new Builder()
    .forBrowser('firefox')
    .setFirefoxOptions(options)
    .build();
  
```

```kotlin
val options = FirefoxOptions()
options.profile = FirefoxProfile()
driver = FirefoxDriver(options)
  
```

```java
        new GeckoDriverService.Builder().withLogFile(logLocation).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L62-L63)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY`\
Property value: String representing path to log file

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L36)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L43)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withLogOutput(System.out).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L76-L77)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L48)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L52)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L90-L91)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY`\
Property value: String representation of `FirefoxDriverLogLevel` enum

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L59)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args += %w[--log debug]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L63)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L106-L107)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_NO_TRUNCATE`\
Property value: `"true"` or `"false"`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L70)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '--log-no-truncate'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L72)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L118-L119)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_PROFILE_ROOT`\
Property value: String representing path to profile root directory

```py
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L81)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args += ['--profile-root', root_directory]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L81)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L133)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.install_addon(addon_path_xpi)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L94)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L137)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      driver.install_addon(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L95)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    let id = await driver.installAddon(xpiPath);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L25)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L148)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.uninstall_addon(id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L106)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```cs
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L152)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      driver.uninstall_addon(extension_id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L106)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    await driver.uninstallAddon(id);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L26)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L160)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.install_addon(addon_path_dir, temporary=True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L115)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```cs
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L165)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```rb
      driver.install_addon(extension_dir_path, true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L115)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    let id = await driver.installAddon(xpiPath, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L41)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L181)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.save_full_page_screenshot("full_page_screenshot.png")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L139)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L125)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
    // Verify the context is back to "content"
    Assertions.assertEquals(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L197-L198)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L151-L152)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      driver.context = 'content'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L132)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

**Note**: As of Firefox 138, geckodriver needs to be started with the argument `--allow-system-access` to switch the context to `CHROME`.

----
url: https://www.selenium.dev/pt-br/documentation/legacy/selenium_3/grid_setup/
----

# Configurando a sua

```shell
java -jar selenium-server-standalone.jar -role hub
```

The Hub will listen to port 4444 by default. You can view the status of the hub by opening a browser window and navigating to <http://localhost:4444/grid/console>.

Para alterar a porta padrão, você pode adicionar a flag opcional `-port` com um número inteiro representando a porta a ser ouvida quando você executa o comando. Além disso, todas as outras opções que você vê no arquivo de configuração JSON (veja abaixo) são possíveis flags de linha de comando.

Você certamente pode sobreviver apenas com o comando simples mostrado acima, mas se você precisar de uma configuração mais avançada, você também pode especificar um arquivo de configuração de formato JSON, por conveniência, para configurar o hub ao iniciá-lo. Você pode fazer assim:

```shell
java -jar selenium-server-standalone.jar -role hub -hubConfig hubConfig.json -debug
```

Abaixo você verá um exemplo de um arquivo `hubConfig.json`. Entraremos em mais detalhes sobre como fornecer arquivos de configuração de nó no Passo 2.

```json
{
  "_comment" : "Configuration for Hub - hubConfig.json",
  "host": ip,
  "maxSession": 5,
  "port": 4444,
  "cleanupCycle": 5000,
  "timeout": 300000,
  "newSessionWaitTimeout": -1,
  "servlets": [],
  "prioritizer": null,
  "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
  "throwOnCapabilityNotPresent": true,
  "nodePolling": 180000,
  "platform": "WINDOWS"}
```

### Pasos 2: Inicialize os Nós

Independentemente de você querer executar uma Grid com a nova funcionalidade WebDriver, ou uma Grid com funcionalidade Selenium 1 RC, ou os dois ao mesmo tempo, você usa o mesmo arquivo `selenium-server-standalone.jar` para iniciar os nós:

```shell
java -jar selenium-server-standalone.jar -role node -hub http://localhost:4444
```

```shell
java -Dwebdriver.chrome.driver=chromedriver.exe -jar selenium-server-standalone.jar -role node -nodeConfig node1Config.json
```

E aqui está um exemplo do arquivo `nodeConfig.json`:

```json
{
  "capabilities": [
    {
      "browserName": "firefox",
      "acceptSslCerts": true,
      "javascriptEnabled": true,
      "takesScreenshot": false,
      "firefox_profile": "",
      "browser-version": "27",
      "platform": "WINDOWS",
      "maxInstances": 5,
      "firefox_binary": "",
      "cleanSession": true
    },
    {
      "browserName": "chrome",
      "maxInstances": 5,
      "platform": "WINDOWS",
      "webdriver.chrome.driver": "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"
    },
    {
      "browserName": "internet explorer",
      "maxInstances": 1,
      "platform": "WINDOWS",
      "webdriver.ie.driver": "C:/Program Files (x86)/Internet Explorer/iexplore.exe"
    }
  ],
  "configuration": {
    "_comment" : "Configuration for Node",
    "cleanUpCycle": 2000,
    "timeout": 30000,
    "proxy": "org.openqa.grid.selenium.proxy.WebDriverRemoteProxy",
    "port": 5555,
    "host": ip,
    "register": true,
    "hubPort": 4444,
    "maxSession": 5
  }
}
```

```shell
java -jar selenium-server-standalone.jar -role hub -log log.txt
```

Use o seu editor de texto favorito para abrir o arquivo de log (log.txt no exemplo acima) para encontrar registros de “ERROR” se você tiver problemas.

### Usando o argumento `-debug`

Você também pode usar o argumento `-debug` para imprimir logs de depuração no console. Inicie o Selenium Grid Hub ou Node com o argumento `-debug`. Por favor, veja o exemplo abaixo:

```shell
java -jar selenium-server-standalone.jar -role hub -debug
```

## Aviso

A Selenium Grid deve ser protegida do acesso externo usando permissões de firewall.

A falha em proteger sua rede pode resultar em um ou mais dos seguintes eventos:

* Você fornece acesso aberto à sua infraestrutura de rede
* Você permite que terceiros acessem aplicativos e arquivos internos da web
* Você permite que terceiros executem binários personalizados

Veja esta postagem do blog em [Detectify](/pt-br/), que dá uma boa visão geral de como uma rede exposta publicamente pode ser mal utilizada: [Não deixe sua grade totalmente aberta](//labs.detectify.com/2017/10/06/guest-blog-dont-leave-your-grid-wide-open/).

## Docker Selenium

[Docker](/pt-br/) fornece uma maneira conveniente de provisionar e escalar a infraestrutura da Selenium Grid em uma unidade conhecida como contêiner. Os contêineres são unidades padronizadas de software que contêm tudo o que é necessário para executar o aplicativo desejado, incluindo todas as dependências, de forma confiável e repetível em máquinas diferentes.

O projeto Selenium mantém um conjunto de imagens Docker que você pode baixar e executar para colocar uma Grid em funcionamento rapidamente. Os nós estão disponíveis para Firefox e Chrome. Detalhes completos de como provisionar uma grade podem ser encontrados no repositório [Docker Selenium](//github.com/SeleniumHQ/docker-selenium).

### Pré-requisitos

O único requisito para executar um Grid é ter o Docker instalado e funcionando. \[Instale o Docker] (// [www.docker.com/products/docker-desktop)](https://www.docker.com/products/docker-desktop%29).

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/interactions/
----

# Browser interactions

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java#L15)

##### /examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class InteractionsTest extends BaseChromeTest {
    @Test
    public void getTitle() {
        driver.get("https://www.selenium.dev/");
        // get title
        String title = driver.getTitle();
        Assertions.assertEquals(title, "Selenium");
    }

    @Test
    public void getCurrentUrl() {
        driver.get("https://www.selenium.dev/");
        // get current url
        String url = driver.getCurrentUrl();
        Assertions.assertEquals(url, "https://www.selenium.dev/");
    }
}
```

```py
title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_interactions.py#L7)

##### /examples/python/tests/interactions/test\_interactions.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")

title = driver.title
assert title == "Selenium"

url = driver.current_url
assert url == "https://www.selenium.dev/"

driver.quit()
```

```cs
            String title = driver.Title;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs#L37)

##### /examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class InteractionsTest
    {
        [TestMethod]
        public void TestInteractions()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url="https://www.selenium.dev/";
            //GetTitle
            String title = driver.Title;
            Assert.AreEqual(title, "Selenium");

            //GetCurrentURL
            String url = driver.Url;
            Assert.AreEqual(url, "https://www.selenium.dev/");

            //quitting driver
            driver.Quit(); //close all windows
        }
    }
}
```

```rb
  it 'gets the current title' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/browser_spec.rb#L8)

##### /examples/ruby/spec/interactions/browser\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'gets the current title' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_title = driver.title
    expect(current_title).to eq 'Selenium'
  end

  it 'gets the current url' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_url = driver.current_url
    expect(current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    let title = await driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/interactionsIndex.spec.js#L20)

##### /examples/javascript/test/interactions/interactionsIndex.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Should be able to get title and current url', async function () {
    const url = 'https://www.selenium.dev/';
    await driver.get(url);

    //Get Current title
    let title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Get Current url
    let currentUrl = await driver.getCurrentUrl();
    assert.equal(currentUrl, url);
  });
});
```

```kotlin
driver.title
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java#L26)

##### /examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class InteractionsTest extends BaseChromeTest {
    @Test
    public void getTitle() {
        driver.get("https://www.selenium.dev/");
        // get title
        String title = driver.getTitle();
        Assertions.assertEquals(title, "Selenium");
    }

    @Test
    public void getCurrentUrl() {
        driver.get("https://www.selenium.dev/");
        // get current url
        String url = driver.getCurrentUrl();
        Assertions.assertEquals(url, "https://www.selenium.dev/");
    }
}
```

```py
url = driver.current_url
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_interactions.py#L10)

##### /examples/python/tests/interactions/test\_interactions.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")

title = driver.title
assert title == "Selenium"

url = driver.current_url
assert url == "https://www.selenium.dev/"

driver.quit()
```

```cs
            String url = driver.Url;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs#L41)

##### /examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class InteractionsTest
    {
        [TestMethod]
        public void TestInteractions()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url="https://www.selenium.dev/";
            //GetTitle
            String title = driver.Title;
            Assert.AreEqual(title, "Selenium");

            //GetCurrentURL
            String url = driver.Url;
            Assert.AreEqual(url, "https://www.selenium.dev/");

            //quitting driver
            driver.Quit(); //close all windows
        }
    }
}
```

```rb
  it 'gets the current url' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/browser_spec.rb#L14)

##### /examples/ruby/spec/interactions/browser\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'gets the current title' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_title = driver.title
    expect(current_title).to eq 'Selenium'
  end

  it 'gets the current url' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_url = driver.current_url
    expect(current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    let currentUrl = await driver.getCurrentUrl();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/interactionsIndex.spec.js#L24)

##### /examples/javascript/test/interactions/interactionsIndex.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Should be able to get title and current url', async function () {
    const url = 'https://www.selenium.dev/';
    await driver.get(url);

    //Get Current title
    let title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Get Current url
    let currentUrl = await driver.getCurrentUrl();
    assert.equal(currentUrl, url);
  });
});
```

```kotlin
driver.currentUrl
```

***

##### [Browser navigation](/pt-br/documentation/webdriver/interactions/navigation/)

##### [Alertas, prompts e confirmações JavaScript](/pt-br/documentation/webdriver/interactions/alerts/)

##### [Trabalhando com cookies](/pt-br/documentation/webdriver/interactions/cookies/)

##### [Working with IFrames and frames](/pt-br/documentation/webdriver/interactions/frames/)

##### [Print Page](/pt-br/documentation/webdriver/interactions/print_page/)

##### [Working with windows and tabs](/pt-br/documentation/webdriver/interactions/windows/)

##### [Virtual Authenticator](/pt-br/documentation/webdriver/interactions/virtual_authenticator/)

Uma representação do modelo Web Authenticator.

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/interactions/frames/
----

# 与IFrames和frames一起工作

框架是一种现在已被弃用的方法，用于从同一域中的多个文档构建站点布局。除非你使用的是 HTML5 之前的 webapp，否则你不太可能与他们合作。内嵌框架允许插入来自完全不同领域的文档，并且仍然经常使用。

如果您需要使用框架或 iframe, WebDriver 允许您以相同的方式使用它们。考虑 iframe 中的一个按钮。 如果我们使用浏览器开发工具检查元素，我们可能会看到以下内容:

```html
<div id="modal">
  <iframe id="buttonframe" name="myframe" src="https://seleniumhq.github.io">
   <button>Click here</button>
 </iframe>
</div>
```

```java
// 这不会工作
driver.findElement(By.tagName("button")).click();
```

```python
    # 这不会工作
driver.find_element(By.TAG_NAME, 'button').click()
```

```csharp
// 这不会工作
driver.FindElement(By.TagName("button")).Click();
```

```ruby
    # 这不会工作
driver.find_element(:tag_name,'button').click
```

```javascript
// 这不会工作
await driver.findElement(By.css('button')).click();
```

```kotlin
// 这不会工作
driver.findElement(By.tagName("button")).click()
```

```java
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L38-L46)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L24-L32)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L38-L46)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L26-L33)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// 存储网页元素
const iframe = driver.findElement(By.css('#modal> iframe'));

// 切换到 frame
await driver.switchTo().frame(iframe);

// 现在可以点击按钮
await driver.findElement(By.css('button')).click();
```

```kotlin
// 存储网页元素
val iframe = driver.findElement(By.cssSelector("#modal>iframe"))

// 切换到 frame
driver.switchTo().frame(iframe)

// 现在可以点击按钮
driver.findElement(By.tagName("button")).click()
```

```java
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L50-L58)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L34-L42)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L50-L58)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L36-L43)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// 使用 ID
await driver.switchTo().frame('buttonframe');

// 或者使用 name 代替
await driver.switchTo().frame('myframe');

// 现在可以点击按钮
await driver.findElement(By.css('button')).click();
```

```kotlin
// 使用 ID
driver.switchTo().frame("buttonframe")

// 或者使用 name 代替
driver.switchTo().frame("myframe")

// 现在可以点击按钮
driver.findElement(By.tagName("button")).click()
```

```java
         //switch To IFrame using index
         driver.switchTo().frame(0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L62-L63)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L45-L46)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L62-L63)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L46-L47)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// 切换到第 2 个框架
await driver.switchTo().frame(1);
```

```kotlin
// 切换到第 2 个框架
driver.switchTo().frame(1)
```

```java
         //leave frame
         driver.switchTo().defaultContent();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L66-L67)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L49-L50)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //leave frame
            driver.SwitchTo().DefaultContent();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L66-L67)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L49-L50)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// 回到顶层
await driver.switchTo().defaultContent();
```

```kotlin
// 回到顶层
driver.switchTo().defaultContent()
```

最后修改 January 21, 2026: [Fix iframe attribute spacing in Chinese frames documentation (#2563)\[deploy site\] (149c6738738)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/149c67387387cf00ad974c9cef62e7bcc68a732f)

----
url: https://www.selenium.dev/zh-cn/documentation/grid/advanced_features/observability/
----

# 可观测性

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar standalone --log-level FINE
```

2. Jaeger UI - OpenTelemetry provides the APIs and SDKs to instrument traces in the code. Whereas Jaeger is a tracing backend, that aids in collecting the tracing telemetry data and providing querying, filtering and visualizing features for the data.

Detailed instructions of visualizing traces using Jaeger UI can be obtained by running the command :

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar info tracing
```

[A very good example and scripts to run the server and send traces to Jaeger](https://github.com/manoj9788/tracing-selenium-grid)

## Leveraging event logs

Tracing has to be enabled for event logging as well, even if one does not wish to export traces to visualize them.\
**By default, tracing is enabled. No additional parameters need to be passed to see logs on the console.** All events within a span are logged at FINE level. Error events are logged at WARN level.

All event logs have the following fields :

| Field            | Field value     | Description                                                                                                                                                                            |
| ---------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Event time       | eventId         | Timestamp of the event record in epoch nanoseconds.                                                                                                                                    |
| Trace Id         | tracedId        | Each trace is uniquely identified by a trace id.                                                                                                                                       |
| Span Id          | spanId          | Each span within a trace is uniquely identified by a span id.                                                                                                                          |
| Span Kind        | spanKind        | Span kind is a property of span indicating the type of span. It helps in understanding the nature of the unit of work done by the Span.                                                |
| Event name       | eventName       | This maps to the log message.                                                                                                                                                          |
| Event attributes | eventAttributes | This forms the crux of the event logs, based on the operation executed, it has JSON formatted key-value pairs. This also includes a handler class attribute, to show the logger class. |

Sample log

```
FINE [LoggingOptions$1.lambda$export$1] - {
  "traceId": "fc8aef1d44b3cc8bc09eb8e581c4a8eb",
  "spanId": "b7d3b9865d3ddd45",
  "spanKind": "INTERNAL",
  "eventTime": 1597819675128886121,
  "eventName": "Session request execution complete",
  "attributes": {
    "http.status_code": 200,
    "http.handler_class": "org.openqa.selenium.grid.router.HandleSession",
    "http.url": "\u002fsession\u002fdd35257f104bb43fdfb06242953f4c85",
    "http.method": "DELETE",
    "session.id": "dd35257f104bb43fdfb06242953f4c85"
  }
}
```

In addition to the above fields, based on [OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/exceptions.md) error logs consist of :

| Field                | Field value          | Description                                                                                                                   |
| -------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Exception type       | exception.type       | The class name of the exception.                                                                                              |
| Exception message    | exception.message    | Reason for the exception.                                                                                                     |
| Exception stacktrace | exception.stacktrace | Prints the call stack at the point of time when the exception was thrown. Helps in understanding the origin of the exception. |

Sample error log

```
WARN [LoggingOptions$1.lambda$export$1] - {
  "traceId": "7efa5ea57e02f89cdf8de586fe09f564",
  "spanId": "914df6bc9a1f6e2b",
  "spanKind": "INTERNAL",
  "eventTime": 1597820253450580272,
  "eventName": "exception",
  "attributes": {
    "exception.type": "org.openqa.selenium.ScriptTimeoutException",
    "exception.message": "Unable to execute request: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist ..." (full message will be printed),
    "exception.stacktrace": "org.openqa.selenium.ScriptTimeoutException: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist\nBuild info: version: '4.0.0-alpha-7', revision: 'Unknown'\nSystem info: host: 'XYZ-MacBook-Pro.local', ip: 'fe80:0:0:0:10d5:b63a:bdc6:1aff%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.7'\nDriver info: driver.version: unknown ...." (full stack will be printed),
    "http.handler_class": "org.openqa.selenium.grid.distributor.remote.RemoteDistributor",
    "http.url": "\u002fsession",
    "http.method": "POST"
  }
}
```

----
url: https://www.selenium.dev/pt-br/documentation/grid/applicability/
----

# Quando usar a Grid

```
   15      *       45s        /        1        =      11m 15s   // Sem Grid
   15      *       45s        /        5        =      2m 15s    // Grid com 5 Nodes
   15      *       45s        /        15       =      45s       // Grid com 15 Nodes
  100      *       120s       /        15       =      13m 20s   // Demoraria mais de 3 horas sem Grid
```

À medida que a bateria de testes executa, a Grid vai alocando os testes contra estes navegadores como está definido nos testes.

Uma configuração deste tipo pode acelerar bastante o tempo de execução mesmo no caso de baterias de testes grandes.

A Selenium Grid é uma parte integrante do projecto Selenium e é mantida em paralelo pela mesma equipa de developers que desenvolvem o resto das funcionalidades base do projecto. Dada a importância da velocidade e desempenho da execução dos testes, a Grid tem sido considerada desde o início como uma parte crítica e fundamental ao projecto.

Última modificação November 15, 2022: [Translate Grid Documentation (#1230) (7608996f8ab)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/7608996f8ab79ac2878a0f873687a61be5aabba6)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/options/
----

# 浏览器选项

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L73-74)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L79-80)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L11)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L80-82)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L86-88)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options.browser_version = 'latest'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L40)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## pageLoadStrategy

共有三种类型的页面加载策略.

页面加载策略可以在此链接查询 [document.readyState](//developer.mozilla.org/en-US/docs/Web/API/Document/readyState) , 如下表所述:

| 策略     | 就绪状态        | 备注                            |
| ------ | ----------- | ----------------------------- |
| normal | complete    | 默认值, 等待所有资源下载                 |
| eager  | interactive | DOM 访问已准备就绪, 但诸如图像的其他资源可能仍在加载 |
| none   | Any         | 完全不会阻塞 WebDriver              |

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L21-L23)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L7-9)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L13-14)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L11-L12)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L28-L34)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L34-L36)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L15-L17)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L29-30)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L20-L21)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L8-L14)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L47-L49)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L23-L25)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
        public void SetPageLoadStrategyNone()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L41-42)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L29-L30)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L18-L24)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L88-L90)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L94-96)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L38-L39)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L60-L61)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L101-103)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L51-L52)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L38-L41)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L96-L98)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L30-32)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L114-L115)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L111-L113)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L37-39)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L105-L106)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L126-L128)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L44-46)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L96-L97)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L141-L142)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L51-53)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L60-L61)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L151-L152)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L58-60)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L69-L70)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L163-L164)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L65-67)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L78-L79)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class ProxyTest {
  public static void main(String[] args) {
    Proxy proxy = new Proxy();
    proxy.setHttpProxy("<HOST:PORT>");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("proxy", proxy);
    WebDriver driver = new ChromeDriver(options);
    driver.get("https://www.google.com/");
    driver.manage().window().maximize();
    driver.quit();
  }
}
```

```py
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L72-74)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

public class ProxyTest{
public static void Main() {
ChromeOptions options = new ChromeOptions();
Proxy proxy = new Proxy();
proxy.Kind = ProxyKind.Manual;
proxy.IsAutoDetect = false;
proxy.SslProxy = "<HOST:PORT>";
options.Proxy = proxy;
options.AddArgument("ignore-certificate-errors");
IWebDriver driver = new ChromeDriver(options);
driver.Navigate().GoToUrl("https://www.selenium.dev/");
}
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L87-L88)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```javascript
let webdriver = require('selenium-webdriver');
let chrome = require('selenium-webdriver/chrome');
let proxy = require('selenium-webdriver/proxy');
let opts = new chrome.Options();

(async function example() {
opts.setProxy(proxy.manual({http: '<HOST:PORT>'}));
let driver = new webdriver.Builder()
.forBrowser('chrome')
.setChromeOptions(opts)
.build();
try {
await driver.get("https://selenium.dev");
}
finally {
await driver.quit();
}
}());
```

```kotlin
import org.openqa.selenium.Proxy
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

class proxyTest {
fun main() {

        val proxy = Proxy()
        proxy.setHttpProxy("<HOST:PORT>")
        val options = ChromeOptions()
        options.setCapability("proxy", proxy)
        val driver: WebDriver = ChromeDriver(options)
        driver["https://www.google.com/"]
        driver.manage().window().maximize()
        driver.quit()
    }
}
```

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/support_features/thread_guard/
----

# 线程守卫

此类仅在Java中可用

ThreadGuard检查是否仅从创建驱动程序的同一线程中调用了驱动程序. 线程问题 (尤其是在Parallel中运行测试时) 可能遇到神秘并且难以诊断错误. 使用此包装器可以防止此类错误,\
并且在发生此类情况时会抛出异常.

以下的示例模拟一种线程冲突的情况:

```java
public class DriverClash {
  //thread main (id 1) created this driver
  private WebDriver protectedDriver = ThreadGuard.protect(new ChromeDriver());

  static {
    System.setProperty("webdriver.chrome.driver", "<Set path to your Chromedriver>");
  }

  //Thread-1 (id 24) is calling the same driver causing the clash to happen
  Runnable r1 = () -> {protectedDriver.get("https://selenium.dev");};
  Thread thr1 = new Thread(r1);

  void runThreads(){
    thr1.start();
  }

  public static void main(String[] args) {
    new DriverClash().runThreads();
  }
}
```

结果如下所示:

```text
Exception in thread "Thread-1" org.openqa.selenium.WebDriverException:
Thread safety error; this instance of WebDriver was constructed
on thread main (id 1)and is being accessed by thread Thread-1 (id 24)
This is not permitted and *will* cause undefined behaviour
```

最后修改 September 23, 2022: [rename additional features section back to support features to re-emphasize the distinct purpose of support classes (c70272e7f8b)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/c70272e7f8be03fada236fd1f6dc75e81ec79638)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/bidi/
----

# 双向功能

双向是指通信同时在两个方向上进行. 传统的 WebDriver 模型涉及严格的请求/响应命令, 在任何时候都只允许单向通信. 在大多数情况下, 这正是您想要的；它能确保浏览器以正确的顺序执行预期的操作, 但异步交互也有许多有趣的地方.

目前, \[Chrome DevTools Protocol] (CDP) 可以有限地提供这种功能, 但为了解决它的一些缺点, Selenium 团队与主要浏览器供应商一起创建了新的 [WebDriver BiDi 协议](https://w3c.github.io/webdriver-bidi/). 该规范旨在创建一个稳定的跨浏览器 API, 利用双向通信增强浏览器自动化和测试功能、 包括通过 WebSockets 从用户代理到控制软件的流式事件. 用户将能在 Selenium 会话过程中监听、记录或操作事件.

### 在Selenium中启用 BiDi

为了使用 WebDriver BiDi, 在浏览器选项中设置该功能将启用所需的功能:

*
*
*
*
*
*

```java
options.setCapability("webSocketUrl", true);
```

```python
options.enable_bidi = True
```

```csharp
UseWebSocketUrl = true,
```

```ruby
options.web_socket_url = true
```

```javascript
Options().enableBidi();
```

```kotlin
options.setCapability("webSocketUrl", true);
```

这将启用用于双向通信的 WebSocket 连接、 释放 WebDriver BiDi 协议的全部潜能.

请注意, Selenium 正在将其整个实现从 WebDriver Classic 升级到 WebDriver BiDi (同时尽可能保持向后兼容性) , 但本部分文档的重点是双向通信所允许的新功能.

终端用户可以在代码中访问低级 BiDi 域, 但我们的目标是提供高级应用程序接口, 这些应用程序接口是真实世界用例的直接方法. 因此, 我们将不对底层组件进行记录, 本节将只关注我们鼓励使用者利用的用户友好功能.

如果您希望看到其他功能, 请提出 [功能请求](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=\&template=feature.md).

***

##### [WebDriver BiDi Network Features](/zh-cn/documentation/webdriver/bidi/network/)

These features are related to networking, and are made available via a “network” namespace.

##### [WebDriver BiDi Script Features](/zh-cn/documentation/webdriver/bidi/script/)

These features are related to scripts, and are made available via a “script” namespace.

##### [WebDriver BiDi 日志功能](/zh-cn/documentation/webdriver/bidi/logging/)

这些功能与日志记录有关。 由于"logging"可以指代许多不同的事物, 因此这些方法通过"script"命名空间提供.

##### [Chrome DevTools 协议](/zh-cn/documentation/webdriver/bidi/cdp/)

使用 Selenium 操作 Chrome DevTools 协议的示例。 CDP 的支持是临时的，直到 WebDriver BiDi 实现为止。

##### [BiDirectional API (W3C compliant)](/zh-cn/documentation/webdriver/bidi/w3c/)

最后修改 March 1, 2025: [Feature/bidi 20250301 (#2203) (d4164e6ce61)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/d4164e6ce6165e2fbd713414a323b4dc9993106c)

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/encouraged/avoid_sharing_state/
----

# 避免共享状态

尽管在多个地方都提到过, 但这点仍值得被再次提及. 确保测试相互隔离.

* 不要共享测试数据. 想象一下有几个测试, 每个测试都会在选择操作执行之前查询数据库中的有效订单. 如果两个测试采用相同的顺序, 则很可能会出现意外行为.

* 清理应用程序中过时的数据, 这些数据可能会被其他测试. 例如无效的订单记录.

* 每次测试都创建一个新的WebDriver实例. 这在确保测试隔离的同时可以保障并行化更为简单.

  * If you choose [pytest](https://pytest.org/) as your test runner, this can be easily done by yielding your driver in a global fixture. This way each test gets its own driver instance, and you can ensure that drivers always quit after a test is finished (pass or fail).

最后修改 September 23, 2024: [Added more detail to Avoid Sharing State Documentation (#1948)\[deploy site\] (e1fa2da1696)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e1fa2da1696971bd7e22f613dce09a8934fd56ff)

----
url: https://www.selenium.dev/ja/documentation/webdriver/bidi/logging/
----

# WebDriver BiDi Logging Features

These features are related to logging. Because “logging” can refer to so many different things, these methods are made available via a “script” namespace.

Remember that to use WebDriver BiDi, you must enable it in Options. For more details, see [Enabling BiDi](https://www.selenium.dev/ja/documentation/webdriver/bidi/)

```py
    driver.script.add_console_message_handler(log_entries.append)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/test_bidi_logging.py#L11)

##### /examples/python/tests/bidi/test\_bidi\_logging.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_console_message_handler(log_entries.append)

    driver.find_element(By.ID, "consoleLog").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Hello, world!"


@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0


@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_javascript_error_handler(log_entries.append)

    driver.find_element(By.ID, "jsException").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Error: Not working"


@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    log_entries = []
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/logging_spec.rb#L11)

##### /examples/ruby/spec/bidi/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_console_message_handler { |log| log_entries << log }

    driver.find_element(id: 'consoleLog').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Hello, world!'
  end

  it 'removes console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_console_message_handler { |log| log_entries << log }
    driver.script.remove_console_message_handler(id)

    driver.find_element(id: 'consoleLog').click
    expect(log_entries).to be_empty
  end

  it 'adds JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_javascript_error_handler { |error| log_entries << error }

    driver.find_element(id: 'jsException').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Error: Not working'
  end

  it 'removes JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_javascript_error_handler { |error| log_entries << error }
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(id: 'jsException').click
    expect(log_entries).to be_empty
  end
end
```

```py
    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/test_bidi_logging.py#L23-24)

##### /examples/python/tests/bidi/test\_bidi\_logging.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_console_message_handler(log_entries.append)

    driver.find_element(By.ID, "consoleLog").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Hello, world!"


@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0


@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_javascript_error_handler(log_entries.append)

    driver.find_element(By.ID, "jsException").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Error: Not working"


@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    log_entries = []
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/logging_spec.rb#L22-L23)

##### /examples/ruby/spec/bidi/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_console_message_handler { |log| log_entries << log }

    driver.find_element(id: 'consoleLog').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Hello, world!'
  end

  it 'removes console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_console_message_handler { |log| log_entries << log }
    driver.script.remove_console_message_handler(id)

    driver.find_element(id: 'consoleLog').click
    expect(log_entries).to be_empty
  end

  it 'adds JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_javascript_error_handler { |error| log_entries << error }

    driver.find_element(id: 'jsException').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Error: Not working'
  end

  it 'removes JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_javascript_error_handler { |error| log_entries << error }
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(id: 'jsException').click
    expect(log_entries).to be_empty
  end
end
```

```py
    driver.script.add_javascript_error_handler(log_entries.append)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/test_bidi_logging.py#L35)

##### /examples/python/tests/bidi/test\_bidi\_logging.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_console_message_handler(log_entries.append)

    driver.find_element(By.ID, "consoleLog").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Hello, world!"


@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0


@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_javascript_error_handler(log_entries.append)

    driver.find_element(By.ID, "jsException").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Error: Not working"


@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    log_entries = []
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/logging_spec.rb#L33)

##### /examples/ruby/spec/bidi/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_console_message_handler { |log| log_entries << log }

    driver.find_element(id: 'consoleLog').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Hello, world!'
  end

  it 'removes console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_console_message_handler { |log| log_entries << log }
    driver.script.remove_console_message_handler(id)

    driver.find_element(id: 'consoleLog').click
    expect(log_entries).to be_empty
  end

  it 'adds JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_javascript_error_handler { |error| log_entries << error }

    driver.find_element(id: 'jsException').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Error: Not working'
  end

  it 'removes JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_javascript_error_handler { |error| log_entries << error }
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(id: 'jsException').click
    expect(log_entries).to be_empty
  end
end
```

```py
    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/test_bidi_logging.py#L47-48)

##### /examples/python/tests/bidi/test\_bidi\_logging.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_console_message_handler(log_entries.append)

    driver.find_element(By.ID, "consoleLog").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Hello, world!"


@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0


@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_javascript_error_handler(log_entries.append)

    driver.find_element(By.ID, "jsException").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Error: Not working"


@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    log_entries = []
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/logging_spec.rb#L44-L45)

##### /examples/ruby/spec/bidi/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_console_message_handler { |log| log_entries << log }

    driver.find_element(id: 'consoleLog').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Hello, world!'
  end

  it 'removes console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_console_message_handler { |log| log_entries << log }
    driver.script.remove_console_message_handler(id)

    driver.find_element(id: 'consoleLog').click
    expect(log_entries).to be_empty
  end

  it 'adds JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_javascript_error_handler { |error| log_entries << error }

    driver.find_element(id: 'jsException').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Error: Not working'
  end

  it 'removes JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_javascript_error_handler { |error| log_entries << error }
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(id: 'jsException').click
    expect(log_entries).to be_empty
  end
end
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

最終更新 October 18, 2024: [add missing pages for netowrk and logging (670665592ab)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/670665592ab989df69a847b0ca71d1e081c3138f)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/troubleshooting/logging/
----

# Logging Selenium commands

```java
    public void logging() throws IOException {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Java Logging is not exactly straightforward, and if you are just looking for an easy way to look at the important Selenium logs, take a look at the [Selenium Logger project](https://github.com/titusfortner/selenium-logger#selenium-logger)

Python logs are typically created per module. You can match all submodules by referencing the top level module. So to work with all loggers in selenium module, you can do this:

```py
    logger = logging.getLogger('selenium')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L5)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

You must also create and add a log handler (`StreamHandler`, `FileHandler`, etc).

To save logs to a file, you can do this:

```py
log_path = '/path/to/log'
handler = logging.FileHandler(log_path)
logger.addHandler(handler)
```

To display logs in the console, you can do this:

```py
handler = logging.StreamHandler()
logger.addHandler(handler)
```

.NET logger is managed with a static class, so all access to logging is managed simply by referencing `Log` from the `OpenQA.Selenium.Internal.Logging` namespace.

If you want to see as much debugging as possible in all the classes, you can turn on debugging globally in Ruby by setting `$DEBUG = true`.

For more fine-tuned control, Ruby Selenium created its own Logger class to wrap the default `Logger` class. This implementation provides some interesting additional features. Obtain the logger directly from the `#logger`class method on the `Selenium::WebDriver` module:

```rb
    logger = Selenium::WebDriver.logger
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L11)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

```javascript
const logging = require('selenium-webdriver/lib/logging')
logger = logging.getLogger('webdriver')
```

```java
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L32-L35)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Python has 6 logger levels: `CRITICAL`, `ERROR`, `WARNING`, `INFO`, `DEBUG`, and `NOTSET`. The default is `WARNING`

To change the level of the logger:

```py
    logger.setLevel(logging.DEBUG)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L7)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

Things get complicated when you use PyTest, though. By default, PyTest hides logging unless the test fails. You need to set 3 things to get PyTest to display logs on passing tests.

To always output logs with PyTest you need to run with additional arguments. First, `-s` to prevent PyTest from capturing the console. Second, `-p no:logging`, which allows you to override the default PyTest logging settings so logs can be displayed regardless of errors.

So you need to set these flags in your IDE, or run PyTest on command line like:

```bash
pytest -s -p no:logging
```

Finally, since you turned off logging in the arguments above, you now need to add configuration to turn it back on:

```py
logging.basicConfig(level=logging.WARN)
```

.NET has 6 logger levels: `Error`, `Warn`, `Info`, `Debug`, `Trace` and `None`. The default level is `Warn`.

To change the level of the logger:

```cs
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L18)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

Ruby logger has 5 logger levels: `:debug`, `:info`, `:warn`, `:error`, `:fatal`. As of Selenium v4.9.1, The default is `:info`.

To change the level of the logger:

```rb
    logger.level = :debug
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L13)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

JavaScript has 9 logger levels: `OFF`, `SEVERE`, `WARNING`, `INFO`, `DEBUG`, `FINE`, `FINER`, `FINEST`, `ALL`. The default is `OFF`.

To change the level of the logger:

```javascript
logger.setLevel(logging.Level.INFO)
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
WARNING: this is a warning
```

Python logs actionable content at logger level — `WARNING` Details about deprecations are logged at this level.

Example:

```text
WARNING  selenium:test_logging.py:23 this is a warning
```

.NET logs actionable content at logger level `Warn`.

Example:

```text
11:04:40.986 WARN LoggingTest: this is a warning
```

Ruby logs actionable content at logger level — `:warn`. Details about deprecations are logged at this level.

For example:

```text
2023-05-08 20:53:13 WARN Selenium [:example_id] this is a warning 
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
INFO: this is useful information
```

Python logs useful information at logger level — `INFO`

Example:

```text
INFO     selenium:test_logging.py:22 this is useful information
```

.NET logs useful information at logger level `Info`.

Example:

```text
11:04:40.986 INFO LoggingTest: this is useful information
```

Ruby logs useful information at logger level — `:info`.

Example:

```text
2023-05-08 20:53:13 INFO Selenium [:example_id] this is useful information 
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
FINE: this is detailed debug information
```

Python logs debugging details at logger level — `DEBUG`

Example:

```text
DEBUG    selenium:test_logging.py:24 this is detailed debug information
```

.NET logs most debug content at logger level `Debug`.

Example:

```text
11:04:40.986 DEBUG LoggingTest: this is detailed debug information
```

Ruby only provides one level for debugging, so all details are at logger level — `:debug`.

Example:

```text
2023-05-08 20:53:13 DEBUG Selenium [:example_id] this is detailed debug information 
```

```java

      Path output = artifactsDir().resolve("selenium.xml");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L37-L38)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

By default all logs are sent to `sys.stderr`. To direct output somewhere else, you need to add a handler with either a `StreamHandler` or a `FileHandler`:

```py
    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L9-L10)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

By default all logs are sent to `System.Console.Error` output. To direct output somewhere else, you need to add a handler with a `FileLogHandler`:

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L20)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

By default, logs are sent to the console in `stdout`.\
To store the logs in a file:

```rb
    logger.output = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L15)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

JavaScript does not currently support sending output to a file.

To send logs to console output:

```javascript
logging.installConsoleHandler()
```

```java
        logger.addHandler(handler);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L40-L41)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Because logging is managed by module, instead of working with just "selenium", you can specify different levels for different modules:

```py
    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L12-L13)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

.NET logging is managed on a per class level, set the level you want to use on a per-class basis:

```cs

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

Ruby’s logger allows you to opt in (“allow”) or opt out (“ignore”) of log messages based on their IDs. Everything that Selenium logs includes an ID. You can also turn on or off all deprecation notices by using `:deprecations`.

These methods accept one or more symbols or an array of symbols:

```rb
    logger.ignore(:jwp_caps, :logger_info)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L17)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

or

```rb
    logger.allow(%i[selenium_manager example_id])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L18)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

Última modificação August 13, 2025: [\[dotnet\] Change default internal log level to Warn (#2409) (22fad037ea6)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/22fad037ea6c457abc65c64d37d6c299bde40a4d)

----
url: https://www.selenium.dev/documentation/test_practices/encouraged/fresh_browser_per_test/
----

# Fresh browser per test

Start each test from a clean, known state. Ideally, spin up a new virtual machine for each test. If spinning up a new virtual machine is not practical, at least start a new WebDriver for each test. Most browser drivers like GeckoDriver and ChromeDriver will start with a clean known state with a new user profile, by default.

```java
WebDriver driver = new FirefoxDriver();
```

Last modified September 4, 2022: [Overview spelling, punctuation fixes (#1156) (6b87463b637)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/6b87463b63700d38146e82130776bf4d832bf82d)

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/testing_types/
----

# Tipos de teste

### Teste de aceitação

Este tipo de teste é feito para determinar se um recurso ou sistema atende às expectativas e requisitos do cliente. Este tipo de teste geralmente envolve cooperação ou feedback do cliente, sendo uma atividade de validação que responde a pergunta:

> Estamos construindo o produto ***certo***?.

Para aplicações web, a automação desse teste pode ser feita diretamente com o Selenium, simulando o comportamento esperado do usuário. Esta simulação pode ser feita por gravação / reprodução ou por meio dos diferentes idiomas suportados, conforme explicado nesta documentação. Observação: o teste de aceitação é um subtipo de ***teste funcional***, ao qual algumas pessoas também podem se referir.

### Teste funcional

Este tipo de teste é feito para determinar se um recurso ou sistema funciona corretamente sem problemas. Verifica o sistema em diferentes níveis para garantir que todos os cenários são cobertos e que o sistema faz *o que está* suposto fazer. É uma atividade de verificação que responde a pergunta:

> Estamos construindo o produto ***corretamente?***.

Isso geralmente inclui: os testes funcionam sem erros (404, exceções …), de forma utilizável (redirecionamentos corretos), de forma acessível e atendendo às suas especificações (consulte ***teste de aceitação*** acima).

Para aplicativos da web, a automação desse teste pode ser feito diretamente com o Selenium, simulando os retornos esperados. Esta simulação pode ser feita por gravação / reprodução ou por meio de os diferentes idiomas suportados, conforme explicado nesta documentação.

### Testes de Integração

Os testes de integração verificam as interações entre diferentes componentes ou módulos de um sistema. Vários módulos são testados juntos. O objetivo dos testes de integração é garantir que todos os módulos se integrem e funcionem juntos conforme esperado. Os testes de integração automatizados ajudam a garantir que essas interações funcionem conforme o esperado e que os componentes integrados funcionem corretamente juntos.

> Por exemplo, ***Testando o fluxo de pedido de um item em um site de comércio eletrônico junto com o pagamento.***

### Testes de sistema

O System Testing é um teste de produto completo e totalmente integrado. É um teste ponta a ponta onde o ambiente de teste é semelhante ao ambiente de produção. Aqui, navegamos por todos os recursos do software e testamos se o negócio final/recurso final funciona. Apenas testamos o recurso final e não verificamos o fluxo de dados, nem fazemos testes funcionais e tudo mais.

> Por exemplo, ***Testando o fluxo de ponta a ponta desde o login até a colocação e pedido e verificando novamente o pedido na página Meus Pedidos e logoff de um site de comércio eletrônico.***

### Teste de performance/desempenho

Como o próprio nome indica, testes de desempenho são feitos para medir o desempenho de um aplicativo.

Existem dois subtipos principais para testes de desempenho:

#### Teste de carga

O teste de carga é feito para verificar o quão bem o aplicativo funciona sob diferentes cargas definidas (geralmente um determinado número de usuários conectados ao mesmo tempo).

> For example, ***Testing that the site can handle numerous orders/users at once.***

#### Teste de estresse

O teste de estresse é feito para verificar o quão bem a aplicação funciona sob estresse (ou acima da carga máxima suportada).

> For example, ***Testing that your ecommerce site can handle Black Friday***

> For example, ***Testing that your new search bar doesn’t break the other buttons on the menu***

Última modificação March 9, 2025: [Added more examples to testing type descriptions (#1970)\[deploy site\] (9f7a22b43fc)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/9f7a22b43fcd2d4158aa007d622c9a6d7bf4ca6b)

----
url: https://www.selenium.dev/zh-cn/documentation/overview/components/
----

# 了解组件

最后修改 October 29, 2025: [Robotium does not support natural language features. Robot Framework … (#2508) (9667de56d4f)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/9667de56d4f85dfa29d81741893570c0b7ae4cdd)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/http_client/
----

# HTTP Client Configuration

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import org.openqa.selenium.remote.http.ClientConfig;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import java.io.FileInputStream;
import java.net.URL;
import java.nio.file.Path;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.time.Duration;

import org.openqa.selenium.UsernameAndPassword;

import static java.net.http.HttpClient.Version.HTTP_1_1;

public class HttpClientTest extends BaseTest {
    URL gridUrl;

    @BeforeEach
    public void startGrid() {
        gridUrl = startStandaloneGridAdvanced();
    }

    @Test
    public void remoteWebDriverWithClientConfig() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createSSLContextWithCA(Path.of("src/test/resources/tls.crt").toAbsolutePath().toString()))
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
    }

    @Test
    public void remoteWebDriverIgnoreSSL() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createIgnoreSSLContext())
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
    }

    @Test
    public void remoteWebDriverWithEmbedAuthUrl() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createSSLContextWithCA(Path.of("src/test/resources/tls.crt").toAbsolutePath().toString()))
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(embedAuthToUrl(gridUrl, "admin", "myStrongPassword"))
                .config(clientConfig)
                .build();
    }

    private URL embedAuthToUrl(URL url, String username, String password) throws Exception {
        String userInfo = username + ":" + password;
        String urlWithAuth = url.getProtocol() + "://" + userInfo + "@" + url.getHost() + ":" + url.getPort() + url.getPath();
        return new URL(urlWithAuth);
    }

    public static SSLContext createSSLContextWithCA(String caCertPath) throws Exception {
        FileInputStream fis = new FileInputStream(caCertPath);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate caCert = (X509Certificate) cf.generateCertificate(fis);
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, null);
        keyStore.setCertificateEntry("caCert", caCert);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(keyStore);
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);
        return sslContext;
    }

    public static SSLContext createIgnoreSSLContext() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    }
                }
        };
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
        return sslContext;
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/HttpClientTest.java)

```py
import os
import pytest
import sys
from urllib3.util import Retry, Timeout
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType
from selenium.webdriver.remote.client_config import ClientConfig


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_with_client_config(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    retries = Retry(connect=2, read=2, redirect=2)
    timeout = Timeout(connect=300, read=3600)
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 init_args_for_pool_manager={
                                     "init_args_for_pool_manager": {"retries": retries, "timeout": timeout}},
                                 ca_certs=_get_resource_path("tls.crt"),
                                 username="admin", password="myStrongPassword")
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_ignore_certs(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 timeout=3600,
                                 ignore_certificates=True,
                                 username="admin", password="myStrongPassword")
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


def _get_resource_path(file_name: str):
    if os.path.abspath("").endswith("tests"):
        path = os.path.abspath(f"resources/{file_name}")
    else:
        path = os.path.abspath(f"tests/resources/{file_name}")
    return path

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_http_client.py)

[Add Example](/documentation/about/contributing/#creating-examples)

```rb

  it 'sets client configuration' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/http_client_spec.rb#L7-L8)

##### /examples/ruby/spec/drivers/http\_client\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'HTTP Client' do
  let(:url) { 'https://www.selenium.dev/selenium/web/' }

  it 'sets client configuration' do
    client = Selenium::WebDriver::Remote::Http::Default.new(open_timeout: 30, read_timeout: 30)
    expect(client.open_timeout).to eq 30
  end

  it 'uses the custom http client' do
    client = Selenium::WebDriver::Remote::Http::Default.new
    driver = Selenium::WebDriver.for :chrome, http_client: client
    driver.get(url)
    driver.quit
  end
end
```

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/troubleshooting/upgrade_to_selenium_4/
----

# 升级到Selenium 4

```java
DesiredCapabilities caps = DesiredCapabilities.firefox();
caps.setCapability("platform", "Windows 10");
caps.setCapability("version", "92");
caps.setCapability("build", myTestBuild);
caps.setCapability("name", myTestName);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), caps);
```

```javascript
caps = {};
caps['browserName'] = 'Firefox';
caps['platform'] = 'Windows 10';
caps['version'] = '92';
caps['build'] = myTestBuild;
caps['name'] = myTestName;
```

```csharp
DesiredCapabilities caps = new DesiredCapabilities();
caps.SetCapability("browserName", "firefox");
caps.SetCapability("platform", "Windows 10");
caps.SetCapability("version", "92");
caps.SetCapability("build", myTestBuild);
caps.SetCapability("name", myTestName);
var driver = new RemoteWebDriver(new Uri(CloudURL), caps);
```

```rb
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L123-L130)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```python
caps = {}
caps['browserName'] = 'firefox'
caps['platform'] = 'Windows 10'
caps['version'] = '92'
caps['build'] = my_test_build
caps['name'] = my_test_name
driver = webdriver.Remote(cloud_url, desired_capabilities=caps)
```

```java
FirefoxOptions browserOptions = new FirefoxOptions();
browserOptions.setPlatformName("Windows 10");
browserOptions.setBrowserVersion("92");
Map<String, Object> cloudOptions = new HashMap<>();
cloudOptions.put("build", myTestBuild);
cloudOptions.put("name", myTestName);
browserOptions.setCapability("cloud:options", cloudOptions);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), browserOptions);
```

```javascript
capabilities = {
  browserName: 'firefox',
  browserVersion: '92',
  platformName: 'Windows 10',
  'cloud:options': {
     build: myTestBuild,
     name: myTestName,
  }
}
```

```csharp
var browserOptions = new FirefoxOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "92";
var cloudOptions = new Dictionary<string, object>();
cloudOptions.Add("build", myTestBuild);
cloudOptions.Add("name", myTestName);
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);
var driver = new RemoteWebDriver(new Uri(CloudURL), browserOptions);
```

```rb
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L38-L47)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```python
from selenium.webdriver.firefox.options import Options as FirefoxOptions
options = FirefoxOptions()
options.browser_version = '92'
options.platform_name = 'Windows 10'
cloud_options = {}
cloud_options['build'] = my_test_build
cloud_options['name'] = my_test_name
options.set_capability('cloud:options', cloud_options)
driver = webdriver.Remote(cloud_url, options=options)
```

### 在 Java 中查找元素工具方法

在 Java 绑定(`FindsBy` 接口)中 查找元素的工具方法已被删除 因为它们仅供内部使用.\
以下代码示例更好地解释了这一点.

使用 `findElement*` 查找单个元素

Before

```java

driver.findElementByClassName("className");
driver.findElementByCssSelector(".className");
driver.findElementById("elementId");
driver.findElementByLinkText("linkText");
driver.findElementByName("elementName");
driver.findElementByPartialLinkText("partialText");
driver.findElementByTagName("elementTagName");
driver.findElementByXPath("xPath");
```

After

```java

driver.findElement(By.className("className"));
driver.findElement(By.cssSelector(".className"));
driver.findElement(By.id("elementId"));
driver.findElement(By.linkText("linkText"));
driver.findElement(By.name("elementName"));
driver.findElement(By.partialLinkText("partialText"));
driver.findElement(By.tagName("elementTagName"));
driver.findElement(By.xpath("xPath"));
```

使用 `findElements*` 查找多个元素

Before

```java

driver.findElementsByClassName("className");
driver.findElementsByCssSelector(".className");
driver.findElementsById("elementId");
driver.findElementsByLinkText("linkText");
driver.findElementsByName("elementName");
driver.findElementsByPartialLinkText("partialText");
driver.findElementsByTagName("elementTagName");
driver.findElementsByXPath("xPath");
```

After

```java

driver.findElements(By.className("className"));
driver.findElements(By.cssSelector(".className"));
driver.findElements(By.id("elementId"));
driver.findElements(By.linkText("linkText"));
driver.findElements(By.name("elementName"));
driver.findElements(By.partialLinkText("partialText"));
driver.findElements(By.tagName("elementTagName"));
driver.findElements(By.xpath("xPath"));
```

```xml

<dependencies>
  <!-- more dependencies ... -->
  <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.141.59</version>
  </dependency>
  <!-- more dependencies ... -->
</dependencies>
```

After

```xml

<dependencies>
    <!-- more dependencies ... -->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.4.0</version>
    </dependency>
    <!-- more dependencies ... -->
</dependencies>
```

进行更改后, 您可以在`pom.xml` 文件的同一目录中 执行 `mvn clean compile` .

#### Gradle

Before

```jsonpath

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter: junit-jupiter-api: 5.7.0'
    testRuntimeOnly 'org.junit.jupiter: junit-jupiter-engine: 5.7.0'
    implementation group:  'org.seleniumhq.selenium', name:  'selenium-java', version:  '3.141.59'
}
test {
    useJUnitPlatform()
}
```

After

```jsonpath

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter: junit-jupiter-api: 5.7.0'
    testRuntimeOnly 'org.junit.jupiter: junit-jupiter-engine: 5.7.0'
    implementation group:  'org.seleniumhq.selenium', name:  'selenium-java', version:  '4.4.0'
}
test {
    useJUnitPlatform()
}
```

进行更改后, 您可以在 build.gradle 文件所在的同一目录中 执行`./gradlew clean build` .

要检查所有 Java 版本, 您可以前往 [MVNRepository](https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java) .

### C\#

在 C# 中获取 Selenium 4 更新的 地方是 [NuGet](https://www.nuget.org/) .\
在下面包 [`Selenium.WebDriver`](https://www.nuget.org/packages/Selenium.WebDriver/4.4.0) 你可以获得更新到最新版本的说明.\
在 Visual Studio 内部, 您可以通过 NuGet 包管理器执行：

```shell
PM> Install-Package Selenium.WebDriver -Version 4.4.0
```

### Python

使用 Python 的最重要变化是所需的最低版本. Selenium 4 将至少需要 Python 3.7 或更高版本.\
更多详细信息可以在 [Python 包索引](https://pypi.org/project/selenium/4.4.3/) .\
基于命令行做升级的话, 你可以执行:

```shell
pip install selenium==4.4.3
```

### Ruby

Selenium 4 的更新细节 可以在RubyGems中的gem发现 [selenium-webdriver](https://rubygems.org/gems/selenium-webdriver/versions/4.4.0) .\
要安装最新版本, 您可以执行:

```shell
gem install selenium-webdriver
```

将以下内容添加到你的Gemfile:

```shell
gem 'selenium-webdriver', '~> 4.4.0'
```

### JavaScript

可以在 Node 包管理器中找到 selenium-webdriver 包, [npmjs](https://www.npmjs.com) .\
Selenium 4 可以在 [这里](https://www.npmjs.com/package/selenium-webdriver/v/4.4.0) 找到.\
要安装, 你可以执行:

```shell
npm install selenium-webdriver
```

或者, 更新你的 package.json 并运行 `npm install` :

```json
{
  "name":  "selenium-tests",
  "version":  "1.0.0",
  "dependencies":  {
    "selenium-webdriver":  "^4.4.0"
  }
}
```

## 潜在错误和弃用消息

这是一组代码示例, 它们将有助于克服 您升级到 Selenium 4 后 可能会遇到的弃用消息.

### Java

#### 等待和超时

Timeout 中接收到的参数 已经从期望 `(long time, TimeUnit unit)` 切换到期待 `(Duration duration)` .

Before

```java

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(2, TimeUnit.MINUTES);
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
```

After

```java

driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().timeouts().scriptTimeout(Duration.ofMinutes(2));
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
```

等待现在也期望不同的参数. `WebDriverWait` 现在期待一个 `Duration` 而不是以秒和毫秒为单位的 `long` 超时. `FluentWait` 的工具方法 `withTimeout` 和 `pollingEvery` 已经从期望 `(long time, TimeUnit unit)` 切换到 期待`(Duration duration)` .

Before

```java

new WebDriverWait(driver, 3)
.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(30, TimeUnit.SECONDS)
  .pollingEvery(5, TimeUnit.SECONDS)
  .ignoring(NoSuchElementException.class);
```

After

```java

new WebDriverWait(driver, Duration.ofSeconds(3))
  .until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

  Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(Duration.ofSeconds(30))
  .pollingEvery(Duration.ofSeconds(5))
  .ignoring(NoSuchElementException.class);
```

#### 合并capabilities不再改变调用对象

曾经可以将一组不同的capabilities合并到另一组中, 并且改变调用对象.\
现在, 需要分配合并操作的结果.

Before

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options.merge(capabilities);

//作为结果, `options` 对象被修改
```

After

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options = options.merge(capabilities);

// `merge` 调用的结果需要分配给一个对象.
```

#### Firefox 遗留模式

在 GeckoDriver 出现之前, Selenium 项目有一个驱动程序实现来自动化 Firefox(版本 <48).\
但是, 不再需要此实现, 因为在最新版本的 Firefox 中它不起作用.\
为避免升级到 Selenium 4 时出现重大问题, `setLegacy`选项将显示为已弃用.\
建议停止使用旧的实现 并且只依赖 GeckoDriver.\
以下代码将显示在升级之后弃用的 `setLegacy` 行.

```java
FirefoxOptions options = new FirefoxOptions();
options.setLegacy(true);
```

#### `BrowserType`

`BrowserType` 接口已经存在很长时间了, 但是其已变为弃用 且推荐使用新的 `Browser` 接口.

Before

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", BrowserType.FIREFOX);
```

After

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", Browser.FIREFOX);
```

### C\#

#### `AddAdditionalCapability` 已弃用

推荐使用`AddAdditionalOption`替代.\
以下为一个示例:

Before

```cs

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalCapability("cloud: options", cloudOptions, true);
```

After

```cs

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalOption("cloud: options", cloudOptions);
```

### Python

#### `executable_path 已弃用, 请传递一个服务对象`

在Selenium 4中,\
您需要从服务对象设置驱动程序的 `可执行路径` , 以防止出现弃用警告. (或者不要设置路径, 而是确保所需的驱动程序位于系统路径上.)

Before

```python

from selenium import webdriver
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(
    executable_path=CHROMEDRIVER_PATH, 
    options=options
)
```

After

```python

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
options = webdriver.ChromeOptions()
service = ChromeService(executable_path=CHROMEDRIVER_PATH)
driver = webdriver.Chrome(service=service, options=options)
```

## 总结

我们已经过了升级到 Selenium 4 时要考虑的主要变化. 涵盖为升级准备测试代码时要涵盖的不同方面, 包括关于如何避免 使用Selenium新版本时 可能出现的潜在问题的建议.\
最后, 我们还介绍了一系列您可能会遇到的升级问题, 分享这些问题的潜在修复方案.

*本文最初发布于 <https://saucelabs.com/resources/articles/how-to-upgrade-to-selenium-4>*

----
url: https://www.selenium.dev/ja/documentation/test_practices/discouraged/gmail_email_and_facebook_logins/
----

# Gmail、Eメール、Facebookログイン

複数の理由から、WebDriverを使用してGmailやFacebookなどのサイトにログインすることはお勧めしません。 これらのサイトの使用条件（アカウントがシャットダウンされるリスクがある）に違反することは別として、それは遅く、信頼性がありません。

理想的なプラクティスは、メールプロバイダーが提供するAPIを使用すること、またはFacebookの場合、テストアカウントや友人などを作成するためのAPIを公開する開発者ツールサービスを使用することです。 APIの使用は少し大変な作業のように思えるかもしれませんが、速度、信頼性、および安定性に見返りがあります。 また、APIが変更されることはほとんどありませんが、WebページとHTMLロケーターは頻繁に変更され、テストフレームワークを更新する必要があります。

テストの任意の時点でWebDriverを使用してサードパーティのサイトにログインすると、テストが長くなるため、テストが失敗するリスクが高くなります。 一般的な経験則として、テストが長くなるほど脆弱で信頼性が低くなります。

[W3C準拠](//w3c.github.io/webdriver/webdriver-spec.html) のWebDriver実装は、サービス拒否攻撃を軽減できるように、`navigator`オブジェクトに`WebDriver`プロパティで注釈を付けます。

----
url: https://www.selenium.dev/ja/documentation/legacy/selenium_ide/
----

# レガシー Selenium IDE

```html
<tr>
    <td>Command</td>
    <td>target (locator)</td>
    <td>Value</td>
</tr>
```

|            |              |       |
| ---------- | ------------ | ----- |
| verifyText | //div//a\[2] | Login |

パラメーターは必ずしも必要ではありません。 コマンドに依存します。 両方のパラメータが必要な場合もあれば、1つのパラメータが必要な場合もあります。 また、コマンドがパラメータをまったく受け取らない場合もあります。 ここにいくつかの例があります。

|                   |             |                         |
| ----------------- | ----------- | ----------------------- |
| goBackAndWait     |             |                         |
| verifyTextPresent |             | Welcome to My Home Page |
| type              | id=phone    | (555) 666-7066          |
| type              | id=address1 | ${myVariableAddress}    |

```html
<table>
    <tr><td>open</td><td>/download/</td><td></td></tr>
    <tr><td>assertTitle</td><td></td><td>Downloads</td></tr>
    <tr><td>verifyText</td><td>//h2</td><td>Downloads</td></tr>
</table>
```

ブラウザでテーブルとしてレンダリングされると、次のようになります。

|             |            |           |
| ----------- | ---------- | --------- |
| open        | /download/ |           |
| assertTitle |            | Downloads |
| verifyText  | //h2       | Downloads |

The Selenese HTML syntax can be used to write and run tests without requiring knowledge of a programming language. With a basic knowledge of selenese and Selenium-IDE you can quickly produce and run testcases.

## テストスイート

テストスイートは、テストのコレクションです。 多くの場合、テストスイート内のすべてのテストを1つの連続バッチジョブとして実行します。

Selenium-IDEを使用する場合、テストスイートは単純なHTMLファイルを使用して定義することもできます。 構文も簡単です。 HTMLテーブルはテストのリストを定義し、各行は各テストへのファイルシステムパスを定義します。 例ですべてがわかります。

```html
<html>
<head>
<title>Test Suite Function Tests - Priority 1</title>
</head>
<body>
<table>
  <tr><td><b>Suite Of Tests</b></td></tr>
  <tr><td><a href="./Login.html">Login</a></td></tr>
  <tr><td><a href="./SearchValues.html">Test Searching for Values</a></td></tr>
  <tr><td><a href="./SaveValues.html">Test Save</a></td></tr>
</table>
</body>
</html>
```

| Command     | Target     | Value        |
| ----------- | ---------- | ------------ |
| open        | /download/ |              |
| assertTitle |            | Downloads    |
| verifyText  | //h2       | Downloads    |
| assertTable | 1.2.1      | Selenium IDE |
| verifyTable | 1.2.2      | June 3, 2008 |
| verifyTable | 1.2.3      | 1.0 beta 2   |

上記の例では、最初にページを開き、次にタイトルを期待値と比較することで正しいページがロードされることを“アサート”します。 これが成功した場合にのみ、次のコマンドが実行され、テキストが予想される場所に存在することを“検証”します。 テストケースは、最初のテーブルの2行目の最初の列に期待値が含まれていることを“アサート”します。 これに合格した場合にのみ、その行の残りのセルが“検証”されます。

### **verifyTextPresent**

`verifyTextPresent` コマンドは、 特定のテキストがページ上のどこかに存在することを検証するのに使います。 このコマンドは引数を 1 つだけ取ります。 引数には、検証するテキストのパターンを指定します。 次に例を示します。

| Command           | Target             | Value |
| ----------------- | ------------------ | ----- |
| verifyTextPresent | Marketing Analysis |       |

この例では、現在テストの対象になっているページ上で “Marketing Analysis” というテキスト文字列を探し、この文字列がページ上のどこかにあるかどうかを検証します。 verifyTextPresent コマンドは、テキストそれ自体がページ上に存在するかどうかだけを調べるときに使います。 テキストがページ上に現れる場所もテストの対象に含める必要がある場合には、このコマンドは使わないでください。

### **verifyElementPresent**

このコマンドは、特定の UI 要素について、その内容ではなく、要素の存在自体をチェックするのに使います。 具体的にはテキストはチェックせず、HTML タグだけをチェックします。 一般的な使い方として、画像が存在するかどうかのチェックなどがあります。

| Command              | Target      | Value |
| -------------------- | ----------- | ----- |
| verifyElementPresent | //div/p/img |       |

この例では、\<img> HTML タグの存在によって指定される画像が、ページ上に存在するかどうか、そして \<img> タグが \<div> タグと \<p> タグに続いて出現するかどうかを検証しています。 最初の (1 つだけの) パラメータは、要素を探す方法を Selenese コマンドに指示するための ロケータ です。 ロケータについては、次のセクションで説明します。

`verifyElementPresent`を使用して、ページ内のHTMLタグの存在を確認できます。 リンク、段落、分割 \<div>などの存在を確認できます。 さらにいくつかの例を示します。

| Command              | Target                        | Value |
| -------------------- | ----------------------------- | ----- |
| verifyElementPresent | //div/p                       |       |
| verifyElementPresent | //div/a                       |       |
| verifyElementPresent | id=Login                      |       |
| verifyElementPresent | link=Go to Marketing Research |       |
| verifyElementPresent | //a\[2]                       |       |
| verifyElementPresent | //head/title                  |       |

これらの例は、UI要素をテストするさまざまな方法を示しています。 繰り返しになりますが、ロケータについては次のセクションで説明します。

### **verifyText**

テキストとそのUI要素の両方をテストする必要がある場合は、`verifyText`を使用します。 verifyTextはロケーターを使用する必要があります。 *XPath* ロケーターまたは *DOM* ロケーターを選択した場合、特定のテキストが、ページ上のほかの UI コンポーネントとの相対位置で指定される特定の場所に出現するかどうかを検証できます。

| Command    | Target              | Value                                                               |
| ---------- | ------------------- | ------------------------------------------------------------------- |
| verifyText | //table/tr/td/div/p | This is my text and it occurs right after the div inside the table. |

## 要素の特定

多くの Selenium コマンドでは、対象を指定する必要があります。 この対象は、Web アプリケーションのコンテキスト内で要素を特定するためのもので、ロケーションストラテジーに続けて、 `locatorType=location` の形でロケーションを指定します。 多くの場合、ロケーションのタイプは省略できます。 ロケーションのタイプについては、以下で例を挙げながら説明します。

### 識別子による特定

この方法は、要素を特定する方法としておそらく最も一般的で、ロケータタイプとして認識されるものが使われていない場合の汎用デフォルトです。 このストラテジーでは、id 属性を持つ要素のうち、ロケーションに一致する最初の要素が使われます。 id 属性に一致する要素がない場合には、name 属性を持つ要素のうち、ロケーションに一致する最初の要素が使われます。

たとえば、ページソースに次のような id 属性と name 属性があったとします。

```html
  <html>
   <body>
    <form id="loginForm">
     <input name="username" type="text" />
     <input name="password" type="password" />
     <input name="continue" type="submit" value="Login" />
    </form>
   </body>
  <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
    </body>
   <html>
```

* `id=loginForm` (3)

### Nameによる特定

name ロケータタイプは、name 属性に一致する最初の要素を特定します。 1つの name 属性に対して、複数の要素が同じ値を持っている場合には、フィルタを使ってロケーションストラテジーの精度を高めることができます。 デフォルトのフィルタタイプは value です (value 属性に一致)。

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
  <html>
   <body>
    <p>Are you sure you want to do this?</p>
    <a href="continue.html">Continue</a> 
    <a href="cancel.html">Cancel</a>
  </body>
  <html>
```

* `link=Continue` (4)
* `link=Cancel` (5)

### DOMによる特定

ドキュメントオブジェクトモデルはHTMLドキュメントを表し、JavaScriptを使用してアクセスできます。 このロケーションストラテジーでは、ページ上の要素に評価される JavaScript を使用します。 単に階層型ドット記法を使って要素の位置を特定できます。

“document” で始まるのは `dom` ロケーターだけなので、DOMロケーターを指定するときに `dom=` ラベルを含める必要はありません。

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input class="required" name="username" type="text" />
      <input class="required passfield" name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | glob:\*Film\*Television\*             |       |

リンクをクリックして表示されるページの実際のタイトルは “De Anza Film And Television Department - Menu” でした。正確に一致するテキストではなく、パターンを使うと、ページのタイトルに “Film” と “Television” の 2 つの単語が (この順序で) 出現する限り、 `verifyTitle` はパスします。 たとえば、ページのオーナーがタイトルを短縮して “Film & Television Department” としても、テストはパスします。リンクとリンクが動作するかどうかのテスト (上の例では `verifyTitle`) との両方でパターンを使うことで、こうしたテストケースの保守の手間を大幅に減らすことができます。

#### 正規表現パターン

*正規表現* パターンは、Selenese がサポートしている 3 種類のパターンの中で最も強力です。 正規表現はほとんどの高水準プログラミング言語、多くのテキストエディタ、さらに Linux/Unix のコマンドラインユーティリティである **grep** や **sed** 、 **awk** など、さまざまなツールでもサポートされています。 Selenese では、正規表現パターンを使うと、それ以外の方法では実現が難しい数多くのタスクを実行することができます。 たとえば、テーブルの特定のセルに入力されているのが数字だけかどうかをテストする必要があるとします。 この場合、 `regexp: [0-9]+` と指定するだけで、任意の長さの数字に一致させることができます。

Selenese のグロビングパターンでサポートしているのは **\*** と **\[ ]** (文字クラス) だけですが、Selenese の正規表現パターンでは JavaScript に存在するものと同じ幅広い特殊文字を使用できます。 次に示すのは、これらの特殊文字です。

| PATTERN | MATCH                                                                            |
| ------- | -------------------------------------------------------------------------------- |
| .       | any single character                                                             |
| \[ ]    | character class: any single character that appears inside the brackets           |
| \*      | quantifier: 0 or more of the preceding character (or group)                      |
| +       | quantifier: 1 or more of the preceding character (or group)                      |
| ?       | quantifier: 0 or 1 of the preceding character (or group)                         |
| {1,5}   | quantifier: 1 through 5 of the preceding character (or group)                    |
| \|      | alternation: the character/group on the left or the character/group on the right |
| ( )     | grouping: often used with alternation and/or quantifier                          |

Selenese の正規表現パターンでは、先頭に `regexp:` または `regexpi:` を付ける必要があります。 前者は大文字と小文字を区別しますが、後者は大文字と小文字を区別しません。

Selenese コマンドでの正規表現パターンの使い方については、いくつか実例を挙げた方がわかりやすいでしょう。 最初の例は、おそらく最もよく使われる正規表現である **.\*** (“ドットスター”) を使ったものです。 この 2 文字の並びは、「任意の文字の 0 回以上の繰り返し」、もっとかみくだいて言えば、「すべて、または何もない」ものに一致します。1 文字のグロビングパターンで **\*** (アスタリスク 1 つ) と指定するのと等価です。

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | regexp:.\*Film.\*Television.\*        |       |

上のテスト例は、すでに示したグロビングパターンを使ったテストの例と機能的には同じです。 違いは、プリフィックス (**glob:** の代わりに **regexp:** が使われていること) と、「すべて、または何もない」パターンが指定されていること ( **\*** の代わりに **.\*** が使われていること) だけです。

次に示すのは、アラスカ州アンカレジの日の出時刻に関する情報が掲載されている Yahoo! Weather のページを対象としたもう少し複雑なテスト例です。

| Command           | Target                                            | Value |
| ----------------- | ------------------------------------------------- | ----- |
| open              | <http://weather.yahoo.com/forecast/USAK0012.html> |       |
| verifyTextPresent | regexp:Sunrise: \*\[0-9]{1,2}:\[0-9]{2} \[ap]m    |       |

上の例で使われている正規表現を 1 つずつ見てみましょう。

|              |                                       |
| ------------ | ------------------------------------- |
| `Sunrise: *` | **Sunrise:** という文字列とそれに続く 0 個以上の空白    |
| `[0-9]{1,2}` | 1 個または 2 個の数字 (時間を表す)                 |
| `:`          | 文字 : そのもの (特殊文字は使われていない)              |
| `[0-9]{2}`   | 2 個の数字 (分を表す) とそれに続く 1 個の空白           |
| `[ap]m`      | 文字 “a” または “p” とそれに続く “m” (am または pm) |

#### 完全一致

Selenium の **完全一致** パターンは、それほど使う機会はないでしょう。 完全一致パターンでは、特殊文字は一切使いません。 したがって、(グロビングパターンと正規表現パターンでは特別な意味を持つ) アスタリスク文字を検索する必要がある場合には、完全一致パターンを使うのも 1 つの方法です。 たとえば、ドロップダウンリストで “Real \*” というラベルの付いた項目を選択する場合、次のようなコードでは、期待どおりに動作する場合もそうでない場合もあります。 `glob:Real *`パターンに含まれるアスタリスクは、「すべて、または何もない」ものに一致します。 したがって、目的の select のオプションより前に “Real Numbers” というラベルの付いたオプションがあれば、それが選択され、目的の “Real \*” というオプションは選択されないことになります。

| Command | Target   | Value        |
| ------- | -------- | ------------ |
| select  | //select | glob:Real \* |

項目 “Real \*” が確実に選択されるようにするには、 `exact:` プリフィックスを使って次のように **完全一致** パターンを指定します。

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| select  | //select | exact:Real \* |

ただし、正規表現パターンで次のようにアスタリスクをエスケープしても同じ結果が得られます。

| Command | Target   | Value            |
| ------- | -------- | ---------------- |
| select  | //select | regexp:Real \\\* |

| Command | Target            | Value |
| ------- | ----------------- | ----- |
| store   | <paul@mysite.org> |       |

上のように記述すると、スクリプトのあとの方で、変数に格納された値を利用できます。 変数の値にアクセスするには、次に示すように、変数をブレース ({}) で囲み、先頭にドル記号を付けます。

| Command    | Target  | Value         |
| ---------- | ------- | ------------- |
| verifyText | //div/p | \\${userName} |

変数の一般的な使い方の 1 つに、入力フィールドへの入力を格納する操作があります。

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| type    | id=login | \\${userName} |

| Command         | Target                                         | Value       |
| --------------- | ---------------------------------------------- | ----------- |
| store           | 10                                             | hits        |
| storeXpathCount | //blockquote                                   | blockquotes |
| storeEval       | storedVars\[‘hits’].storedVars\[‘blockquotes’] | paragraphs  |

次に示すのは、JavaScript コードの断片でメソッドを呼び出す例です。 この例では、JavaScript String オブジェクトの `toUpperCase` メソッドと `toLowerCase` メソッドを呼び出しています。

| Command   | Target                            | Value |
| --------- | --------------------------------- | ----- |
| store     | Edith Wharton                     | name  |
| storeEval | storedVars\[’name’].toUpperCase() | uc    |
| storeEval | storedVars\[’name’].toUpperCase() | lc    |

#### 非スクリプトパラメータでの JavaScript の使用

コマンドが取るパラメータの種類が **スクリプト** ではない場合でも、パラメータに使う値を JavaScript を使って生成することができます。 ただし、この場合には特別な構文が必要になり、JavaScript コードの断片をブレースで囲み、その前にラベル javascript を付ける必要があります。 具体的には、 `javascript {*ここにコードを記述*}` のように指定します。 次に示すのは、 `type` コマンドの 2 番目のパラメータ `value` を、特別な構文を使って JavaScript コードから生成する例です。

| Command | Target            | Value                                                 |
| ------- | ----------------- | ----------------------------------------------------- |
| store   | league of nations | searchString                                          |
| type    | q                 | javascript{storedVars\[‘searchString’].toUpperCase()} |

## *echo* - Selenese の Print コマンド

Selenese には、テスト出力にテキストを書き込むことができる簡単なコマンドが用意されています。 このコマンドを使うと、テストの実行中に進捗状況を示す情報をコンソールに表示できるので便利です。 これらの情報を使えば、テスト結果のレポートに実行時の状況を埋め込むこともできるので、テストで問題が見つかったときに、ページ上のどこにバグがあるのか探すのに役立ちます。 また、echo 文を使うと、Selenium 変数の内容を出力できます。次に例を示します。

| Command | Target                    | Value |
| ------- | ------------------------- | ----- |
| echo    | Testing page footer now.  |       |
| echo    | Username is \\${userName} |       |

## 警告、ポップアップ、および複数のウィンドウ

次のようなページをテストしているとします。

```html
  <!DOCTYPE HTML>
  <html>
  <head>
    <script type="text/javascript">
      function output(resultText){
        document.getElementById('output').childNodes[0].nodeValue=resultText;
      }

      function show_confirm(){
        var confirmation=confirm("Chose an option.");
        if (confirmation==true){
          output("Confirmed.");
        }
        else{
          output("Rejected!");
        }
      }
      
      function show_alert(){
        alert("I'm blocking!");
        output("Alert is gone.");
      }
      function show_prompt(){
        var response = prompt("What's the best web QA tool?","Selenium");
        output(response);
      }
      function open_window(windowName){
        window.open("newWindow.html",windowName);
      }
      </script>
  </head>
  <body>

    <input type="button" id="btnConfirm" onclick="show_confirm()" value="Show confirm box" />
    <input type="button" id="btnAlert" onclick="show_alert()" value="Show alert" />
    <input type="button" id="btnPrompt" onclick="show_prompt()" value="Show prompt" />
    <a href="newWindow.html" id="lnkNewWindow" target="_blank">New Window Link</a>
    <input type="button" id="btnNewNamelessWindow" onclick="open_window()" value="Open Nameless Window" />
    <input type="button" id="btnNewNamedWindow" onclick="open_window('Mike')" value="Open Named Window" />

    <br />
    <span id="output">
    </span>
  </body>
  </html>
```

ユーザーは、アラート/確認ボックスに応答するとともに、新しく開いたポップアップウィンドウにフォーカスを移動する必要があります。 幸いなことに、SeleniumはJavaScriptポップアップをカバーできます。

ただし、アラート/確認/プロンプトを個別に詳細に説明する前に、それらの共通点を理解しておくと役立ちます。 アラート、確認ボックス、プロンプトにはすべて次のバリエーションがあります。

| Command                   | Description                          |
| ------------------------- | ------------------------------------ |
| assertFoo(pattern)        | パターンがポップアップのテキストと一致しない場合、エラーをスローします  |
| assertFooPresent          | ポップアップが利用できない場合はエラーをスローします           |
| assertFooNotPresent       | ポップアップが存在する場合、エラーをスローします             |
| storeFoo(variable)        | ポップアップのテキストを変数に保存します                 |
| storeFooPresent(variable) | ポップアップのテキストを変数に保存し、trueまたはfalseを返します |

Seleniumで実行している場合、JavaScriptポップアップは表示されません。 これは、関数呼び出しが実行時に実際にSeleniumのJavaScriptによってオーバーライドされるためです。 ただし、ポップアップが表示されないからといって、ポップアップを処理する必要はありません。 ポップアップを処理するには、その `assertFoo(pattern)` 関数を呼び出す必要があります。 ポップアップの存在をアサートしないと、次のコマンドがブロックされ、次のようなエラーが表示されます。 `[エラー]エラー：予期しない確認がありました！ [オプションを選択してください。]`

### アラート

アラートは処理が最も簡単なポップアップなので、始めましょう。 まず、ブラウザで上記のHTMLサンプルを開き、“Show alert” ボタンをクリックします。 アラートを閉じると、“Alert is gone.” というテキストが表示されます。 ページに表示されます。 次に、Selenium IDE記録で同じ手順を実行し、アラートを閉じた後にテキストが追加されたことを確認します。 テストは次のようになります。

| Command           | Target         | Value |
| ----------------- | -------------- | ----- |
| open              | /              |       |
| click             | btnAlert       |       |
| assertAlert       | I’m blocking!  |       |
| verifyTextPresent | Alert is gone. |       |

あなたは「それはおかしい、私はそのアラートをアサートしようとしたことはない」と考えているかもしれません。 ただし、これはSelenium-IDEの処理であり、アラートを閉じます。 そのステップを削除してテストを再生すると、次のエラーが表示されます `[エラー]エラー：予期しないアラートがありました！ [I'm blocking!]` 。 アラートの存在を確認するには、アラートのアサーションを含める必要があります。

アラートが存在することをアサートしたいが、アラートに含まれるテキストがわからないか気にする必要がない場合は、`assertAlertPresent`を使うことができます。 これはtrueまたはfalseを返し、falseはテストを停止します。

### 確認

確認はアラートとほぼ同じように動作し、 `assertConfirmation` と `assertConfirmationPresent` は対応するアラートと同じ特性を提供します。 ただし、デフォルトでは、確認が表示されたときにSeleniumはOKを選択します。 サンプルページの"確認ダイアログを表示"ボタンをクリックして記録を試みますが、ポップアップの"キャンセル"ボタンをクリックして、出力テキストをアサートします。 テストは次のようになります。

| Command                        | Target            | Value |
| ------------------------------ | ----------------- | ----- |
| open                           | /                 |       |
| click                          | btnConfirm        |       |
| chooseCancelOnNextConfirmation |                   |       |
| assertConfirmation             | Choose an option. |       |
| verifyTextPresent              | Rejected          |       |

`chooseCancelOnNextConfirmation` 関数は、後続のすべての確認がfalseを返すことをSeleniumに伝えます。 chooseOkOnNextConfirmationを呼び出すことでリセットできます。

Seleniumは未処理の確認があると苦情を言うので、このテストを再生できないことに気付くかもしれません。 これは、Selenium-IDEが記録するイベントの順序により、クリックしてchooseCancelOnNextConfirmationが間違った順序になるためです（考えてみれば、Seleniumは、確認を開く前にキャンセルしていることを知ることができません）。 これら2つのコマンドを切り替えると、テストは正常に実行されます。

### プロンプト

プロンプトは、`assertPrompt` および `assertPromptPresent` が対応するアラートと同じ特性を提供することで、アラートとほぼ同じように動作します。 デフォルトでは、Seleniumはプロンプトがポップアップしたときにデータの入力を待機します。 サンプルページの “Show prompt” ボタンをクリックして記録を試み、プロンプトに “Selenium” と入力します。 テストは次のようになります。

| Command            | Target                       | Value |
| ------------------ | ---------------------------- | ----- |
| open               | /                            |       |
| answerOnNextPrompt | Selenium!                    |       |
| click              | id=btnPrompt                 |       |
| assertPrompt       | What’s the best web QA tool? |       |
| verifyTextPresent  | Selenium!                    |       |

```html
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Sample Selenium Test Suite</title>
    </head>
    <body>
        <table cellpadding="1" cellspacing="1" border="1">
            <thead>
                <tr><td>Test Cases for De Anza A-Z Directory Links</td></tr>
            </thead>
        <tbody>
            <tr><td><a href="./a.html">A Links</a></td></tr>
            <tr><td><a href="./b.html">B Links</a></td></tr>
            <tr><td><a href="./c.html">C Links</a></td></tr>
            <tr><td><a href="./d.html">D Links</a></td></tr>
        </tbody>
        </table>
    </body>
</html>
```

***

*error loading test case: no command found*

「ファイル」メニューの「開く」を使用して、テストスイートファイルを開こうとしました。 代わりに「ファイル」メニューの「テストスイートを開く」を使用してください。

このエラーメッセージを改善するために、機能の拡張がリクエストされました。 詳細は、[issue 1010](http://code.google.com/p/selenium/issues/detail?id=1010)を参照してください。

***

このタイプの **エラー** は、タイミングの問題を示している可能性があります。 つまり、コマンドのロケーターによって指定された要素が、コマンドの実行時に完全にロードされていません。 コマンドの前に **pause 5000** を入れて、問題が本当にタイミングに関連しているかどうかを判断してください。 その場合、失敗したコマンドの前に適切な **waitFor\*** または **\*AndWait** コマンドを使って調査してください。

***

上記の **open** コマンドの場合のように変数置換を使用しようとして失敗した場合は、アクセスしようとしている値を持つ変数を実際に作成していないことを示します。 これは、変数を **Target** フィールドに配置する必要がある場合に **Value** フィールドに配置するか、その逆の場合があります。 上記の例では、storeコマンドの2つのパラメーターが、必要なものと逆の順序で誤って配置されています。 Seleneseコマンドの場合、最初の必須パラメーターは **Target** フィールドに入力し、2番目の必須パラメーター（存在する場合）は **Value** フィールドに入力する必要があります。

***

*error loading test case: \[Exception… “Component returned failure code: 0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND) \[nsIFileInputStream.init]” nresult: “0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND)” location: “JS frame :: chrome://selenium-ide/content/file-utils.js :: anonymous :: line 48” data: no]*

テストスイートのテストケースの1つが見つかりません。 テストケースが配置されていることを示すテストスイートが実際に配置されていることを確認してください。 また、実際のテストケースファイルのファイル名と参照先のテストスイートファイルの両方に.html拡張子が付いていることを確認してください。

このエラーメッセージを改善するために、機能の拡張がリクエストされました。 詳細は、[issue 1011](http://code.google.com/p/selenium/issues/detail?id=1011)を参照してください。

***

拡張ファイルの内容が、Selenium-IDEによって読み取られていません。 Selenium-IDE の *“オプション” メニューで “設定” をクリックし、 “一般” タブ* の **Selenium Core 拡張スクリプト (user-extension.js) のパス** フィールドに適切なパス名を指定していることを確認してください。 また、 **Selenium Core 拡張スクリプト (user-extension.js) のパス** フィールドの内容を変更した後は、Selenium-IDEを再起動する必要があります。

***

##### [HTMLランナー](/ja/documentation/legacy/selenium_ide/html_runner/)

Execute HTML Selenium IDE exports from command line

最終更新 April 23, 2025: [fix: correct typo in name locator description in Japanese documentation (#2281) (58b2ba193ba)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/58b2ba193bad9bd0f9b0a741181c94364c6b8949)

----
url: https://www.selenium.dev/ja/documentation/grid/applicability/
----

# いつGridを使用すべきか

```
   15      *       45s        /        1        =      11m 15s   // Grid なし
   15      *       45s        /        5        =      2m 15s    // 5 ノードの Grid
   15      *       45s        /        15       =      45s       // 15 ノードの Grid
  100      *       120s       /        15       =      13m 20s   // Grid なしの場合3時間以上かかります
```

テストスイートが実行されると Grid はテストで設定されたブラウザに対して実行するテストを割り当てます。

このような設定により、大規模な Selenium テストスイートであっても実行時間を大幅に短縮することができます。

Selenium Grid は Selenium プロジェクトの一部であり、 Selenium コアの開発コミッターと同じチームによってメンテナンスされています。 テストの実行速度の重要性を認識し、Grid は Selenium プロジェクトの初期段階から重要な役割を担っています。

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/encouraged/test_independency/
----

# Independência de Testes

Escreva cada teste como sua própria unidade. Escreva os testes de uma forma que não seja dependente de outros testes para concluir:

Digamos que existe um sistema de gerenciamento de conteúdo com o qual você pode criar algum conteúdo personalizado que então aparece em seu site como um módulo após publicação, e pode levar algum tempo para sincronizar entre o CMS e a aplicação.

Uma maneira errada de testar seu módulo é que o conteúdo seja criado e publicado em um teste e, em seguida, verificar o módulo em outro teste. Este teste não é viável, pois o conteúdo pode não estar disponível imediatamente para o outro teste após a publicação.

Em vez disso, você pode criar um conteúdo stub que pode ser ligado e desligado dentro do teste e use-o para validar o módulo. Contudo, para a criação de conteúdo, você ainda pode ter um teste separado.

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/discouraged/performance_testing/
----

# 性能测试

通常不建议使用Selenium和WebDriver进行性能测试. 并非因为不能做, 只是缺乏针对此类工作的优化, 因而难以得到乐观的结果.

对于用户而言, 在用户上下文中执行性能测试似乎是自然而然的选择, 但是WebDriver的测试会受到许多外部和内部的影响而变得脆弱, 这是您无法控制的. 例如, 浏览器的启动速度, HTTP服务器的速度, 托管JavaScript或CSS的第三方服务器的响应 以及WebDriver实现本身检测的损失. 这些因素的变化会影响结果. 很难区分网站自身与外部资源之间的性能差异, 并且也很难明确浏览器中使用WebDriver对性能的影响, 尤其是在注入脚本时.

另一个潜在的吸引点是"节省时间"-同时执行功能和性能测试. 但是, 功能和性能测试分别具有截然不同的目标. 要测试功能, 测试人员可能需要耐心等待加载, 但这会使性能测试结果蒙上阴影, 反之亦然.

为了提高网站的性能, 您需要不依赖于环境的差异来分析整体性能, 识别不良代码的实践, 对单个资源 (即CSS或JavaScript) 的性能进行细分 以了解需要改进的地方. 有很多性能测试工具已经可以完成这项工作, 并且提供了报告和分析结果, 甚至可以提出改进建议.

例如一种易于使用的 (开源) 软件包是: [JMeter](/zh-cn/)

----
url: https://www.selenium.dev/zh-cn/documentation/about/style/
----

# Style guide for Selenium documentation

Conventions for contributions to the Selenium documentation and code examples

Read our [contributing documentation](https://www.selenium.dev/zh-cn/documentation/about/contributing/) for complete instructions on how to add content to this documentation.

## Alerts

Alerts have been added to direct potential contributors to where specific content is missing.

```html
{{< alert-content />}}
```

or

```html
{{< alert-content >}}
Additional information about what specific content is needed
{{< /alert-content >}}
```

```java
WebDriver driver = new ChromeDriver();
```

```python
driver = webdriver.Chrome()
```

```csharp
var driver = new ChromeDriver();
```

```ruby
driver = Selenium::WebDriver.for :chrome
```

```javascript
let driver = await new Builder().forBrowser('chrome').build();
```

```kotlin
val driver = ChromeDriver()
```

To generate the above tabs, this is what you need to write. Note that the `tabpane` includes `langEqualsHeader=true`. This auto-formats the code in each tab to match the header name, and ensures that all tabs on the page with a language are set to the same thing.

```
{{< tabpane langEqualsHeader=true >}}
  {{< tab header="Java" >}}
    WebDriver driver = new ChromeDriver();
  {{< /tab >}}
  {{< tab header="Python" >}}
    driver = webdriver.Chrome()
  {{< /tab >}}
  {{< tab header="CSharp" >}}
    var driver = new ChromeDriver();
  {{< /tab >}}
  {{< tab header="Ruby" >}}
    driver = Selenium::WebDriver.for :chrome
  {{< /tab >}}
  {{< tab header="JavaScript" >}}
    let driver = await new Builder().forBrowser('chrome').build();
  {{< /tab >}}
  {{< tab header="Kotlin" >}}
    val driver = ChromeDriver()
  {{< /tab >}}
{{< /tabpane >}}
```

#### Reference GitHub Examples

To ensure that all code is kept up to date, our goal is to write the code in the repo where it can be executed when Selenium versions are updated to ensure that everything is correct.

All code examples to be in our [example directories](https://github.com/SeleniumHQ/seleniumhq.github.io/tree/dev/examples).

This code can be automatically displayed in the documentation using the `gh-codeblock` shortcode. The shortcode automatically generates its own html, so we do not want it to auto-format with the language header. If all tabs are using this shortcode, set `text=true` in the `tabpane` and remove `langEqualsHeader=true`. If only some tabs are using this shortcode, keep `langEqualsHeader=true` in the `tabpane` and add `text=true` to the `tab`. Note that the `gh-codeblock` line can not be indented at all.

One great thing about using `gh-codeblock` is that it adds a link to the full example. This means you don’t have to include any additional context code, just the line(s) that are needed, and the user can navigate to the repo to see how to use it.

A basic comparison of code looks like:

```
{{< tabpane text=true >}}
{{< tab header="Java" >}}
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-L27" >}}
{{< /tab >}}
{{< tab header="Python" >}}
{{< gh-codeblock path="/examples/python/tests/getting_started/first_script.py#L18-L19" >}}
{{< /tab >}}
{{< tab header="CSharp" >}}
{{< gh-codeblock path="/examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-L26" >}}
{{< /tab >}}
{{< tab header="Ruby" >}}
{{< gh-codeblock path="/examples/ruby/spec/getting_started/first_script.rb#L17-L18" >}}
{{< /tab >}}
{{< tab header="JavaScript" >}}
{{< gh-codeblock path="/examples/javascript/test/getting_started/firstScript.spec.js#L22-L23" >}}
{{< /tab >}}
{{< tab header="Kotlin" >}}
{{< gh-codeblock path="/examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-L32" >}}
{{< /tab >}}
{{< /tabpane >}}
```

```java
        WebElement message = driver.findElement(By.id("message"));
        message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L26-L27)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
message = driver.find_element(by=By.ID, value="message")
text = message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/first_script.py#L18-L19)

##### /examples/python/tests/getting\_started/first\_script.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev/selenium/web/web-form.html")

title = driver.title

driver.implicitly_wait(0.5)

text_box = driver.find_element(by=By.NAME, value="my-text")
submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

text_box.send_keys("Selenium")
submit_button.click()

message = driver.find_element(by=By.ID, value="message")
text = message.text

driver.quit()
```

```cs
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L25-L26)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
message = driver.find_element(id: 'message')
message.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/first_script.rb#L17-L18)

##### /examples/ruby/spec/getting\_started/first\_script.rb

```rb
require 'selenium-webdriver'

driver = Selenium::WebDriver.for :chrome

driver.get('https://www.selenium.dev/selenium/web/web-form.html')

driver.title

driver.manage.timeouts.implicit_wait = 500

text_box = driver.find_element(name: 'my-text')
submit_button = driver.find_element(tag_name: 'button')

text_box.send_keys('Selenium')
submit_button.click

message = driver.find_element(id: 'message')
message.text

driver.quit
```

```js
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L22-L23)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        val message = driver.findElement(By.id("message"))
        val value = message.getText()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L31-L32)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

### Using Markdown in a Tab

If you want your example to include something other than code (default) or html (from `gh-codeblock`), you need to first set `text=true`, then change the Hugo syntax for the `tab`to use `%` instead of `<` and `>` with curly braces:

```
{{< tabpane text=true >}}
{{% tab header="Java" %}}
1. Start the driver
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12" >}}
2. Navigate to a page
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14" >}}
3. Quit the driver
{{< gh-codeblock path="/examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29" >}}
{{% /tab %}}
< ... >
{{< /tabpane >}}
```

This produces:

*

1. Start the driver

   ```java
           WebDriver driver = new ChromeDriver();
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L12)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

2. Navigate to a page

   ```java
           driver.get("https://www.selenium.dev/selenium/web/web-form.html");
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L14)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

3. Quit the driver

   ```java
           driver.quit();
   ```

   [View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

   ##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

   ```java
   package dev.selenium.getting_started;

   import org.openqa.selenium.By;
   import org.openqa.selenium.WebDriver;
   import org.openqa.selenium.WebElement;
   import org.openqa.selenium.chrome.ChromeDriver;

   import java.time.Duration;

   public class FirstScript {
       public static void main(String[] args) {
           WebDriver driver = new ChromeDriver();

           driver.get("https://www.selenium.dev/selenium/web/web-form.html");

           driver.getTitle();

           driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

           WebElement textBox = driver.findElement(By.name("my-text"));
           WebElement submitButton = driver.findElement(By.cssSelector("button"));

           textBox.sendKeys("Selenium");
           submitButton.click();

           WebElement message = driver.findElement(By.id("message"));
           message.getText();

           driver.quit();
       }
   }
   ```

This is preferred to writing code comments because those will not be translated. Only include the code that is needed for the documentation, and avoid over-explaining. Finally, remember not to indent plain text or it will rendered as a codeblock.

----
url: https://www.selenium.dev/ja/documentation/legacy/selenium_2/upgrading/
----

# RCからWebDriverへの移行

```java
Selenium selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.yoursite.com");
selenium.start();
```

これは次のように置き換える必要があります。

```java
WebDriver driver = new FirefoxDriver();
Selenium selenium = new WebDriverBackedSelenium(driver, "http://www.yoursite.com");
```

## 次のステップ

テストがエラーなしで実行されたら、次の段階は実際のテストコードを移行してWebDriver APIを使用することです。 コードがどれだけ適切に抽象化されているかによって、これは短いプロセスまたは長いプロセスになります。 どちらの場合でも、アプローチは同じであり、簡単に要約できます。 編集するときに新しいAPIを使用するようにコードを変更します。

基になるWebDriver実装をSeleniumインスタンスから抽出する必要がある場合は、WrapsDriverにキャストするだけです。

```java
WebDriver driver = ((WrapsDriver) selenium).getWrappedDriver();
```

これにより、通常どおりSeleniumインスタンスの受け渡しを続けることができますが、必要に応じてWebDriverインスタンスのラップを解除できます。

ある時点で、コードベースは主に新しいAPIを使用します。 この時点で、WebDriverを使用して関係を反転し、オンデマンドでSeleniumインスタンスをインスタンス化できます。

```java
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);
```

## 一般的な問題

幸いなことに、この移行を最初に行ったのはあなたではないので、他の人が経験した一般的な問題とその解決方法を以下に示します。

### クリックと入力がより完全に

Selenium RCテストの一般的なパターンは、以下のとおりです。

```java
selenium.type("name", "exciting tex");
selenium.keyDown("name", "t");
selenium.keyPress("name", "t");
selenium.keyUp("name", "t");
```

```java
Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(30));
WebElement element= wait.until(visibilityOfElementLocated(By.id("some_id")));
```

“visibilityOfElementLocated” は次のように実装されます。

```java
public ExpectedCondition<WebElement> visibilityOfElementLocated(final By locator) {
  return new ExpectedCondition<WebElement>() {
    public WebElement apply(WebDriver driver) {
      WebElement toReturn = driver.findElement(locator);
      if (toReturn.isDisplayed()) {
        return toReturn;
      }
      return null;
    }
  };
}
```

これは複雑に見えるかもしれませんが、ほとんどすべての定型コードです。 唯一の興味深い点は、 “apply” メソッドが “null” でもBoolean.FALSEでもないものを返すまで、 “ExpectedCondition” が繰り返し評価されることです。

もちろん、これらの “wait” 呼び出しをすべて追加すると、コードが混乱する可能性があります。 その場合で、ニーズが単純な場合は、暗黙的な待機の使用を検討してください。

```java
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
```

```java
String name = selenium.getEval(
    "selenium.browserbot.findElement('id=foo', browserbot.getCurrentWindow()).tagName");
```

このようになります。

```java
WebElement element = driver.findElement(By.id("foo"));
String name = (String) ((JavascriptExecutor) driver).executeScript(
    "return arguments[0].tagName", element);
```

渡された “element” 変数が、JS標準の “arguments” 配列の最初の項目としてどのように表示されるかに注目してください。

### Executing Javascript Doesn’t Return Anything

WebDriverのJavascriptExecutorは、すべてのJSをラップし、匿名式として評価します。 これは、 “return” キーワードを使用する必要があることを意味します。

```java
String title = selenium.getEval("browserbot.getCurrentWindow().document.title");
```

このようになります。

```java
((JavascriptExecutor) driver).executeScript("return document.title;");
```

----
url: https://www.selenium.dev/_print/documentation/webdriver/interactions/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/webdriver/interactions/).

# Browser interactions

* 1: [Browser navigation](#pg-fedcd598f2ffbe9c0326ecee13ad71a0)
* 2: [JavaScript alerts, prompts and confirmations](#pg-a3da25e36fdab1d60ab69c96a69f53ed)
* 3: [Working with cookies](#pg-dd64772105280f916af37d22904f9658)
* 4: [Working with IFrames and frames](#pg-34dde4ee0380237c9f897224f75055e5)
* 5: [Print Page](#pg-c55f7c60ac13469ca61bfd53a5611471)
* 6: [Working with windows and tabs](#pg-0173104e5a75fd17aec00cf87e6f26d4)
* 7: [Virtual Authenticator](#pg-ee8f25811af4812f0932978c98e7c82c)

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java#L15)

##### /examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class InteractionsTest extends BaseChromeTest {
    @Test
    public void getTitle() {
        driver.get("https://www.selenium.dev/");
        // get title
        String title = driver.getTitle();
        Assertions.assertEquals(title, "Selenium");
    }

    @Test
    public void getCurrentUrl() {
        driver.get("https://www.selenium.dev/");
        // get current url
        String url = driver.getCurrentUrl();
        Assertions.assertEquals(url, "https://www.selenium.dev/");
    }
}
```

```py
title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_interactions.py#L7)

##### /examples/python/tests/interactions/test\_interactions.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")

title = driver.title
assert title == "Selenium"

url = driver.current_url
assert url == "https://www.selenium.dev/"

driver.quit()
```

```cs
            String title = driver.Title;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs#L37)

##### /examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class InteractionsTest
    {
        [TestMethod]
        public void TestInteractions()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url="https://www.selenium.dev/";
            //GetTitle
            String title = driver.Title;
            Assert.AreEqual(title, "Selenium");

            //GetCurrentURL
            String url = driver.Url;
            Assert.AreEqual(url, "https://www.selenium.dev/");

            //quitting driver
            driver.Quit(); //close all windows
        }
    }
}
```

```rb
  it 'gets the current title' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/browser_spec.rb#L8)

##### /examples/ruby/spec/interactions/browser\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'gets the current title' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_title = driver.title
    expect(current_title).to eq 'Selenium'
  end

  it 'gets the current url' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_url = driver.current_url
    expect(current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    let title = await driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/interactionsIndex.spec.js#L20)

##### /examples/javascript/test/interactions/interactionsIndex.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Should be able to get title and current url', async function () {
    const url = 'https://www.selenium.dev/';
    await driver.get(url);

    //Get Current title
    let title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Get Current url
    let currentUrl = await driver.getCurrentUrl();
    assert.equal(currentUrl, url);
  });
});
```

```kotlin
driver.title
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java#L26)

##### /examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class InteractionsTest extends BaseChromeTest {
    @Test
    public void getTitle() {
        driver.get("https://www.selenium.dev/");
        // get title
        String title = driver.getTitle();
        Assertions.assertEquals(title, "Selenium");
    }

    @Test
    public void getCurrentUrl() {
        driver.get("https://www.selenium.dev/");
        // get current url
        String url = driver.getCurrentUrl();
        Assertions.assertEquals(url, "https://www.selenium.dev/");
    }
}
```

```py
url = driver.current_url
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_interactions.py#L10)

##### /examples/python/tests/interactions/test\_interactions.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")

title = driver.title
assert title == "Selenium"

url = driver.current_url
assert url == "https://www.selenium.dev/"

driver.quit()
```

```cs
            String url = driver.Url;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs#L41)

##### /examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class InteractionsTest
    {
        [TestMethod]
        public void TestInteractions()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url="https://www.selenium.dev/";
            //GetTitle
            String title = driver.Title;
            Assert.AreEqual(title, "Selenium");

            //GetCurrentURL
            String url = driver.Url;
            Assert.AreEqual(url, "https://www.selenium.dev/");

            //quitting driver
            driver.Quit(); //close all windows
        }
    }
}
```

```rb
  it 'gets the current url' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/browser_spec.rb#L14)

##### /examples/ruby/spec/interactions/browser\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'gets the current title' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_title = driver.title
    expect(current_title).to eq 'Selenium'
  end

  it 'gets the current url' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_url = driver.current_url
    expect(current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    let currentUrl = await driver.getCurrentUrl();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/interactionsIndex.spec.js#L24)

##### /examples/javascript/test/interactions/interactionsIndex.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Should be able to get title and current url', async function () {
    const url = 'https://www.selenium.dev/';
    await driver.get(url);

    //Get Current title
    let title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Get Current url
    let currentUrl = await driver.getCurrentUrl();
    assert.equal(currentUrl, url);
  });
});
```

```kotlin
driver.currentUrl
```

# 1 - Browser navigation

```java
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L14-L18)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.get("https://www.selenium.dev/selenium/web/index.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L6)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Convenient
            driver.Url = "https://selenium.dev";
            //Longer
            driver.Navigate().GoToUrl("https://selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class NavigationTest
    {
        [TestMethod]
        public void TestNavigationCommands()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            //Convenient
            driver.Url = "https://selenium.dev";
            //Longer
            driver.Navigate().GoToUrl("https://selenium.dev");
            var title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Back
            driver.Navigate().Back();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Forward
            driver.Navigate().Forward();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Refresh
            driver.Navigate().Refresh();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Quit the browser
            driver.Quit();
        }
    }
}
```

```rb

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L7-L9)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Convenient
      await driver.get('https://www.selenium.dev');
  
      //Longer way
      await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L16-L20)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
  const assert = require("node:assert");
  
  describe('Interactions - Navigation', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser('chrome')
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('Browser navigation test', async function () {
      //Convenient
      await driver.get('https://www.selenium.dev');
  
      //Longer way
      await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
      let title = await driver.getTitle();
      assert.equal(title, "Index of Available Pages");
  
      //Back
      await driver.navigate().back();
      title = await driver.getTitle();
      assert.equal(title, "Selenium");
  
      //Forward
      await driver.navigate().forward();
      title = await driver.getTitle();
      assert.equal(title, "Index of Available Pages");
  
      //Refresh
      await driver.navigate().refresh();
      title = await driver.getTitle();
      assert.equal(title, "Index of Available Pages");
    });
  });
```

```kotlin
//Convenient
driver.get("https://selenium.dev")

//Longer way
driver.navigate().to("https://selenium.dev")
  
```

```java
        //Back
        driver.navigate().back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L22-L23)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.back()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L11)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Back
             driver.Navigate().Back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L24-L25)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
    driver.navigate.to 'https://www.selenium.dev/'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L15)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Back
      await driver.navigate().back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L24-L25)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
  const assert = require("node:assert");
  
  describe('Interactions - Navigation', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser('chrome')
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('Browser navigation test', async function () {
      //Convenient
      await driver.get('https://www.selenium.dev');
  
      //Longer way
      await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
      let title = await driver.getTitle();
      assert.equal(title, "Index of Available Pages");
  
      //Back
      await driver.navigate().back();
      title = await driver.getTitle();
      assert.equal(title, "Selenium");
  
      //Forward
      await driver.navigate().forward();
      title = await driver.getTitle();
      assert.equal(title, "Index of Available Pages");
  
      //Refresh
      await driver.navigate().refresh();
      title = await driver.getTitle();
      assert.equal(title, "Index of Available Pages");
    });
  });
```

```kotlin
driver.navigate().back() 
```

```java
        //Forward
        driver.navigate().forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L27-L28)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.forward()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L15)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Forward
             driver.Navigate().Forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L29-L30)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L23)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Forward
    await driver.navigate().forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L29-L30)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().forward()
```

```java
        //Refresh
        driver.navigate().refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L32-L33)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.refresh()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L19)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Refresh
             driver.Navigate().Refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L34-L35)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
  it 'refreshes the page' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L29)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Refresh
    await driver.navigate().refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L34-L35)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().refresh()
```

# 2 - JavaScript alerts, prompts and confirmations

```java

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L36-L41)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L12-L18)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See an example alert")).Click();

//Wait for the alert to be displayed and store it in a variable
IAlert alert = wait.Until(ExpectedConditions.AlertIsPresent());

//Store the alert text in a variable
string text = alert.Text;

//Press the OK button
alert.Accept();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L15-L22)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L19-L21)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See an example alert")).click()

//Wait for the alert to be displayed and store it in a variable
val alert = wait.until(ExpectedConditions.alertIsPresent())

//Store the alert text in a variable
val text = alert.getText()

//Press the OK button
alert.accept()
  
```

```java
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L131-L138)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L26-L32)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See a sample confirm")).Click();

//Wait for the alert to be displayed
wait.Until(ExpectedConditions.AlertIsPresent());

//Store the alert in a variable
IAlert alert = driver.SwitchTo().Alert();

//Store the alert in a variable for reuse
string text = alert.Text;

//Press the Cancel button
alert.Dismiss();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L28-L35)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L30-L32)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See a sample confirm")).click()

//Wait for the alert to be displayed
wait.until(ExpectedConditions.alertIsPresent())

//Store the alert in a variable
val alert = driver.switchTo().alert()

//Store the alert in a variable for reuse
val text = alert.text

//Press the Cancel button
alert.dismiss()
  
```

```java
        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L79-L84)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L40-L47)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

//Click the link to activate the alert driver.FindElement(By.LinkText("See a sample prompt")).Click(); //Wait for the alert to be displayed and store it in a variable IAlert alert = wait.Until(ExpectedConditions.AlertIsPresent()); //Type your message alert.SendKeys("Selenium"); //Press the OK button alert.Accept();

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L41-L48)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L42-L45)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

//Click the link to activate the alert driver.findElement(By.linkText("See a sample prompt")).click() //Wait for the alert to be displayed and store it in a variable val alert = wait.until(ExpectedConditions.alertIsPresent()) //Type your message alert.sendKeys("Selenium") //Press the OK button alert.accept()

# 3 - Working with cookies

```java

    WebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L30-L32)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L5-L9)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L32-L34)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L9-L11)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L18)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")

        // Adds the cookie into current browser context
        driver.manage().addCookie(Cookie("key", "value"))
    } finally {
        driver.quit()
    }
}
  
```

```java
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L38-L42)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L13-L20)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L40-L44)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L17-L21)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L35-L38)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("foo", "bar"))

        // Get cookie details with named cookie 'foo'
        val cookie = driver.manage().getCookieNamed("foo")
        println(cookie)
    } finally {
        driver.quit()
    }
}  
  
```

```java
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L52-L66)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L24-L32)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L51-L64)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L26-L31)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L49-L51)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        driver.manage().addCookie(Cookie("test2", "cookie2"))

        // Get All available cookies
        val cookies = driver.manage().cookies
        println(cookies)
    } finally {
        driver.quit()
    }
}  
  
```

```java
        }
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L74-L77)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L35-L43)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L70-L73)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L40-L43)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L61-L62)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        val cookie1 = Cookie("test2", "cookie2")
        driver.manage().addCookie(cookie1)

        // delete a cookie with name 'test1'
        driver.manage().deleteCookieNamed("test1")
        
        // delete cookie by passing cookie object of current browsing context.
        driver.manage().deleteCookie(cookie1)
    } finally {
        driver.quit()
    }
}  
  
```

```java
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L100-L105)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L47-L55)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L92-L97)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L49-L54)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L77-L78)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        driver.manage().addCookie(Cookie("test2", "cookie2"))

        // deletes all cookies
        driver.manage().deleteAllCookies()
    } finally {
        driver.quit()
    }
}  
  
```

```java

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L112-L121)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L59-L71)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SameSiteCookie {
  class SameSiteCookie {
    static void Main(string[] args) {
      IWebDriver driver = new ChromeDriver();
      try {
        driver.Navigate().GoToUrl("http://www.example.com");

        var cookie1Dictionary = new System.Collections.Generic.Dictionary<string, object>() {
          { "name", "test1" }, { "value", "cookie1" }, { "sameSite", "Strict" } };
        var cookie1 = Cookie.FromDictionary(cookie1Dictionary);

        var cookie2Dictionary = new System.Collections.Generic.Dictionary<string, object>() {
          { "name", "test2" }, { "value", "cookie2" }, { "sameSite", "Lax" } };
        var cookie2 = Cookie.FromDictionary(cookie2Dictionary);

        driver.Manage().Cookies.AddCookie(cookie1);
        driver.Manage().Cookies.AddCookie(cookie2);

        System.Console.WriteLine(cookie1.SameSite);
        System.Console.WriteLine(cookie2.SameSite);
      } finally {
        driver.Quit();
      }
    }
  }
}
  
```

```ruby
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://www.example.com'
  # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
  driver.manage.add_cookie(name: "foo", value: "bar", same_site: "Strict")
  driver.manage.add_cookie(name: "foo1", value: "bar", same_site: "Lax")
  puts driver.manage.cookie_named('foo')
  puts driver.manage.cookie_named('foo1')
ensure
  driver.quit
end
  
```

```js
  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L24-L26)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("http://www.example.com")
        val cookie = Cookie.Builder("key", "value").sameSite("Strict").build()
        val cookie1 = Cookie.Builder("key", "value").sameSite("Lax").build()
        driver.manage().addCookie(cookie)
        driver.manage().addCookie(cookie1)
        println(cookie.getSameSite())
        println(cookie1.getSameSite())
    } finally {
        driver.quit()
    }
}
  
```

# 4 - Working with IFrames and frames

Frames are a now deprecated means of building a site layout from multiple documents on the same domain. You are unlikely to work with them unless you are working with an pre HTML5 webapp. Iframes allow the insertion of a document from an entirely different domain, and are still commonly used.

If you need to work with frames or iframes, WebDriver allows you to work with them in the same way. Consider a button within an iframe. If we inspect the element using the browser development tools, we might see the following:

```html
<div id="modal">
  <iframe id="buttonframe" name="myframe"  src="https://seleniumhq.github.io">
   <button>Click here</button>
 </iframe>
</div>
```

```java
//This won't work
driver.findElement(By.tagName("button")).click();
  
```

```python
    # This Wont work
driver.find_element(By.TAG_NAME, 'button').click()
  
```

```csharp
//This won't work
driver.FindElement(By.TagName("button")).Click();
  
```

```ruby
    # This won't work
driver.find_element(:tag_name,'button').click
  
```

```javascript
// This won't work
await driver.findElement(By.css('button')).click();
  
```

```kotlin
//This won't work
driver.findElement(By.tagName("button")).click()
  
```

```java
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L38-L46)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L24-L32)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L38-L46)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L26-L33)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Store the web element
const iframe = driver.findElement(By.css('#modal > iframe'));

// Switch to the frame
await driver.switchTo().frame(iframe);

// Now we can click the button
await driver.findElement(By.css('button')).click();
  
```

```kotlin
//Store the web element
val iframe = driver.findElement(By.cssSelector("#modal>iframe"))

//Switch to the frame
driver.switchTo().frame(iframe)

//Now we can click the button
driver.findElement(By.tagName("button")).click()
  
```

```java
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L50-L58)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L34-L42)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L50-L58)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L36-L43)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Using the ID
await driver.switchTo().frame('buttonframe');

// Or using the name instead
await driver.switchTo().frame('myframe');

// Now we can click the button
await driver.findElement(By.css('button')).click();
  
```

```kotlin
//Using the ID
driver.switchTo().frame("buttonframe")

//Or using the name instead
driver.switchTo().frame("myframe")

//Now we can click the button
driver.findElement(By.tagName("button")).click()
  
```

```java
         //switch To IFrame using index
         driver.switchTo().frame(0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L62-L63)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L45-L46)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L62-L63)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L46-L47)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Switches to the second frame
await driver.switchTo().frame(1);
  
```

```kotlin
// Switches to the second frame
driver.switchTo().frame(1)
  
```

```java
         //leave frame
         driver.switchTo().defaultContent();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L66-L67)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L49-L50)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //leave frame
            driver.SwitchTo().DefaultContent();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L66-L67)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L49-L50)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Return to the top level
await driver.switchTo().defaultContent();
  
```

```kotlin
// Return to the top level
driver.switchTo().defaultContent()
  
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L14-L17)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L12-L19)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L12-L14)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L23-L26)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L22-L29)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L18-L20)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L32-L35)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L32-L38)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L24-L26)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L41-L48)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L51-L57)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L30-L35)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L53-L57)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L61-L68)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L42-L45)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L63-L66)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L41-L48)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L49-L51)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L72-L75)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L71-L78)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L55-L57)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java#L27-L31)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.Pdf;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.PrintsPage;
import dev.selenium.BaseTest;

public class PrintsPageTest extends BaseTest{

    @BeforeEach
    public void setup() {
        ChromeOptions options = getDefaultChromeOptions();
        options.setCapability("webSocketUrl", true);
        driver = new ChromeDriver(options);
    }

    @Test
    public void PrintWithPrintsPageTest() 
    {
        driver.get("https://www.selenium.dev/");
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }

    @Test
    public void PrintWithBrowsingContextTest() 
    {
        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);
        Assertions.assertTrue(printPage.length() > 0);
    }
}
```

**BrowsingContext()**

```java
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        PrintOptions printOptions = new PrintOptions();
        String printPage = browsingContext.print(printOptions);
        Assertions.assertTrue(printPage.length() > 0);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java#L37-L41)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.Pdf;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.PrintsPage;
import dev.selenium.BaseTest;

public class PrintsPageTest extends BaseTest{

    @BeforeEach
    public void setup() {
        ChromeOptions options = getDefaultChromeOptions();
        options.setCapability("webSocketUrl", true);
        driver = new ChromeDriver(options);
    }

    @Test
    public void PrintWithPrintsPageTest() 
    {
        driver.get("https://www.selenium.dev/");
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }

    @Test
    public void PrintWithBrowsingContextTest() 
    {
        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);
        Assertions.assertTrue(printPage.length() > 0);
    }
}
```

```cs
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L81-L88)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

**print\_page()**

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    pdf = driver.print_page(print_options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_prints_page.py#L12-L14)

##### /examples/python/tests/interactions/test\_prints\_page.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_prints_page(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    pdf = driver.print_page(print_options)
    assert len(pdf) > 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

# 6 - Working with windows and tabs

```java
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L16-L20)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L16-L18)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L17-L21)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
driver.window_handle
```

```javascript
await driver.getWindowHandle();
```

```kotlin
driver.windowHandle
```

```java
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L22-L29)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L22-L32)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L23-L30)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
    # Store the ID of the original window
original_window = driver.window_handle

    # Check we don't have other windows open already
assert(driver.window_handles.length == 1, 'Expected one window')

    # Click the link which opens in a new window
driver.find_element(link: 'new window').click

    # Wait for the new window or tab
wait.until { driver.window_handles.length == 2 }

    #Loop through until we find a new window handle
driver.window_handles.each do |handle|
    if handle != original_window
        driver.switch_to.window handle
        break
    end
end

    #Wait for the new tab to finish loading content
wait.until { driver.title == 'Selenium documentation'}
  
```

```javascript
//Store the ID of the original window
const originalWindow = await driver.getWindowHandle();

//Check we don't have other windows open already
assert((await driver.getAllWindowHandles()).length === 1);

//Click the link which opens in a new window
await driver.findElement(By.linkText('new window')).click();

//Wait for the new window or tab
await driver.wait(
    async () => (await driver.getAllWindowHandles()).length === 2,
    10000
  );

//Loop through until we find a new window handle
const windows = await driver.getAllWindowHandles();
windows.forEach(async handle => {
  if (handle !== originalWindow) {
    await driver.switchTo().window(handle);
  }
});

//Wait for the new tab to finish loading content
await driver.wait(until.titleIs('Selenium documentation'), 10000);
  
```

```kotlin
//Store the ID of the original window
val originalWindow = driver.getWindowHandle()

//Check we don't have other windows open already
assert(driver.getWindowHandles().size() === 1)

//Click the link which opens in a new window
driver.findElement(By.linkText("new window")).click()

//Wait for the new window or tab
wait.until(numberOfWindowsToBe(2))

//Loop through until we find a new window handle
for (windowHandle in driver.getWindowHandles()) {
    if (!originalWindow.contentEquals(windowHandle)) {
        driver.switchTo().window(windowHandle)
        break
    }
}

//Wait for the new tab to finish loading content
wait.until(titleIs("Selenium documentation"))

  
```

```java
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L31-L34)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L46-L46)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L32-L35)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
    #Close the tab or window
driver.close

    #Switch back to the old tab or window
driver.switch_to.window original_window
  
```

```javascript
//Close the tab or window
await driver.close();

//Switch back to the old tab or window
await driver.switchTo().window(originalWindow);
  
```

```kotlin
//Close the tab or window
driver.close()

//Switch back to the old tab or window
driver.switchTo().window(originalWindow)

  
```

```java
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L36-L42)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L53-L58)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L37-L43)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

Opens a new tab and switches to new tab:

```rb
    driver.switch_to.new_window(:tab)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/windows_spec.rb#L9)

##### /examples/ruby/spec/interactions/windows\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Windows' do
  let(:driver) { start_session }

  it 'opens new tab' do
    driver.switch_to.new_window(:tab)

    expect(driver.window_handles.size).to eq 2
  end

  it 'opens new window' do
    driver.switch_to.new_window(:window)

    expect(driver.window_handles.size).to eq 2
  end
end
```

Opens a new window and switches to new window:

```rb
    driver.switch_to.new_window(:window)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/windows_spec.rb#L15)

##### /examples/ruby/spec/interactions/windows\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Windows' do
  let(:driver) { start_session }

  it 'opens new tab' do
    driver.switch_to.new_window(:tab)

    expect(driver.window_handles.size).to eq 2
  end

  it 'opens new window' do
    driver.switch_to.new_window(:window)

    expect(driver.window_handles.size).to eq 2
  end
end
```

Opens a new tab and switches to new tab

```js
    await driver.switchTo().newWindow('tab');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L70)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

Opens a new window and switches to new window:

```js
    await driver.switchTo().newWindow('window');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L75)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Opens a new tab and switches to new tab
driver.switchTo().newWindow(WindowType.TAB)

// Opens a new window and switches to new window
driver.switchTo().newWindow(WindowType.WINDOW)
  
```

```java
        //quitting driver
        driver.quit(); //close all windows
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L44-L45)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L13-L13)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //quitting driver
              driver.Quit(); //close all windows
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L45-L46)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
driver.quit
```

```javascript
await driver.quit();
```

```kotlin
driver.quit()
```

```java
/**
 * Example using JUnit
 * https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
 */
@AfterAll
public static void tearDown() {
    driver.quit();
}
  
```

```python
    # unittest teardown
    # https://docs.python.org/3/library/unittest.html?highlight=teardown#unittest.TestCase.tearDown
def tearDown(self):
    self.driver.quit()
  
```

```csharp
/*
    Example using Visual Studio's UnitTesting
    https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.aspx
*/
[TestCleanup]
public void TearDown()
{
    driver.Quit();
}
  
```

```ruby
    # UnitTest Teardown
    # https://www.rubydoc.info/github/test-unit/test-unit/Test/Unit/TestCase
def teardown
    @driver.quit
end
  
```

```javascript
/**
 * Example using Mocha
 * https://mochajs.org/#hooks
 */
after('Tear down', async function () {
  await driver.quit();
});
  
```

```kotlin
/**
 * Example using JUnit
 * https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
 */
@AfterAll
fun tearDown() {
    driver.quit()
}
  
```

```java
try {
    //WebDriver code here...
} finally {
    driver.quit();
}
  
```

```python
try:
    #WebDriver code here...
finally:
    driver.quit()
  
```

```csharp
try {
    //WebDriver code here...
} finally {
    driver.Quit();
}
  
```

```ruby
begin
    #WebDriver code here...
ensure
    driver.quit
end
  
```

```javascript
try {
    //WebDriver code here...
} finally {
    await driver.quit();
}
  
```

```kotlin
try {
    //WebDriver code here...
} finally {
    driver.quit()
}
  
```

Python’s WebDriver now supports the python context manager, which when using the `with` keyword can automatically quit the driver at the end of execution.

```python
with webdriver.Firefox() as driver:
  # WebDriver code here...

# WebDriver will automatically quit after indentation
```

```java
//Access each dimension individually
int width = driver.manage().window().getSize().getWidth();
int height = driver.manage().window().getSize().getHeight();

//Or store the dimensions and query them later
Dimension size = driver.manage().window().getSize();
int width1 = size.getWidth();
int height1 = size.getHeight();
  
```

```python
    # Access each dimension individually
width = driver.get_window_size().get("width")
height = driver.get_window_size().get("height")

    # Or store the dimensions and query them later
size = driver.get_window_size()
width1 = size.get("width")
height1 = size.get("height")
  
```

```csharp
//Access each dimension individually
int width = driver.Manage().Window.Size.Width;
int height = driver.Manage().Window.Size.Height;

//Or store the dimensions and query them later
System.Drawing.Size size = driver.Manage().Window.Size;
int width1 = size.Width;
int height1 = size.Height;
  
```

```ruby
    # Access each dimension individually
width = driver.manage.window.size.width
height = driver.manage.window.size.height

    # Or store the dimensions and query them later
size = driver.manage.window.size
width1 = size.width
height1 = size.height
  
```

Access each dimension individually

```js
    const { width, height } = await driver.manage().window().getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L93)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

(or) store the dimensions and query them later

```js
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L96-L98)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
//Access each dimension individually
val width = driver.manage().window().size.width
val height = driver.manage().window().size.height

//Or store the dimensions and query them later
val size = driver.manage().window().size
val width1 = size.width
val height1 = size.height
  
```

```java
driver.manage().window().setSize(new Dimension(1024, 768));
```

```python
driver.set_window_size(1024, 768)
```

```csharp
driver.Manage().Window.Size = new Size(1024, 768);
```

```ruby
driver.manage.window.resize_to(1024,768)
```

```javascript
await driver.manage().window().setRect({ width: 1024, height: 768 });
```

```kotlin
driver.manage().window().size = Dimension(1024, 768)
```

```java
// Access each dimension individually
int x = driver.manage().window().getPosition().getX();
int y = driver.manage().window().getPosition().getY();

// Or store the dimensions and query them later
Point position = driver.manage().window().getPosition();
int x1 = position.getX();
int y1 = position.getY();
  
```

```python
    # Access each dimension individually
x = driver.get_window_position().get('x')
y = driver.get_window_position().get('y')

    # Or store the dimensions and query them later
position = driver.get_window_position()
x1 = position.get('x')
y1 = position.get('y')
  
```

```csharp
//Access each dimension individually
int x = driver.Manage().Window.Position.X;
int y = driver.Manage().Window.Position.Y;

//Or store the dimensions and query them later
Point position = driver.Manage().Window.Position;
int x1 = position.X;
int y1 = position.Y;
  
```

```ruby
    #Access each dimension individually
x = driver.manage.window.position.x
y = driver.manage.window.position.y

    # Or store the dimensions and query them later
rect  = driver.manage.window.rect
x1 = rect.x
y1 = rect.y
  
```

Access each dimension individually

```js
    const { x, y } = await driver.manage().window().getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L108)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

(or) store the dimensions and query them later

```js
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L111-L113)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Access each dimension individually
val x = driver.manage().window().position.x
val y = driver.manage().window().position.y

// Or store the dimensions and query them later
val position = driver.manage().window().position
val x1 = position.x
val y1 = position.y

  
```

```java
// Move the window to the top left of the primary monitor
driver.manage().window().setPosition(new Point(0, 0));
  
```

```python
    # Move the window to the top left of the primary monitor
driver.set_window_position(0, 0)
  
```

```csharp
// Move the window to the top left of the primary monitor
driver.Manage().Window.Position = new Point(0, 0);
  
```

```ruby
driver.manage.window.move_to(0,0)
  
```

```javascript
// Move the window to the top left of the primary monitor
await driver.manage().window().setRect({ x: 0, y: 0 });
  
```

```kotlin
// Move the window to the top left of the primary monitor
driver.manage().window().position = Point(0,0)
    
```

```java
driver.manage().window().maximize();
```

```python
driver.maximize_window()
```

```csharp
driver.Manage().Window.Maximize();
```

```ruby
driver.manage.window.maximize
```

```javascript
await driver.manage().window().maximize();
```

```kotlin
driver.manage().window().maximize()
```

```java
driver.manage().window().minimize();
```

```python
driver.minimize_window()
```

```csharp
driver.Manage().Window.Minimize();
```

```ruby
driver.manage.window.minimize
```

```javascript
await driver.manage().window().minimize();
```

```kotlin
driver.manage().window().minimize()
```

```java
driver.manage().window().fullscreen();
```

```python
driver.fullscreen_window()
```

```csharp
driver.Manage().Window.FullScreen();
```

```ruby
driver.manage.window.full_screen
```

```javascript
await driver.manage().window().fullscreen();
```

```kotlin
driver.manage().window().fullscreen()
```

```java
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.*;
import org.openqa.selenium.*;

public class SeleniumTakeScreenshot {
    public static void main(String args[]) throws IOException {
        WebDriver driver = new ChromeDriver();
        driver.get("http://www.example.com");
        File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(scrFile, new File("./image.png"));
        driver.quit();
    }
}
  
```

```python
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("http://www.example.com")

    # Returns and base64 encoded string into image
driver.save_screenshot('./image.png')

driver.quit()
```

```csharp
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using OpenQA.Selenium.Support.UI;

  var driver = new ChromeDriver();
  driver.Navigate().GoToUrl("http://www.example.com");
  Screenshot screenshot = (driver as ITakesScreenshot).GetScreenshot();
  screenshot.SaveAsFile("screenshot.png", ScreenshotImageFormat.Png); // Format values are Bmp, Gif, Jpeg, Png, Tiff
  
```

```ruby
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://example.com/'

    # Takes and Stores the screenshot in specified path
  driver.save_screenshot('./image.png')

end
  
```

```js
    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L56-L59)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
import com.oracle.tools.packager.IOUtils.copyFile
import org.openqa.selenium.*
import org.openqa.selenium.chrome.ChromeDriver
import java.io.File

fun main(){
    val driver =  ChromeDriver()
    driver.get("https://www.example.com")
    val scrFile = (driver as TakesScreenshot).getScreenshotAs<File>(OutputType.FILE)
    copyFile(scrFile, File("./image.png"))
    driver.quit()
}
   
```

```java
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.File;
import java.io.IOException;

public class SeleniumelementTakeScreenshot {
  public static void main(String args[]) throws IOException {
    WebDriver driver = new ChromeDriver();
    driver.get("https://www.example.com");
    WebElement element = driver.findElement(By.cssSelector("h1"));
    File scrFile = element.getScreenshotAs(OutputType.FILE);
    FileUtils.copyFile(scrFile, new File("./image.png"));
    driver.quit();
  }
}
  
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

driver.get("http://www.example.com")

ele = driver.find_element(By.CSS_SELECTOR, 'h1')

    # Returns and base64 encoded string into image
ele.screenshot('./image.png')

driver.quit()
  
```

```csharp
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;
    using OpenQA.Selenium.Support.UI;

    // Webdriver
    var driver = new ChromeDriver();
    driver.Navigate().GoToUrl("http://www.example.com");

    // Fetch element using FindElement
    var webElement = driver.FindElement(By.CssSelector("h1"));

    // Screenshot for the element
    var elementScreenshot = (webElement as ITakesScreenshot).GetScreenshot();
    elementScreenshot.SaveAsFile("screenshot_of_element.png");
  
```

```ruby
    # Works with Selenium4-alpha7 Ruby bindings and above
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://example.com/'
  ele = driver.find_element(:css, 'h1')

    # Takes and Stores the element screenshot in specified path
  ele.save_screenshot('./image.jpg')
end
  
```

```js
    let header = await driver.findElement(By.css('h1'));
      // Captures the element screenshot
      let encodedString = await header.takeScreenshot(true);
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
  
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L44-L48)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
  const chrome = require('selenium-webdriver/chrome');
  const assert = require("node:assert");
  let opts = new chrome.Options();
  opts.addArguments('--headless');
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let imgMagicNumber = 'iVBOR'
  let base64Code
  
  describe('Interactions - Windows', function () {
    let driver;
    before(async function () {
      driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
    });
  
    after(async () => await driver.quit());
  
    it('Should be able to print page to pdf', async function () {
  
      await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
      let base64 = await driver.printPage({pageRanges: ["1-2"]});
      // page can be saved as a PDF as below
      // await fs.writeFileSync('./test.pdf', base64, 'base64');
  
      base64Code = base64.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, pdfMagicNumber)
    });
  
    it('Should be able to get text using executeScript', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
      // Stores the header element
      let header = await driver.findElement(By.css('h1'));
  
      // Executing JavaScript to capture innerText of header element
      let text = await driver.executeScript('return arguments[0].innerText', header);
      assert.strictEqual(text, `Type Stuff`)
    });
  
    it('Should be able to take Element Screenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      let header = await driver.findElement(By.css('h1'));
      // Captures the element screenshot
      let encodedString = await header.takeScreenshot(true);
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to takeScreenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      // Captures the screenshot
      let encodedString = await driver.takeScreenshot();
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to switch to newWindow and newTab and close', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
      const initialWindow = await driver.getAllWindowHandles();
      assert.strictEqual(initialWindow.length, 1)
  
      // Opens a new tab and switches to new tab
      await driver.switchTo().newWindow('tab');
      const browserTabs = await driver.getAllWindowHandles();
      assert.strictEqual(browserTabs.length, 2)
  
      // Opens a new window and switches to new window
      await driver.switchTo().newWindow('window');
      const windows = await driver.getAllWindowHandles();
      assert.strictEqual(windows.length, 3)
  
      //Close the tab or window
      await driver.close();
  
      //Switch back to the old tab or window
      await driver.switchTo().window(windows[1]);
  
      const windowsAfterClose = await driver.getAllWindowHandles();
      assert.strictEqual(windowsAfterClose.length, 2);
    });
  
    it('Should be able to getWindow Size', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { width, height } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const windowWidth = rect.width;
      const windowHeight = rect.height;
  
      assert.ok(windowWidth>0);
      assert.ok(windowHeight>0);
    });
  
    it('Should be able to getWindow position', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { x, y } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const x1 = rect.x;
      const y1 = rect.y;
  
      assert.ok(x1>=0);
      assert.ok(y1>=0);
    });
  });
```

```kotlin
import org.apache.commons.io.FileUtils
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.*
import java.io.File

fun main() {
    val driver = ChromeDriver()
    driver.get("https://www.example.com")
    val element = driver.findElement(By.cssSelector("h1"))
    val scrFile: File = element.getScreenshotAs(OutputType.FILE)
    FileUtils.copyFile(scrFile, File("./image.png"))
    driver.quit()
}
  
```

```java
    //Creating the JavascriptExecutor interface object by Type casting
      JavascriptExecutor js = (JavascriptExecutor)driver;
    //Button Element
      WebElement button =driver.findElement(By.name("btnLogin"));
    //Executing JavaScript to click on element
      js.executeScript("arguments[0].click();", button);
    //Get return value from script
      String text = (String) js.executeScript("return arguments[0].innerText", button);
    //Executing JavaScript directly
      js.executeScript("console.log('hello world')");
  
```

```python
    # Stores the header element
header = driver.find_element(By.CSS_SELECTOR, "h1")

    # Executing JavaScript to capture innerText of header element
driver.execute_script('return arguments[0].innerText', header)
  
```

```csharp
	//creating Chromedriver instance
	IWebDriver driver = new ChromeDriver();
	//Creating the JavascriptExecutor interface object by Type casting
	IJavaScriptExecutor js = (IJavaScriptExecutor) driver;
	//Button Element
	IWebElement button = driver.FindElement(By.Name("btnLogin"));
	//Executing JavaScript to click on element
	js.ExecuteScript("arguments[0].click();", button);
	//Get return value from script
	String text = (String)js.ExecuteScript("return arguments[0].innerText", button);
	//Executing JavaScript directly
	js.ExecuteScript("console.log('hello world')");
  
```

```ruby
    # Stores the header element
header = driver.find_element(css: 'h1')

    # Get return value from script
result = driver.execute_script("return arguments[0].innerText", header)

    # Executing JavaScript directly
driver.execute_script("alert('hello world')")
  
```

```js
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L33-L37)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Stores the header element
val header = driver.findElement(By.cssSelector("h1"))

// Get return value from script
val result = driver.executeScript("return arguments[0].innerText", header)

// Executing JavaScript directly
driver.executeScript("alert('hello world')")
  
```

```java
    import org.openqa.selenium.print.PrintOptions;

    driver.get("https://www.selenium.dev");
    printer = (PrintsPage) driver;

    PrintOptions printOptions = new PrintOptions();
    printOptions.setPageRanges("1-2");

    Pdf pdf = printer.print(printOptions);
    String content = pdf.getContent();
  
```

```python
    from selenium.webdriver.common.print_page_options import PrintOptions

    print_options = PrintOptions()
    print_options.page_ranges = ['1-2']

    driver.get("printPage.html")

    base64code = driver.print_page(print_options)
  
```

```csharp
    // code sample not available please raise a PR
  
```

```ruby
    driver.navigate_to 'https://www.selenium.dev'

    base64encodedContent = driver.print_page(orientation: 'landscape')
  
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
      let base64 = await driver.printPage({pageRanges: ["1-2"]});
      // page can be saved as a PDF as below
      // await fs.writeFileSync('./test.pdf', base64, 'base64');
  
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L22-L25)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
  const chrome = require('selenium-webdriver/chrome');
  const assert = require("node:assert");
  let opts = new chrome.Options();
  opts.addArguments('--headless');
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let imgMagicNumber = 'iVBOR'
  let base64Code
  
  describe('Interactions - Windows', function () {
    let driver;
    before(async function () {
      driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
    });
  
    after(async () => await driver.quit());
  
    it('Should be able to print page to pdf', async function () {
  
      await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
      let base64 = await driver.printPage({pageRanges: ["1-2"]});
      // page can be saved as a PDF as below
      // await fs.writeFileSync('./test.pdf', base64, 'base64');
  
      base64Code = base64.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, pdfMagicNumber)
    });
  
    it('Should be able to get text using executeScript', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
      // Stores the header element
      let header = await driver.findElement(By.css('h1'));
  
      // Executing JavaScript to capture innerText of header element
      let text = await driver.executeScript('return arguments[0].innerText', header);
      assert.strictEqual(text, `Type Stuff`)
    });
  
    it('Should be able to take Element Screenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      let header = await driver.findElement(By.css('h1'));
      // Captures the element screenshot
      let encodedString = await header.takeScreenshot(true);
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to takeScreenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      // Captures the screenshot
      let encodedString = await driver.takeScreenshot();
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to switch to newWindow and newTab and close', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
      const initialWindow = await driver.getAllWindowHandles();
      assert.strictEqual(initialWindow.length, 1)
  
      // Opens a new tab and switches to new tab
      await driver.switchTo().newWindow('tab');
      const browserTabs = await driver.getAllWindowHandles();
      assert.strictEqual(browserTabs.length, 2)
  
      // Opens a new window and switches to new window
      await driver.switchTo().newWindow('window');
      const windows = await driver.getAllWindowHandles();
      assert.strictEqual(windows.length, 3)
  
      //Close the tab or window
      await driver.close();
  
      //Switch back to the old tab or window
      await driver.switchTo().window(windows[1]);
  
      const windowsAfterClose = await driver.getAllWindowHandles();
      assert.strictEqual(windowsAfterClose.length, 2);
    });
  
    it('Should be able to getWindow Size', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { width, height } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const windowWidth = rect.width;
      const windowHeight = rect.height;
  
      assert.ok(windowWidth>0);
      assert.ok(windowHeight>0);
    });
  
    it('Should be able to getWindow position', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { x, y } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const x1 = rect.x;
      const y1 = rect.y;
  
      assert.ok(x1>=0);
      assert.ok(y1>=0);
    });
  });
```

```kotlin
    driver.get("https://www.selenium.dev")
    val printer = driver as PrintsPage

    val printOptions = PrintOptions()
    printOptions.setPageRanges("1-2")
    
    val pdf: Pdf = printer.print(printOptions)
    val content = pdf.content
  
```

# 7 - Virtual Authenticator

```java
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L55-L61)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L48-55)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L40-L46)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setHasUserVerification(true);
    options.setIsUserConsenting(true);
    options.setTransport(Transport['USB']);
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    assert(Object.keys(options).length === 6);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticatorOptions.spec.js#L11-L17)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticatorOptions.spec.js

```js
const {VirtualAuthenticatorOptions, Transport, Protocol} = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')


describe('Virtual authenticator options', function () {
  let options;

  it('Virtual options', async function () {
    options = new VirtualAuthenticatorOptions();
    options.setIsUserVerified(true);
    options.setHasUserVerification(true);
    options.setIsUserConsenting(true);
    options.setTransport(Transport['USB']);
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    assert(Object.keys(options).length === 6);
  });

  it('User verified', async function () {
    options.setIsUserVerified(true);

    assert(options.toDict()['isUserVerified']);
  });
});
```

```java
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L68-L73)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L63-71)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L53-L58)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L51-L55)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L86)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#80-86)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L68-L74)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L62-L63)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L100-L103)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#103-107)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L89-L97)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L80-L94)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L143-L145)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L145-148)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L140-L147)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L136-L140)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L137-L146)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L139-150)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.add_credential(credential)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L150)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L131-L142)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L157-L171)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L162-178)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    credential_list = driver.get_credentials()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L183)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L154-L170)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L181-L190)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L189-198)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.remove_credential(credential.id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L209)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```java
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L196-L205)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L207-216)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.remove_all_credentials()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L239)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L181-L190)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L211-L212)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L224-225)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L245-L247)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setIsUserVerified(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L197-L197)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

----
url: https://www.selenium.dev/pt-br/_print/documentation/webdriver/elements/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/webdriver/elements/).

# Elemento Web

Identificando e trabalhando com elementos no DOM.

* 1: [Encontrando Elementos Web](#pg-be84f3c90fe0395284ff7c38998f0549)
* 2: [Interacting with web elements](#pg-fc42f16dac6efcbe4d303b21d355511c)
* 3: [Information about web elements](#pg-5459c6b0a0f0c24c4420c1a7d0bde90d)
* 4: [Localizando elementos](#pg-138419c96e848823f86444bc75a808fe)
* 5: [File Upload](#pg-3203f7b76d6fd426112da6ee2fa8c5a3)

A maioria do código que é escrito recorrendo às bibliotecas Selenium envolve trabalhar com elementos.

# 1 - Encontrando Elementos Web

Localizando elementos com base nos valores providenciados pelo localizador.

Um dos aspectos mais fundamentais do uso do Selenium é obter referências de elementos para trabalhar. O Selenium oferece várias [estratégias de localizador](https://www.selenium.dev/pt-br/documentation/webdriver/elements/locators/) para identificar exclusivamente um elemento. Há muitas maneiras de usar os localizadores em cenários complexos. Para os propósitos desta documentação, vamos considerar este trecho de HTML:

```html
<ol id="vegetables">
 <li class="potatoes">…
 <li class="onions">…
 <li class="tomatoes"><span>O tomate é um vegetal</span>…
</ol>
<ul id="fruits">
  <li class="bananas">…
  <li class="apples">…
  <li class="tomatoes"><span>O tomate é uma fruta</span>…
</ul>
```

```java
WebElement vegetable = driver.findElement(By.className("tomatoes"));
  
```

```python
vegetable = driver.find_element(By.CLASS_NAME, "tomatoes")
  
```

```csharp
var vegetable = driver.FindElement(By.ClassName("tomatoes"));
  
```

```rb
      driver.find_element(class: 'tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L10)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const vegetable = await driver.findElement(By.className('tomatoes'));
  
```

```kotlin
val vegetable: WebElement = driver.findElement(By.className("tomatoes"))
  
```

```java
WebElement fruits = driver.findElement(By.id("fruits"));
WebElement fruit = fruits.findElement(By.className("tomatoes"));
  
```

```python
fruits = driver.find_element(By.ID, "fruits")
fruit = fruits.find_element(By.CLASS_NAME,"tomatoes")
  
```

```csharp
IWebElement fruits = driver.FindElement(By.Id("fruits"));
IWebElement fruit = fruits.FindElement(By.ClassName("tomatoes"));
  
```

```rb
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L14-L15)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const fruits = await driver.findElement(By.id('fruits'));
const fruit = fruits.findElement(By.className('tomatoes'));
  
```

```kotlin
val fruits = driver.findElement(By.id("fruits"))
val fruit = fruits.findElement(By.className("tomatoes"))
  
```

```java
WebElement shadowHost = driver.findElement(By.cssSelector("#shadow_host"));
SearchContext shadowRoot = shadowHost.getShadowRoot();
WebElement shadowContent = shadowRoot.findElement(By.cssSelector("#shadow_content"));
```

```python
shadow_host = driver.find_element(By.CSS_SELECTOR, '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(By.CSS_SELECTOR, '#shadow_content')
```

```csharp
var shadowHost = _driver.FindElement(By.CssSelector("#shadow_host"));
var shadowRoot = shadowHost.GetShadowRoot();
var shadowContent = shadowRoot.FindElement(By.CssSelector("#shadow_content"));
```

```ruby
shadow_host = @driver.find_element(css: '#shadow_host')
shadow_root = shadow_host.shadow_root
shadow_content = shadow_root.find_element(css: '#shadow_content')
```

```java
WebElement fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"));
  
```

```python
fruit = driver.find_element(By.CSS_SELECTOR,"#fruits .tomatoes")
  
```

```csharp
var fruit = driver.FindElement(By.CssSelector("#fruits .tomatoes"));
  
```

```rb
      driver.find_element(css: '#fruits .tomatoes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L19)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const fruit = await driver.findElement(By.css('#fruits .tomatoes'));
  
```

```kotlin
val fruit = driver.findElement(By.cssSelector("#fruits .tomatoes"))
  
```

```java
List<WebElement> plants = driver.findElements(By.tagName("li"));
  
```

```python
plants = driver.find_elements(By.TAG_NAME, "li")
  
```

```csharp
IReadOnlyList<IWebElement> plants = driver.FindElements(By.TagName("li"));
  
```

```rb
      driver.find_elements(tag_name: 'li')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L23)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Finders' do
  let(:driver) { start_session }

  context 'without executing finders', skip: 'these are just examples, not actual tests' do
    it 'finds the first matching element' do
      driver.find_element(class: 'tomatoes')
    end

    it 'uses a subset of the dom to find an element' do
      fruits = driver.find_element(id: 'fruits')
      fruits.find_element(class: 'tomatoes')
    end

    it 'uses an optimized locator' do
      driver.find_element(css: '#fruits .tomatoes')
    end

    it 'finds all matching elements' do
      driver.find_elements(tag_name: 'li')
    end

    it 'gets an element from a collection' do
      elements = driver.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'finds element from element' do
      element = driver.find_element(:tag_name, 'div')
      elements = element.find_elements(:tag_name, 'p')
      elements.each { |e| puts e.text }
    end

    it 'find active element' do
      driver.find_element(css: '[name="q"]').send_keys('webElement')
      driver.switch_to.active_element.attribute('title')
    end
  end
end
```

```javascript
const plants = await driver.findElements(By.tagName('li'));
  
```

```kotlin
val plants: List<WebElement> = driver.findElements(By.tagName("li"))
  
```

```java
List<WebElement> elements = driver.findElements(By.tagName("li"));

for (WebElement element : elements) {
    System.out.println("Paragraph text:" + element.getText());
}
  
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Firefox()

    # Navegar até a URL
driver.get("https://www.example.com")

    # Obtém todos os elementos disponiveis com o nome da tag 'p'
elements = driver.find_elements(By.TAG_NAME, 'p')

for e in elements:
    print(e.text)
  
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using System.Collections.Generic;

namespace FindElementsExample {
 class FindElementsExample {
  public static void Main(string[] args) {
   IWebDriver driver = new FirefoxDriver();
   try {
    // Navegar até a URL
    driver.Navigate().GoToUrl("https://example.com");

    // Obtém todos os elementos disponiveis com o nome da tag 'p'
    IList < IWebElement > elements = driver.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }

   } finally {
    driver.Quit();
   }
  }
 }
}
  
```

```rb
      elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L27-L28)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
   
   require 'spec_helper'
   
   RSpec.describe 'Element Finders' do
     let(:driver) { start_session }
   
     context 'without executing finders', skip: 'these are just examples, not actual tests' do
       it 'finds the first matching element' do
         driver.find_element(class: 'tomatoes')
       end
   
       it 'uses a subset of the dom to find an element' do
         fruits = driver.find_element(id: 'fruits')
         fruits.find_element(class: 'tomatoes')
       end
   
       it 'uses an optimized locator' do
         driver.find_element(css: '#fruits .tomatoes')
       end
   
       it 'finds all matching elements' do
         driver.find_elements(tag_name: 'li')
       end
   
       it 'gets an element from a collection' do
         elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'finds element from element' do
         element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'find active element' do
         driver.find_element(css: '[name="q"]').send_keys('webElement')
         driver.switch_to.active_element.attribute('title')
       end
     end
   end
   
```

```javascript
const {Builder, By} = require('selenium-webdriver');
(async function example() {
    let driver = await new Builder().forBrowser('firefox').build();
    try {
        // Navegar até a URL
        await driver.get('https://www.example.com');

        // Obtém todos os elementos disponiveis com o nome da tag 'p'
        let elements = await driver.findElements(By.css('p'));
        for(let e of elements) {
            console.log(await e.getText());
        }
    }
    finally {
        await driver.quit();
    }
})();
  
```

```kotlin
import org.openqa.selenium.By
import org.openqa.selenium.firefox.FirefoxDriver

fun main() {
    val driver = FirefoxDriver()
    try {
        driver.get("https://example.com")
        // Obtém todos os elementos disponiveis com o nome da tag 'p'
        val elements = driver.findElements(By.tagName("p"))
        for (element in elements) {
            println("Paragraph text:" + element.text)
        }
    } finally {
        driver.quit()
    }
}
  
```

```java
  import org.openqa.selenium.By;
  import org.openqa.selenium.WebDriver;
  import org.openqa.selenium.WebElement;
  import org.openqa.selenium.chrome.ChromeDriver;
  import java.util.List;

  public class findElementsFromElement {
      public static void main(String[] args) {
          WebDriver driver = new ChromeDriver();
          try {
              driver.get("https://example.com");

              // Obtém o elemento com o nome da tag 'div'
              WebElement element = driver.findElement(By.tagName("div"));

              // Obtém todos os elementos disponiveis com o nome da tag 'p'
              List<WebElement> elements = element.findElements(By.tagName("p"));
              for (WebElement e : elements) {
                  System.out.println(e.getText());
              }
          } finally {
              driver.quit();
          }
      }
  }
  
```

```python
##get elements from parent element using TAG_NAME

    # Obtém o elemento com o nome da tag 'div'
element = driver.find_element(By.TAG_NAME, 'div')

    # Obtém todos os elementos disponíveis com o nome da tag 'p'
elements = element.find_elements(By.TAG_NAME, 'p')
for e in elements:
    print(e.text)

##get elements from parent element using XPATH
##NOTE: in order to utilize XPATH from current element, you must add "." to beginning of path

    # Get first element of tag 'ul'
element = driver.find_element(By.XPATH, '//ul')

    # get children of tag 'ul' with tag 'li'
elements  = element.find_elements(By.XPATH, './/li')
for e in elements:
    print(e.text)
  
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace FindElementsFromElement {
 class FindElementsFromElement {
  public static void Main(string[] args) {
   IWebDriver driver = new ChromeDriver();
   try {
    driver.Navigate().GoToUrl("https://example.com");

    // Obtém o elemento com o nome da tag 'div'
    IWebElement element = driver.FindElement(By.TagName("div"));

    // Obtém todos os elementos disponíveis com o nome da tag 'p'
    IList < IWebElement > elements = element.FindElements(By.TagName("p"));
    foreach(IWebElement e in elements) {
     System.Console.WriteLine(e.Text);
    }
   } finally {
    driver.Quit();
   }
  }
 }
}
  
```

```rb
      element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L32-L34)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
   
   require 'spec_helper'
   
   RSpec.describe 'Element Finders' do
     let(:driver) { start_session }
   
     context 'without executing finders', skip: 'these are just examples, not actual tests' do
       it 'finds the first matching element' do
         driver.find_element(class: 'tomatoes')
       end
   
       it 'uses a subset of the dom to find an element' do
         fruits = driver.find_element(id: 'fruits')
         fruits.find_element(class: 'tomatoes')
       end
   
       it 'uses an optimized locator' do
         driver.find_element(css: '#fruits .tomatoes')
       end
   
       it 'finds all matching elements' do
         driver.find_elements(tag_name: 'li')
       end
   
       it 'gets an element from a collection' do
         elements = driver.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'finds element from element' do
         element = driver.find_element(:tag_name, 'div')
         elements = element.find_elements(:tag_name, 'p')
         elements.each { |e| puts e.text }
       end
   
       it 'find active element' do
         driver.find_element(css: '[name="q"]').send_keys('webElement')
         driver.switch_to.active_element.attribute('title')
       end
     end
   end
   
```

```javascript
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = new Builder()
          .forBrowser('chrome')
          .build();

      await driver.get('https://www.example.com');

      //  Obtém o elemento com o nome da tag 'div'
      let element = driver.findElement(By.css("div"));

      // Obtém todos os elementos disponíveis com o nome da tag 'p'
      let elements = await element.findElements(By.css("p"));
      for(let e of elements) {
          console.log(await e.getText());
      }
  })();
  
```

```kotlin
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://example.com")

           // Obtém o elemento com o nome da tag 'div'
          val element = driver.findElement(By.tagName("div"))

          // Obtém todos os elementos disponíveis com o nome da tag 'p'
          val elements = element.findElements(By.tagName("p"))
          for (e in elements) {
              println(e.text)
          }
      } finally {
          driver.quit()
      }
  }
  
```

```java
  import org.openqa.selenium.*;
  import org.openqa.selenium.chrome.ChromeDriver;

  public class activeElementTest {
    public static void main(String[] args) {
      WebDriver driver = new ChromeDriver();
      try {
        driver.get("http://www.google.com");
        driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement");

        // Obter atributo do elemento atualmente ativo
        String attr = driver.switchTo().activeElement().getAttribute("title");
        System.out.println(attr);
      } finally {
        driver.quit();
      }
    }
  }
  
```

```python
  from selenium import webdriver
  from selenium.webdriver.common.by import By

  driver = webdriver.Chrome()
  driver.get("https://www.google.com")
  driver.find_element(By.CSS_SELECTOR, '[name="q"]').send_keys("webElement")

    # Obter atributo do elemento atualmente ativo
  attr = driver.switch_to.active_element.get_attribute("title")
  print(attr)
  
```

```csharp
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;

    namespace ActiveElement {
     class ActiveElement {
      public static void Main(string[] args) {
       IWebDriver driver = new ChromeDriver();
       try {
        // Navegar até a URL
        driver.Navigate().GoToUrl("https://www.google.com");
        driver.FindElement(By.CssSelector("[name='q']")).SendKeys("webElement");

        // Obter atributo do elemento atualmente ativo
        string attr = driver.SwitchTo().ActiveElement().GetAttribute("title");
        System.Console.WriteLine(attr);
       } finally {
        driver.Quit();
       }
      }
     }
    }
  
```

```rb
      driver.find_element(css: '[name="q"]').send_keys('webElement')
        driver.switch_to.active_element.attribute('title')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/finders_spec.rb#L38-L39)

##### /examples/ruby/spec/elements/finders\_spec.rb

```rb
# frozen_string_literal: true
  
  require 'spec_helper'
  
  RSpec.describe 'Element Finders' do
    let(:driver) { start_session }
  
    context 'without executing finders', skip: 'these are just examples, not actual tests' do
      it 'finds the first matching element' do
        driver.find_element(class: 'tomatoes')
      end
  
      it 'uses a subset of the dom to find an element' do
        fruits = driver.find_element(id: 'fruits')
        fruits.find_element(class: 'tomatoes')
      end
  
      it 'uses an optimized locator' do
        driver.find_element(css: '#fruits .tomatoes')
      end
  
      it 'finds all matching elements' do
        driver.find_elements(tag_name: 'li')
      end
  
      it 'gets an element from a collection' do
        elements = driver.find_elements(:tag_name, 'p')
        elements.each { |e| puts e.text }
      end
  
      it 'finds element from element' do
        element = driver.find_element(:tag_name, 'div')
        elements = element.find_elements(:tag_name, 'p')
        elements.each { |e| puts e.text }
      end
  
      it 'find active element' do
        driver.find_element(css: '[name="q"]').send_keys('webElement')
        driver.switch_to.active_element.attribute('title')
      end
    end
  end
  
```

```javascript
  const {Builder, By} = require('selenium-webdriver');

  (async function example() {
      let driver = await new Builder().forBrowser('chrome').build();
      await driver.get('https://www.google.com');
      await  driver.findElement(By.css('[name="q"]')).sendKeys("webElement");

      // Obter atributo do elemento atualmente ativo
      let attr = await driver.switchTo().activeElement().getAttribute("title");
      console.log(`${attr}`)
  })();
  
```

```kotlin
  import org.openqa.selenium.By
  import org.openqa.selenium.chrome.ChromeDriver

  fun main() {
      val driver = ChromeDriver()
      try {
          driver.get("https://www.google.com")
          driver.findElement(By.cssSelector("[name='q']")).sendKeys("webElement")

          // Obter atributo do elemento atualmente ativo
          val attr = driver.switchTo().activeElement().getAttribute("title")
          print(attr)
      } finally {
          driver.quit()
      }
  }
  
```

# 2 - Interacting with web elements

```java
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L18-L22)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L12-L17)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L17-L21)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'color_input').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L11)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
    await submitButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L20)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
  const assert = require("assert");
  
  (async function firstTest() {
    let driver;
    
    try {
      driver = await new Builder().forBrowser(Browser.CHROME).build();
      await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
    
      let title = await driver.getTitle();
      assert.equal("Web form", title);
    
      await driver.manage().setTimeouts({implicit: 500});
    
      let textBox = await driver.findElement(By.name('my-text'));
      let submitButton = await driver.findElement(By.css('button'));
    
      await textBox.sendKeys('Selenium');
      await submitButton.click();
    
      let message = await driver.findElement(By.id('message'));
      let value = await message.getText();
      assert.equal("Received!", value);
    } catch (e) {
      console.log(e)
    } finally {
      await driver.quit();
    }
  }())
  
```

```kotlin
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    // Click the element
    driver.findElement(By.name("color_input")).click();
  
  
```

```java
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L27-L32)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L22-L27)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L27-L33)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L16)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
      let inputField = await driver.findElement(By.name('no_type'));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/interactions.spec.js#L21)

##### /examples/javascript/test/elements/interactions.spec.js

```js

  const {By, Browser, Builder} = require('selenium-webdriver');
  const assert = require("node:assert");
  
  
  describe('Element Interactions', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('should Clear input and send keys into input field', async function () {
  
      try {
        await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
        let inputField = await driver.findElement(By.name('no_type'));
        await inputField.clear();
        await inputField.sendKeys('Selenium');
        const text = await inputField.getAttribute('value');
        assert.strictEqual(text, "Selenium");
      } catch (e) {
        console.log(e)
      }
    });
  });
```

```kotlin
  
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

	//Clear field to empty it from any previous data
	driver.findElement(By.name("email_input")).clear()
	
    // Enter text 
    driver.findElement(By.name("email_input")).sendKeys("admin@localhost.dev")
  
  
```

```java
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InteractionTest.java#L38-L40)

##### /examples/java/src/test/java/dev/selenium/elements/InteractionTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class InteractionTest {

    @Test
    public void interactWithElements() {
        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // Click on the element
        WebElement checkInput = driver.findElement(By.name("checkbox_input"));
        checkInput.click();
        Boolean isChecked = checkInput.isSelected();
        assertEquals(isChecked, false);

        // SendKeys
        // Clear field to empty it from any previous data
        WebElement emailInput = driver.findElement(By.name("email_input"));
        emailInput.clear();
        // Enter Text
        String email = "admin@localhost.dev";
        emailInput.sendKeys(email);
        // Verify
        String data = emailInput.getAttribute("value");
        assertEquals(data, email);

        // Clear Element
        // Clear field to empty it from any previous data
        emailInput.clear();
        data = emailInput.getAttribute("value");
        assertEquals(data, "");

        driver.quit();
    }
}
```

```py
    email_input.clear()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_interaction.py#L34)

##### /examples/python/tests/elements/test\_interaction.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_interactions():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    # Navigate to URL
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # Click on the checkbox
    check_input = driver.find_element(By.NAME, "checkbox_input")
    check_input.click()

    is_checked = check_input.is_selected()
    assert is_checked == False

    # Handle the email input field
    email_input = driver.find_element(By.NAME, "email_input")
    email_input.clear()  # Clear field
    
    email = "admin@localhost.dev"
    email_input.send_keys(email)  # Enter text

    # Verify input
    data = email_input.get_attribute("value")
    assert data == email

    # Clear the email input field again
    email_input.clear()
    data = email_input.get_attribute("value")
    assert data == ""

    # Quit the driver
    driver.quit()
```

```cs
            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs#L40-L43)

##### /examples/dotnet/SeleniumDocs/Elements/InteractionTest.cs

```cs
using System;
	using Microsoft.VisualStudio.TestTools.UnitTesting;
	using OpenQA.Selenium;
	using OpenQA.Selenium.Chrome;
	
	namespace SeleniumDocs.Elements
	{
	    [TestClass]
	    public class InteractionTest
	    {
	        [TestMethod]
	        public void TestInteractionCommands()
	        {
	            IWebDriver driver = new ChromeDriver();
	            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
	
	            // Navigate to Url
	            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/inputs.html");
	            // Click on the element 
	            IWebElement checkInput = driver.FindElement(By.Name("checkbox_input"));
	            checkInput.Click();
	
	            //Verify
	            Boolean isChecked = checkInput.Selected;
	            Assert.AreEqual(isChecked, false);
	
	            //SendKeys
	            // Clear field to empty it from any previous data
	            IWebElement emailInput = driver.FindElement(By.Name("email_input"));
	            emailInput.Clear();
	            //Enter Text
	            String email = "admin@localhost.dev";
	            emailInput.SendKeys(email);
	
	            //Verify
	            String data = emailInput.GetAttribute("value");
	            Assert.AreEqual(data, email);
	
	
	            //Clear Element
	            // Clear field to empty it from any previous data
	            emailInput.Clear();
	            data = emailInput.GetAttribute("value");
	            
	            //Verify
	            Assert.AreEqual(data, "");
	
	            //Quit the browser
	            driver.Quit();
	        }
	    }
	}
```

```rb
    driver.find_element(name: 'email_input').clear
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/interaction_spec.rb#L15)

##### /examples/ruby/spec/elements/interaction\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Interaction' do
  let(:driver) { start_session }

  before { driver.get 'https://www.selenium.dev/selenium/web/inputs.html' }

  it 'clicks an element' do
    driver.find_element(name: 'color_input').click
  end

  it 'clears and send keys to an element' do
    driver.find_element(name: 'email_input').clear
    driver.find_element(name: 'email_input').send_keys 'admin@localhost.dev'
  end
end
```

```js
      await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/interactions.spec.js#L20)

##### /examples/javascript/test/elements/interactions.spec.js

```js

  const {By, Browser, Builder} = require('selenium-webdriver');
  const assert = require("node:assert");
  
  
  describe('Element Interactions', function () {
    let driver;
  
    before(async function () {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('should Clear input and send keys into input field', async function () {
  
      try {
        await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
        let inputField = await driver.findElement(By.name('no_type'));
        await inputField.clear();
        await inputField.sendKeys('Selenium');
        const text = await inputField.getAttribute('value');
        assert.strictEqual(text, "Selenium");
      } catch (e) {
        console.log(e)
      }
    });
  });
```

```kotlin
  
    // Navigate to Url
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

	//Clear field to empty it from any previous data
	driver.findElement(By.name("email_input")).clear()
	
  
  
```

## Submit

In Selenium 4 this is no longer implemented with a separate endpoint and functions by executing a script. As such, it is recommended not to use this method and to click the applicable form submission button instead.

# 3 - Information about web elements

```java
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L27-L29)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L12-L15)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L18-L22)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    displayed_value = driver.find_element(name: 'email_input').displayed?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L12)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L16-L17)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
 driver.get("https://www.selenium.dev/selenium/web/inputs.html")

 //returns true if element is displayed else returns false
 val flag = driver.findElement(By.name("email_input")).isDisplayed()
```

```java
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L32-L34)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L19)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L25-L27)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    enabled_value = driver.find_element(name: 'email_input').enabled?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L17)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L23-L24)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//returns true if element is enabled else returns false
val attr = driver.findElement(By.name("button_input")).isEnabled()
```

```java
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L37-L39)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L23)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L30-L32)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    selected_value = driver.find_element(name: 'email_input').selected?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L22)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L30-L31)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
 //navigates to url
 driver.get("https://www.selenium.dev/selenium/web/inputs.html")

 //returns true if element is checked else returns false
 val attr =  driver.findElement(By.name("checkbox_input")).isSelected()
```

```java
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L42-L44)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L27)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L35-L37)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    tag_name = driver.find_element(name: 'email_input').tag_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L27)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L37-L38)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//returns TagName of the element
val attr =  driver.findElement(By.name("email_input")).getTagName()
```

```java
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L47-L50)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    rect = driver.find_element(By.NAME, "range_input").rect
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L31)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L40-L43)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    size = driver.find_element(name: 'email_input').size
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L32)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    let object = await driver.findElement(By.name('range_input')).getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L45)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

// Returns height, width, x and y coordinates referenced element
val res = driver.findElement(By.name("range_input")).rect

// Rectangle class provides getX,getY, getWidth, getHeight methods
println(res.getX())
```

```java
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L52-L54)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L35-L37)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L49-L50)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L38)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L76-L78)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to Url
driver.get("https://www.selenium.dev/selenium/web/colorPage.html")

// Retrieves the computed style property 'color' of linktext
val cssValue = driver.findElement(By.id("namedColor")).getCssValue("background-color")
```

```java
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L58-L60)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    text = driver.find_element(By.TAG_NAME, "h1").text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L41)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L53-L55)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    text = driver.find_element(xpath: '//h1').text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L43)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L84-L86)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to URL
driver.get("https://www.selenium.dev/selenium/web/linked_image.html")

// retrieves the text of the element
val text = driver.findElement(By.id("justanotherlink")).getText()
```

```java
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L64-L68)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L44-L46)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L58-L62)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L48)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L55-L59)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to URL
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//fetch the value property associated with the textbox
val attr = driver.findElement(By.name("email_input")).getAttribute("value")
```

# 4 - Localizando elementos

Formas de identificar um ou mais elementos no DOM.

Um localizador é uma forma de identificar elementos numa página. São os argumentos passados aos métodos [Finders](https://www.selenium.dev/pt-br/documentation/webdriver/elements/finders/) .

Visite os nossas [directrizes e recomendações](https://www.selenium.dev/pt-br/documentation/test_practices/encouraged/) para dicas sobre [locators](https://www.selenium.dev/pt-br/documentation/test_practices/encouraged/locators/), incluindo quais usar e quando, e também porque é que deve declarar localizadores separadamente dos finders.

### Estratégias de seleção de elemento

Existem oito estratégias diferentes de localização de elementos embutidas no WebDriver:

| Localizador       | Descrição                                                                                                                                               |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| class name        | Localiza elementos cujo nome de classe contém o valor de pesquisa (nomes de classes compostas não são permitidos)                                       |
| css selector      | Localiza elementos que correspondem a um seletor CSS                                                                                                    |
| id                | Localiza elementos cujo atributo de ID corresponde ao valor de pesquisa                                                                                 |
| name              | Localiza elementos cujo atributo NAME corresponde ao valor de pesquisa                                                                                  |
| link text         | Localiza elementos âncora cujo texto visível corresponde ao valor de pesquisa                                                                           |
| partial link text | Localiza elementos âncora cujo texto visível contém o valor da pesquisa. Se vários elementos forem correspondentes, apenas o primeiro será selecionado. |
| tag name          | Localiza elementos cujo nome de tag corresponde ao valor de pesquisa                                                                                    |
| xpath             | Localiza elementos que correspondem a uma expressão XPath                                                                                               |

## Creating Locators

To work on a web element using Selenium, we need to first locate it on the web page. Selenium provides us above mentioned ways, using which we can locate element on the page. To understand and create locator we will use the following HTML snippet.

```html
<html>
<body>
<style>
.information {
  background-color: white;
  color: black;
  padding: 10px;
}
</style>
<h2>Contact Selenium</h2>

<form>
  <input type="radio" name="gender" value="m" />Male &nbsp;
  <input type="radio" name="gender" value="f" />Female <br>
  <br>
  <label for="fname">First name:</label><br>
  <input class="information" type="text" id="fname" name="fname" value="Jane"><br><br>
  <label for="lname">Last name:</label><br>
  <input class="information" type="text" id="lname" name="lname" value="Doe"><br><br>
  <label for="newsletter">Newsletter:</label>
  <input type="checkbox" name="newsletter" value="1" /><br><br>
  <input type="submit" value="Submit">
</form> 

<p>To know more about Selenium, visit the official page 
<a href ="www.selenium.dev">Selenium Official Page</a> 
</p>

</body>
</html>
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L31" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L7-L9)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.ClassName("information"));
  
```

```rb
    driver.find_element(class: 'information')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L7)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.className('information'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.className("information"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L38" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L17-L19)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.CssSelector("#fname"));
  
```

```rb
    driver.find_element(css: '#fname')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L11)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.css('#fname'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.css("#fname"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L45" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L27-L29)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.Id("lname"));
  
```

```rb
    driver.find_element(id: 'lname')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L15)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.id('lname'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.id("lname"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L52" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L37-L39)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.Name("newsletter"));
  
```

```rb
    driver.find_element(name: 'newsletter')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L19)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.name('newsletter'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.name("newsletter"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L59" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L47-L49)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.LinkText("Selenium Official Page"));
  
```

```rb
    driver.find_element(link_text: 'Selenium Official Page')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L23)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.linkText('Selenium Official Page'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.linkText("Selenium Official Page"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L66" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L57-L59)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.PartialLinkText("Official Page"));
  
```

```rb
    driver.find_element(partial_link_text: 'Official Page')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L27)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.partialLinkText('Official Page'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.partialLinkText("Official Page"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L73" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L67-L69)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.TagName("a"));
  
```

```rb
    driver.find_element(tag_name: 'a')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L31)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.tagName('a'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.tagName("a"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L80" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L77-L79)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.Xpath("//input[@value='f']"));
  
```

```rb
    driver.find_element(xpath: "//input[@value='f']")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L35)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.xpath('//input[@value='f']'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.xpath('//input[@value='f']'))
  
```

```java
    import org.openqa.selenium.By;
    WebDriver driver = new ChromeDriver();
	driver.findElement(By.className("information"));
  
```

```python
    from selenium.webdriver.common.by import By
    driver = webdriver.Chrome()
	driver.find_element(By.CLASS_NAME, "information")
  
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.ClassName("information"));
  
```

```rb
    driver.find_element(class: 'information')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L7)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.className('information'));
  
```

```kotlin
    import org.openqa.selenium.By
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.className("information"))
  
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java#L37-L38)

##### /examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java

```java
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java#L22-L23)

##### /examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java

```java
```

```java
By emailLocator = RelativeLocator.with(By.tagName("input")).above(By.id("password"));
```

```python
email_locator = locate_with(By.TAG_NAME, "input").above({By.ID: "password"})
```

```csharp
var emailLocator = RelativeBy.WithLocator(By.TagName("input")).Above(By.Id("password"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L40)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let emailLocator = locateWith(By.tagName('input')).above(By.id('password'));
```

```kotlin
val emailLocator = RelativeLocator.with(By.tagName("input")).above(By.id("password"))
```

```java
By passwordLocator = RelativeLocator.with(By.tagName("input")).below(By.id("email"));
```

```python
password_locator = locate_with(By.TAG_NAME, "input").below({By.ID: "email"})
```

```csharp
var passwordLocator = RelativeBy.WithLocator(By.TagName("input")).Below(By.Id("email"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L44)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let passwordLocator = locateWith(By.tagName('input')).below(By.id('email'));
```

```kotlin
val passwordLocator = RelativeLocator.with(By.tagName("input")).below(By.id("email"))
```

```java
By cancelLocator = RelativeLocator.with(By.tagName("button")).toLeftOf(By.id("submit"));
```

```python
cancel_locator = locate_with(By.TAG_NAME, "button").to_left_of({By.ID: "submit"})
```

```csharp
var cancelLocator = RelativeBy.WithLocator(By.tagName("button")).LeftOf(By.Id("submit"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L48)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let cancelLocator = locateWith(By.tagName('button')).toLeftOf(By.id('submit'));
```

```kotlin
val cancelLocator = RelativeLocator.with(By.tagName("button")).toLeftOf(By.id("submit"))
```

```java
By submitLocator = RelativeLocator.with(By.tagName("button")).toRightOf(By.id("cancel"));
```

```python
submit_locator = locate_with(By.TAG_NAME, "button").to_right_of({By.ID: "cancel"})
```

```csharp
var submitLocator = RelativeBy.WithLocator(By.tagName("button")).RightOf(By.Id("cancel"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L52)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let submitLocator = locateWith(By.tagName('button')).toRightOf(By.id('cancel'));
```

```kotlin
val submitLocator = RelativeLocator.with(By.tagName("button")).toRightOf(By.id("cancel"))
```

```java
By emailLocator = RelativeLocator.with(By.tagName("input")).near(By.id("lbl-email"));
```

```python
email_locator = locate_with(By.TAG_NAME, "input").near({By.ID: "lbl-email"})
```

```csharp
var emailLocator = RelativeBy.WithLocator(By.tagName("input")).Near(By.Id("lbl-email"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L56)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let emailLocator = locateWith(By.tagName('input')).near(By.id('lbl-email'));
```

```kotlin
val emailLocator = RelativeLocator.with(By.tagName("input")).near(By.id("lbl-email"));
```

```java
By submitLocator = RelativeLocator.with(By.tagName("button")).below(By.id("email")).toRightOf(By.id("cancel"));
```

```python
submit_locator = locate_with(By.TAG_NAME, "button").below({By.ID: "email"}).to_right_of({By.ID: "cancel"})
```

```csharp
var submitLocator = RelativeBy.WithLocator(By.tagName("button")).Below(By.Id("email")).RightOf(By.Id("cancel"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L60)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let submitLocator = locateWith(By.tagName('button')).below(By.id('email')).toRightOf(By.id('cancel'));
```

```kotlin
val submitLocator = RelativeLocator.with(By.tagName("button")).below(By.id("email")).toRightOf(By.id("cancel"))
```

# 5 - File Upload

```java
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/FileUploadTest.java#L17-L19)

##### /examples/java/src/test/java/dev/selenium/elements/FileUploadTest.java

```java
package dev.selenium.elements;

import dev.selenium.BaseChromeTest;
import java.io.File;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;

public class FileUploadTest extends BaseChromeTest {

  @Test
  public void fileUploadTest() {
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }
}
```

```py
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_file_upload.py#L12-L14)

##### /examples/python/tests/elements/test\_file\_upload.py

```py
import os

from selenium import webdriver
from selenium.webdriver.common.by import By


def test_uploads(driver):
    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"
```

```cs
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/FileUploadTest.cs#L21-L23)

##### /examples/dotnet/SeleniumDocs/Elements/FileUploadTest.cs

```cs
using System;
using System.IO;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;

namespace SeleniumDocs.Elements
{
    [TestClass]
    public class FileUploadTest : BaseChromeTest
    {
        [TestMethod]
        public void Uploads()
        {
            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }
    }
}
```

```rb
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/file_upload_spec.rb#L12-L14)

##### /examples/ruby/spec/elements/file\_upload\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'File Upload' do
  let(:driver) { start_session }

  it 'uploads' do
    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    file_name = driver.find_element(id: 'uploaded-files')
    expect(file_name.text).to eq 'selenium-snapshot.png'
  end
end
```

```js
    await driver.get('https://the-internet.herokuapp.com/upload');
    // Upload snapshot
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/fileUpload.spec.js#L24-L25)

##### /examples/javascript/test/elements/fileUpload.spec.js

```js

const {Browser, By, until, Builder} = require("selenium-webdriver");
const path = require("path");
const assert = require('node:assert');


describe('File Upload Test', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async() => await driver.quit());

  it('Should be able to upload a file successfully', async function() {
    const image = path.resolve('./test/resources/selenium-snapshot.png')

    await driver.manage().setTimeouts({implicit: 5000});

    // Navigate to URL
    await driver.get('https://the-internet.herokuapp.com/upload');
    // Upload snapshot
    await driver.findElement(By.id("file-upload")).sendKeys(image);
    await driver.findElement(By.id("file-submit")).submit();

    const revealed = await driver.findElement(By.id('uploaded-files'))
    await driver.wait(until.elementIsVisible(revealed), 2000);
    const data = await driver.findElement(By.css('h3'));

    assert.equal(await data.getText(), `File Uploaded!`);
  });
});
```

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/bidi/w3c/
----

# BiDirectional API (W3C compliant)

The following list of APIs will be growing as the [WebDriver BiDirectional Protocol](https://w3c.github.io/webdriver-bidi/) 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](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=\&template=feature.md).

***

##### [Browsing Context](/zh-cn/documentation/webdriver/bidi/w3c/browsing_context/)

##### [Browsing Context](/zh-cn/documentation/webdriver/bidi/w3c/input/)

##### [Network](/zh-cn/documentation/webdriver/bidi/w3c/network/)

##### [Script](/zh-cn/documentation/webdriver/bidi/w3c/script/)

##### [BiDirectional API (W3C compliant)](/zh-cn/documentation/webdriver/bidi/w3c/log/)

----
url: https://www.selenium.dev/zh-cn/_print/documentation/grid/configuration/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/grid/configuration/).

# 配置组件

在这里，您可以看到如何根据公共配置值和特定于组件的配置值分别配置每个网格组件.

* 1: [配置帮助](#pg-93fa084268206a9aa52621f65987bf76)
* 2: [CLI 选项](#pg-4eef2fd47f890b3bd4246fa0b9f9e349)
* 3: [Toml配置选项](#pg-9908b5b7f21b6519e90ed597e0ccd1e4)

# 1 - 配置帮助

```shell
java -jar selenium-server-<version>.jar info config
```

### 安全

获取构建网格服务器的详细信息, 用于安全通信和节点注册.

```shell
java -jar selenium-server-<version>.jar info security
```

### 会话表配置

默认情况下, 网格使用本地会话表来存储会话信息. 网格支持额外的存储选项, 比如Redis和JDBC-SQL支持的数据库. 要设置不同的会话存储, 请使用以下命令获取设置步骤:

```shell
java -jar selenium-server-<version>.jar info sessionmap
```

### 基于OpenTelemetry和Jaeger的追踪配置

默认情况下, 追踪是启用的. 要通过Jaeger导出追踪并将其可视化, 请使用以下命令进行说明:

```shell
java -jar selenium-server-<version>.jar info tracing
```

## 列出Selenium网格的命令

```shell
java -jar selenium-server-<version>.jar --config-help
```

上述命令将显示所有可用的命令及其描述.

## 组件帮助命令

在Selenium后面键入–help的配置选项, 以获取特定组件的配置信息.

### Standalone

```shell
java -jar selenium-server-<version>.jar standalone --help
```

### Hub

```shell
java -jar selenium-server-<version>.jar hub --help
```

### Sessions

```shell
java -jar selenium-server-<version>.jar sessions --help
```

### 队列器

```shell
java -jar selenium-server-<version>.jar sessionqueue --help
```

### Distributor

```shell
java -jar selenium-server-<version>.jar distributor --help
```

### Router

```shell
java -jar selenium-server-<version>.jar router --help
```

### Node

```shell
java -jar selenium-server-<version>.jar node --help
```

# 2 - CLI 选项

所有网格组件配置CLI选项的详细信息.

**Page being translated from English to Chinese. Do you speak Chinese? Help us to translate it by sending us pull requests!

Different sections are available to configure a Grid. Each section has options can be configured through command line arguments.

A complete description of the component to section mapping can be seen below.

Note that this documentation could be outdated if an option was modified or added but has not been documented yet. In case you bump into this situation, please check the [“Config help”](https://www.selenium.dev/zh-cn/documentation/grid/configuration/help/) section and feel free to send us a pull request updating this page.

## Sections

|                               | Standalone | Hub | Node | Distributor | Router | Sessions | SessionQueue |
| ----------------------------- | ---------- | --- | ---- | ----------- | ------ | -------- | ------------ |
| [Distributor](#distributor)   | **         | **  |      | **          | **     |          |              |
| [Docker](#docker)             | **         |     | **   |             |        |          |              |
| [Events](#events)             |            | **  | **   | **          |        | **       | **           |
| [Logging](#logging)           | **         | **  | **   | **          | **     | **       | **           |
| [Network](#network)           | **         | **  |      |             | **     |          |              |
| [Node](#node)                 | **         |     | **   |             |        |          |              |
| [Router](#router)             | **         | **  |      |             | **     |          |              |
| [Relay](#relay)               | **         |     | **   |             |        |          |              |
| [Server](#server)             | **         | **  | **   | **          | **     | **       | **           |
| [SessionQueue](#sessionqueue) | **         | **  |      | **          | **     |          | **           |
| [Sessions](#sessions)         |            |     |      | **          | **     | **       |              |

### Distributor

| Option                         | Type    | Value/Example                                                       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ------------------------------ | ------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--healthcheck-interval`       | int     | `120`                                                               | How often, in seconds, will the health check run for all Nodes. This ensures the server can ping all the Nodes successfully.                                                                                                                                                                                                                                                                                                                        |
| `--distributor`                | uri     | `http://localhost:5553`                                             | Url of the distributor.                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `--distributor-host`           | string  | `localhost`                                                         | Host on which the distributor is listening.                                                                                                                                                                                                                                                                                                                                                                                                         |
| `--distributor-implementation` | string  | `org.openqa.selenium.grid.distributor.local.LocalDistributor`       | Full class name of non-default distributor implementation                                                                                                                                                                                                                                                                                                                                                                                           |
| `--distributor-port`           | int     | `5553`                                                              | Port on which the distributor is listening.                                                                                                                                                                                                                                                                                                                                                                                                         |
| `--reject-unsupported-caps`    | boolean | `false`                                                             | Allow the Distributor to reject a request immediately if the Grid does not support the requested capability. Rejecting requests immediately is suitable for a Grid setup that does not spin up Nodes on demand.                                                                                                                                                                                                                                     |
| `--slot-matcher`               | string  | `org.openqa.selenium.grid.data.DefaultSlotMatcher`                  | Full class name of non-default slot matcher to use. This is used to determine whether a Node can support a particular session.                                                                                                                                                                                                                                                                                                                      |
| `--slot-selector`              | string  | `org.openqa.selenium.grid.distributor.selector.DefaultSlotSelector` | Full class name of non-default slot selector. This is used to select a slot in a Node once the Node has been matched.                                                                                                                                                                                                                                                                                                                               |
| `--newsession-threadpool-size` | int     | `24`                                                                | The Distributor uses a fixed-sized thread pool to create new sessions as it consumes new session requests from the queue. This allows configuring the size of the thread pool. The default value is no. of available processors \* 3. Note: If the no. of threads is way greater than the available processors it will not always increase the performance. A high number of threads causes more context switching which is an expensive operation. |
| `--purge-nodes-interval`       | int     | `30`                                                                | How often, in seconds, will the Distributor purge Nodes that have been down for a while. This is calculated based on the heartbeat received from a particular node.                                                                                                                                                                                                                                                                                 |

### Docker

| Option                      | Type      | Value/Example                                                     | Description                                                                                                                                                                                                                                                                                 |
| --------------------------- | --------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--docker-assets-path`      | string    | `/opt/selenium/assets`                                            | Absolute path where assets will be stored                                                                                                                                                                                                                                                   |
| `--docker-`                 | string\[] | `selenium/standalone-firefox:latest '{"browserName": "firefox"}'` | Docker configs which map image name to stereotype capabilities (example \`-D selenium/standalone-firefox:latest ‘{“browserName”: “firefox”}’)                                                                                                                                               |
| `--docker-devices`          | string\[] | `/dev/kvm:/dev/kvm`                                               | Exposes devices to a container. Each device mapping declaration must have at least the path of the device in both host and container separated by a colon like in this example: /device/path/in/host:/device/path/in/container                                                              |
| `--docker-host`             | string    | `localhost`                                                       | Host name where the Docker daemon is running                                                                                                                                                                                                                                                |
| `--docker-port`             | int       | `2375`                                                            | Port where the Docker daemon is running                                                                                                                                                                                                                                                     |
| `--docker-url`              | string    | `http://localhost:2375`                                           | URL for connecting to the Docker daemon                                                                                                                                                                                                                                                     |
| `--docker-video-image`      | string    | `selenium/video:latest`                                           | Docker image to be used when video recording is enabled                                                                                                                                                                                                                                     |
| `--docker-host-config-keys` | string\[] | `Dns DnsOptions DnsSearch ExtraHosts Binds`                       | Specify which docker host configuration keys should be passed to browser containers. Keys name can be found in the Docker API [documentation](https://docs.docker.com/engine/api/v1.41/#tag/Container/operation/ContainerCreate), or by running `docker inspect` the node-docker container. |

### Events

| Option                    | Type    | Value/Example                                      | Description                                                                                                                                                                                                                                                                         |
| ------------------------- | ------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--bind-bus`              | boolean | `false`                                            | Whether the connection string should be bound or connected. When true, the component will be bound to the Event Bus (as in the Event Bus will also be started by the component, typically by the Distributor and the Hub). When false, the component will connect to the Event Bus. |
| `--events-implementation` | string  | `org.openqa.selenium.events.zeromq.ZeroMqEventBus` | Full class name of non-default event bus implementation                                                                                                                                                                                                                             |
| `--publish-events`        | string  | `tcp://*:4442`                                     | Connection string for publishing events to the event bus                                                                                                                                                                                                                            |
| `--subscribe-events`      | string  | `tcp://*:4443`                                     | Connection string for subscribing to events from the event bus                                                                                                                                                                                                                      |

### Logging

| Option                   | Type    | Value/Example                                                                                                                                              | Description                                                                                                                                                            |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--http-logs`            | boolean | `false`                                                                                                                                                    | Enable http logging. Tracing should be enabled to log http logs.                                                                                                       |
| `--log-encoding`         | string  | `UTF-8`                                                                                                                                                    | Log encoding                                                                                                                                                           |
| `--log`                  | string  | Windows path example : `'\path\to\file\gridlog.log'` or `'C:\path\path\to\file\gridlog.log'` Linux/Unix/MacOS path example : `'/path/to/file/gridlog.log'` | File to write out logs. Ensure the file path is compatible with the operating system’s file path.                                                                      |
| `--log-level`            | string  | `“INFO”`                                                                                                                                                   | Log level. Default logging level is INFO. Log levels are described here <https://docs.oracle.com/en/java/javase/11/docs/api/java.logging/java/util/logging/Level.html> |
| `--plain-logs`           | boolean | `true`                                                                                                                                                     | Use plain log lines                                                                                                                                                    |
| `--structured-logs`      | boolean | `false`                                                                                                                                                    | Use structured logs                                                                                                                                                    |
| `--tracing`              | boolean | `true`                                                                                                                                                     | Enable trace collection                                                                                                                                                |
| `--log-timestamp-format` | string  | `HH:mm:ss.SSS`                                                                                                                                             | Allows the configure log timestamp format                                                                                                                              |

### Network

| Option           | Type    | Value/Example | Description                                                                                                          |
| ---------------- | ------- | ------------- | -------------------------------------------------------------------------------------------------------------------- |
| `--relax-checks` | boolean | `false`       | Relax checks on origin header and content type of incoming requests, in contravention of strict W3C spec compliance. |

### Node

| Option                           | Type      | Value/Example                                                                                                                                                                                                                                                              | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |   |
| -------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | - |
| `--detect-drivers`               | boolean   | `true`                                                                                                                                                                                                                                                                     | Autodetect which drivers are available on the current system, and add them to the Node.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |   |
| `--driver-configuration`         | string\[] | `display-name="Firefox Nightly" max-sessions=2 webdriver-path="/usr/local/bin/geckodriver" stereotype="{\"browserName\": \"firefox\", \"browserVersion\": \"86\", \"moz:firefoxOptions\": {\"binary\":\"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"` | List of configured drivers a Node supports. It is recommended to provide this type of configuration through a toml config file to improve readability                                                                                                                                                                                                                                                                                                                                                                                                                                                   |   |
| `--driver-factory`               | string\[] | `org.openqa.selenium.example.LynxDriverFactory '{"browserName": "lynx"}'`                                                                                                                                                                                                  | Mapping of fully qualified class name to a browser configuration that this matches against.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |   |
| `--driver-implementation`        | string\[] | `"firefox"`                                                                                                                                                                                                                                                                | Drivers that should be checked. If specified, will skip autoconfiguration.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |   |
| `--node-implementation`          | string    | `"org.openqa.selenium.grid.node.local.LocalNodeFactory"`                                                                                                                                                                                                                   | Full classname of non-default Node implementation. This is used to manage a session’s lifecycle.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |   |
| `--grid-url`                     | string    | `https://grid.example.com`                                                                                                                                                                                                                                                 | Public URL of the Grid as a whole (typically the address of the Hub or the Router)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |   |
| `--heartbeat-period`             | int       | `60`                                                                                                                                                                                                                                                                       | How often, in seconds, will the Node send heartbeat events to the Distributor to inform it that the Node is up.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |   |
| `--max-sessions`                 | int       | `8`                                                                                                                                                                                                                                                                        | Maximum number of concurrent sessions. Default value is the number of available processors.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |   |
| `--override-max-sessions`        | boolean   | `false`                                                                                                                                                                                                                                                                    | The # of available processors is the recommended max sessions value (1 browser session per processor). Setting this flag to true allows the recommended max value to be overwritten. Session stability and reliability might suffer as the host could run out of resources.                                                                                                                                                                                                                                                                                                                             |   |
| `--register-cycle`               | int       | `10`                                                                                                                                                                                                                                                                       | How often, in seconds, the Node will try to register itself for the first time to the Distributor.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |   |
| `--register-period`              | int       | `120`                                                                                                                                                                                                                                                                      | How long, in seconds, will the Node try to register to the Distributor for the first time. After this period is completed, the Node will not attempt to register again.                                                                                                                                                                                                                                                                                                                                                                                                                                 |   |
| `--session-timeout`              | int       | `300`                                                                                                                                                                                                                                                                      | Let X be the session-timeout in seconds. The Node will automatically kill a session that has not had any activity in the last X seconds. This will release the slot for other tests.                                                                                                                                                                                                                                                                                                                                                                                                                    |   |
| `--vnc-env-var`                  | string\[] | `SE_START_XVFB SE_START_VNC SE_START_NO_VNC`                                                                                                                                                                                                                               | Environment variable to check in order to determine if a vnc stream is available or not.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |   |
| `--no-vnc-port`                  | int       | `7900`                                                                                                                                                                                                                                                                     | If VNC is available, sets the port where the local noVNC stream can be obtained                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |   |
| `--drain-after-session-count`    | int       | `1`                                                                                                                                                                                                                                                                        | Drain and shutdown the Node after X sessions have been executed. Useful for environments like Kubernetes. A value higher than zero enables this feature.                                                                                                                                                                                                                                                                                                                                                                                                                                                |   |
| `--hub`                          | string    | `http://localhost:4444`                                                                                                                                                                                                                                                    | The address of the Hub in a Hub-and-Node configuration. Can be a hostname or IP address (`hostname`), in which case the Hub will be assumed to be `http://hostname:4444`, the `--grid-url` will be the same `--publish-events` will be `tcp://hostname:4442` and `--subscribe-events` will be `tcp://hostname:4443`. If `hostname` contains a port number, that will be used for `--grid-url` but the URIs for the event bus will remain the same. Any of these default values may be overridden but setting the correct flags. If the hostname has a protocol (such as `https`) that will be used too. |   |
| `--enable-cdp`                   | boolean   | `true`                                                                                                                                                                                                                                                                     | Enable CDP proxying in Grid. A Grid admin can disable CDP if the network does not allow websockets. True by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |   |
| `--enable-managed-downloads`     | boolean   | `false`                                                                                                                                                                                                                                                                    | This causes the Node to auto manage files downloaded for a given session on the Node.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |   |
| `--selenium-manager`             | boolean   | `false`                                                                                                                                                                                                                                                                    | When drivers are not available on the current system, use Selenium Manager. False by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |   |
| `--connection-limit-per-session` | int       | `10`                                                                                                                                                                                                                                                                       | Let X be the maximum number of websocket connections per session.This will ensure one session is not able to exhaust the connection limit of the host.                                                                                                                                                                                                                                                                                                                                                                                                                                                  |   |

### Relay

| Option                       | Type      | Value/Example                                                                                                     | Description                                                                                                                                                              |
| ---------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--service-url`              | string    | `http://localhost:4723`                                                                                           | URL for connecting to the service that supports WebDriver commands like an Appium server or a cloud service.                                                             |
| `--service-host`             | string    | `localhost`                                                                                                       | Host name where the service that supports WebDriver commands is running                                                                                                  |
| `--service-port`             | int       | `4723`                                                                                                            | Port where the service that supports WebDriver commands is running                                                                                                       |
| `--service-status-endpoint`  | string    | `/status`                                                                                                         | Optional, endpoint to query the WebDriver service status, an HTTP 200 response is expected                                                                               |
| `--service-protocol-version` | string    | `HTTP/1.1`                                                                                                        | Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status                                                          |
| `--service-configuration`    | string\[] | `max-sessions=2 stereotype='{"browserName": "safari", "platformName": "iOS", "appium:platformVersion": "14.5"}}'` | Configuration for the service where calls will be relayed to. It is recommended to provide this type of configuration through a toml config file to improve readability. |

### Router

| Option         | Type    | Value/Example              | Description                                                                                                         |
| -------------- | ------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `--password`   | string  | `myStrongPassword`         | Password clients must use to connect to the server. Both this and the username need to be set in order to be used.  |
| `--username`   | string  | `admin`                    | User name clients must use to connect to the server. Both this and the password need to be set in order to be used. |
| `--sub-path`   | string  | `my_company/selenium_grid` | A sub-path that should be considered for all user facing routes on the Hub/Router/Standalone.                       |
| `--disable-ui` | boolean | `true`                     | Disable the Grid UI.                                                                                                |

### Server

| Option                | Type    | Value/Example        | Description                                                                                                                                                                                                                                                                           |
| --------------------- | ------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--allow-cors`        | boolean | `true`               | Whether the Selenium server should allow web browser connections from any host                                                                                                                                                                                                        |
| `--host`              | string  | `localhost`          | Server IP or hostname: usually determined automatically.                                                                                                                                                                                                                              |
| `--bind-host`         | boolean | `true`               | Whether the server should bind to the host address/name, or only use it to" report its reachable url. Helpful in complex network topologies where the server cannot report itself with the current IP/hostname but rather an external IP or hostname (e.g. inside a Docker container) |
| `--https-certificate` | path    | `/path/to/cert.pem`  | Server certificate for https. Get more detailed information by running “java -jar selenium-server.jar info security”                                                                                                                                                                  |
| `--https-private-key` | path    | `/path/to/key.pkcs8` | Private key for https. Get more detailed information by running “java -jar selenium-server.jar info security”                                                                                                                                                                         |
| `--max-threads`       | int     | `24`                 | Maximum number of listener threads. Default value is: (available processors) \* 3.                                                                                                                                                                                                    |
| `--port`              | int     | `4444`               | Port to listen on. There is no default as this parameter is used by different components, for example, Router/Hub/Standalone will use 4444 and Node will use 5555.                                                                                                                    |

### SessionQueue

| Option                      | Type   | Value/Example           | Description                                                                                                                                               |
| --------------------------- | ------ | ----------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--sessionqueue`            | uri    | `http://localhost:1237` | Address of the session queue server.                                                                                                                      |
| `-sessionqueue-host`        | string | `localhost`             | Host on which the session queue server is listening.                                                                                                      |
| `--sessionqueue-port`       | int    | `1234`                  | Port on which the session queue server is listening.                                                                                                      |
| `--session-request-timeout` | int    | `300`                   | Timeout in seconds. A new incoming session request is added to the queue. Requests sitting in the queue for longer than the configured time will timeout. |
| `--session-retry-interval`  | int    | `5`                     | Retry interval in seconds. If all slots are busy, new session request will be retried after the given interval.                                           |
| `--maximum-response-delay`  | int    | `8`                     | How often, in seconds, will the the SessionQueue response in case there is no data, to reduce the http requests while polling for new session requests.   |

### Sessions

| Option            | Type   | Value/Example           | Description                                        |
| ----------------- | ------ | ----------------------- | -------------------------------------------------- |
| `--sessions`      | uri    | `http://localhost:1234` | Address of the session map server.                 |
| `--sessions-host` | string | `localhost`             | Host on which the session map server is listening. |
| `--sessions-port` | int    | `1234`                  | Port on which the session map server is listening. |

## Configuration examples

All the options mentioned above can be used when starting the Grid components. They are a good way of exploring the Grid options, and trying out values to find a suitable configuration.

We recommend the use of [Toml files](https://www.selenium.dev/zh-cn/documentation/grid/configuration/toml_options/) to configure a Grid. Configuration files improve readability, and you can also check them in source control.

When needed, you can combine a Toml file configuration with CLI arguments.

### Command-line flags

To pass config options as command-line flags, identify the valid options for the component and follow the template below.

```
java -jar selenium-server-<version>.jar <component> --<option> value
```

#### Standalone, setting max sessions and main port

```
java -jar selenium-server-<version>.jar standalone --max-sessions 4 --port 4444
```

#### Hub, setting a new session request timeout, a main port, and disabling tracing

```
java -jar selenium-server-<version>.jar hub --session-request-timeout 500 --port 3333 --tracing false
```

#### Node, with 4 max sessions, with debug(fine) log, 7777 as port, and only with Firefox and Edge

```
java -jar selenium-server-<version>.jar node --max-sessions 4 --log-level "fine" --port 7777 --driver-implementation "firefox" --driver-implementation "edge"
```

#### Distributor, setting Session Map server url, Session Queue server url, and disabling bus

```
java -jar selenium-server-<version>.jar distributor --sessions http://localhost:5556 --sessionqueue http://localhost:5559 --bind-bus false
```

#### Setting custom capabilities for matching specific Nodes

**Important:** Custom capabilities need to be set in the configuration in all Nodes. They also need to be included always in every session request.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node A with custom cap set to `true`

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":true}' --port 6161
```

##### Start the Node B with custom cap set to `false`

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":false}' --port 6262
```

##### Matching Node A

```java
ChromeOptions options = new ChromeOptions();
options.setCapability("gsg:customcap", true);
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

Set the custom capability to `false` in order to match the Node B.

#### Enabling Managed downloads by the Node

At times a test may need to access files that were downloaded by it on the Node. To retrieve such files, following can be done.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node with manage downloads enabled

```
java -jar selenium-server-<version>.jar node --enable-managed-downloads true
```

##### Set the capability at the test level

Tests that want to use this feature should set the capability `"se:downloadsEnabled"`to `true`

```java
options.setCapability("se:downloadsEnabled", true);
```

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

In the response the list of file names appear under the key `names`.

##### Dowloading a file:

* The endpoint to `POST` from is `/session/<sessionId>/se/files` with a payload of the form `{"name": "fileNameGoesHere}`
* The session needs to be active in order for the command to work.
* The raw response looks like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "Base64EncodedStringContentsOfDownloadedFileAsZipGoesHere"
  }
}
```

* The response blob contains two keys,

  * `filename` - The file name that was downloaded.
  * `contents` - Base64 encoded zipped contents of the file.

* The file contents are Base64 encoded and they need to be unzipped.

##### List files that can be downloaded

The below mentioned `curl` example can be used to list all the files that were downloaded by the current session in the Node, and which can be retrieved locally.

```bash
curl -X GET "http://localhost:4444/session/90c0149a-2e75-424d-857a-e78734943d4c/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

##### Retrieve a downloaded file

Assuming the downloaded file is named `Red-blue-green-channel.jpg`, and using `curl`, the file could be downloaded with the following command:

```bash
curl -H "Accept: application/json" \
-H "Content-Type: application/json; charset=utf-8" \
-X POST -d '{"name":"Red-blue-green-channel.jpg"}' \
"http://localhost:4444/session/18033434-fa4f-4d11-a7df-9e6d75920e19/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "UEsDBBQACAgIAJpagVYAAAAAAAAAAAAAAAAaAAAAUmVkLWJsAAAAAAAAAAAAUmVkLWJsdWUtZ3JlZW4tY2hhbm5lbC5qcGdQSwUGAAAAAAEAAQBIAAAAcNkAAAAA"
  }
}
```

##### Complete sample code in Java

Below is an example in Java that does the following:

* Sets the capability to indicate that the test requires automatic managing of downloaded files.
* Triggers a file download via a browser.
* Lists the files that are available for retrieval from the remote node (These are essentially files that were downloaded in the current session)
* Picks one file and downloads the file from the remote node to the local machine.

```java
import com.google.common.collect.ImmutableMap;

import org.openqa.selenium.By;
import org.openqa.selenium.io.Zip;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.io.File;
import java.net.URL;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import static org.openqa.selenium.remote.http.Contents.asJson;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.HttpMethod.GET;
import static org.openqa.selenium.remote.http.HttpMethod.POST;

public class DownloadsSample {

  public static void main(String[] args) throws Exception {
    // Assuming the Grid is running locally.
    URL gridUrl = new URL("http://localhost:4444");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("se:downloadsEnabled", true);
    RemoteWebDriver driver = new RemoteWebDriver(gridUrl, options);
    try {
      demoFileDownloads(driver, gridUrl);
    } finally {
      driver.quit();
    }
  }

	private static void demoFileDownloads(RemoteWebDriver driver, URL gridUrl) throws Exception {
		driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
		// Download the two available files on the page
		driver.findElement(By.id("file-1")).click();
		driver.findElement(By.id("file-2")).click();

		// The download happens in a remote Node, which makes it difficult to know when the file
		// has been completely downloaded. For demonstration purposes, this example uses a
		// 10-second sleep which should be enough time for a file to be downloaded.
		// We strongly recommend to avoid hardcoded sleeps, and ideally, to modify your
		// application under test, so it offers a way to know when the file has been completely
		// downloaded.
		TimeUnit.SECONDS.sleep(10);

		//This is the endpoint which will provide us with list of files to download and also to
		//let us download a specific file.
		String downloadsEndpoint = String.format("/session/%s/se/files", driver.getSessionId());

		String fileToDownload;

		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To list all files that are were downloaded on the remote node for the current session
			// we trigger GET request.
			HttpRequest request = new HttpRequest(GET, downloadsEndpoint);
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			@SuppressWarnings("unchecked")
			List<String> names = (List<String>) value.get("names");
			// Let's say there were "n" files downloaded for the current session, we would like
			// to retrieve ONLY the first file.
			fileToDownload = names.get(0);
		}

		// Now, let's download the file
		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To retrieve a specific file from one or more files that were downloaded by the current session
			// on a remote node, we use a POST request.
			HttpRequest request = new HttpRequest(POST, downloadsEndpoint);
			request.setContent(asJson(ImmutableMap.of("name", fileToDownload)));
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			// The returned map would contain 2 keys,
			// filename - This represents the name of the file (same as what was provided by the test)
			// contents - Base64 encoded String which contains the zipped file.
			String zippedContents = value.get("contents").toString();
			// The file contents would always be a zip file and has to be unzipped.
			File downloadDir = Zip.unzipToTempDir(zippedContents, "download", "");
			// Read the file contents
			File downloadedFile = Optional.ofNullable(downloadDir.listFiles()).orElse(new File[]{})[0];
			String fileContent = String.join("", Files.readAllLines(downloadedFile.toPath()));
			System.out.println("The file which was "
					+ "downloaded in the node is now available in the directory: "
					+ downloadDir.getAbsolutePath() + " and has the contents: " + fileContent);
		}
	}


}
```

# 3 - Toml配置选项

```toml
[section1]
option1="value"

[section2]
option2=["value1","value2"]
option3=true
```

下面是一些使用Toml文件配置的 Grid组件示例, 该组件可以 从下面的方式开始:

```
java -jar selenium-server-<version>.jar <component> --config /path/to/file/<file-name>.toml
```

### 单机模式

单机服务器, 在端口4449上运行, 新会话请求超时500秒.

```toml
[server]
port = 4449

[sessionqueue]
session-request-timeout = 500
```

### 特定浏览器和最大会话数限制

默认情况下仅启用Firefox 和Chrome的单机服务器或节点.

```toml
[node]
drivers = ["chrome", "firefox"]
max-sessions = 3
```

### 配置和定制驱动程序

具有定制驱动程序的单机或节点服务器, 允许使用Firefox试用或者每日构建的功能, 并且有不同的浏览器版本.

```toml
[node]
detect-drivers = false
[[node.driver-configuration]]
max-sessions = 100
display-name = "Firefox Nightly"
stereotype = "{\"browserName\": \"firefox\", \"browserVersion\": \"93\", \"platformName\": \"MAC\", \"moz:firefoxOptions\": {\"binary\": \"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"
[[node.driver-configuration]]
display-name = "Chrome Beta"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"94\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta\"}}"
[[node.driver-configuration]]
display-name = "Chrome Dev"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"95\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev\"}}"
webdriver-executable = '/path/to/chromedriver/95/chromedriver'
```

### 带Docker的单机或节点

单机或节点服务器能够在Docker容器中运行每个新会话. 禁用驱动程序检测, 则最多有2个并发会话. 原型配置需要映射一个Docker映像, Docker的守护进程需要通过http/tcp公开. 此外, 可以通过 `devices` 属性定义在主机上可访问的哪些设备文件将在容器中可用. 有关 docker 设备映射如何工作的更多信息, 请参阅 [docker](https://docs.docker.com/engine/reference/commandline/run/#add-host-device-to-container---device) 文档.

```toml
[node]
detect-drivers = false
max-sessions = 2

[docker]
configs = [
    "selenium/standalone-chrome:93.0", "{\"browserName\": \"chrome\", \"browserVersion\": \"91\"}", 
    "selenium/standalone-firefox:92.0", "{\"browserName\": \"firefox\", \"browserVersion\": \"92\"}"
]
#Optionally define all device files that should be mapped to docker containers
#devices = [
#    "/dev/kvm:/dev/kvm"
#]
url = "http://localhost:2375"
video-image = "selenium/video:latest"
```

### 将命令中继到支持WebDriver的服务端点

连接到支持WebDriver外部服务 的Selenium Grid非常有用. 这种服务的一个例子可以是 云提供商或Appium服务器. 这样, Grid可以实现对本地不存在的平台和版本的更多覆盖.

下面是一个将Appium服务器连接到Grid的示例.

```toml
[node]
detect-drivers = false

[relay]
# Default Appium/Cloud server endpoint
url = "http://localhost:4723/wd/hub"
status-endpoint = "/status"
# Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status (e.g. HTTP/1.1, HTTP/2)
protocol-version = "HTTP/1.1"
# Stereotypes supported by the service. The initial number is "max-sessions", and will allocate 
# that many test slots to that particular configuration
configs = [
  "5", "{\"browserName\": \"chrome\", \"platformName\": \"android\", \"appium:platformVersion\": \"11\"}"
]
```

### 启用基本身份验证

通过配置包含用户名和密码的 路由器/集线器/单机的方式, 可以使用这样的基本身份验证保护Grid. 加载Grid UI或者开始一个新的会话时 需要此用户/密码组合.

```toml
[router]
username = "admin"
password = "myStrongPassword"
```

下面是一个Java示例, 演示如何使用配置的用户和密码启动会话.

```java
ClientConfig clientConfig = ClientConfig.defaultConfig()
  .baseUrl(new URL("http://localhost:4444"))
  .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"));
HttpCommandExecutor executor = new HttpCommandExecutor(clientConfig);
RemoteWebDriver driver = new RemoteWebDriver(executor, new ChromeOptions());
```

在其他语言中, 您可以使用 URL http\://admin:myStrongPassword\@localhost:4444

### 为匹配特定节点设置自定义功能

**重要提示:** 自定义功能需要在所有节点的配置中进行设置. 并且在每次会话请求中都必须包含这些功能.

```toml
[node]
detect-drivers = false

[[node.driver-configuration]]
display-name = "firefox"
stereotype = '{"browserName": "firefox", "platformName": "macOS", "browserVersion":"96", "networkname:applicationName":"node_1", "nodename:applicationName":"app_1" }'
max-sessions = 5
```

这里有一个 Java 示例, 展示了如何匹配那个节点

```java
FirefoxOptions options = new FirefoxOptions();
options.setCapability("networkname:applicationName", "node_1");
options.setCapability("nodename:applicationName", "app_1");
options.setBrowserVersion("96");
options.setPlatformName("macOS");
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

### 启用节点的托管下载功能.

节点可以被设置为自动管理下载. 这将导致节点会把特定会话中下载的所有文件保存到一个临时目录中, 之后可以从节点中获取这些文件.\
要启用此功能, 请使用以下配置:

```toml
[node]
enable-managed-downloads = true
```

有关完整示例, 请参阅[CLI章节](https://www.selenium.dev/zh-cn/documentation/grid/configuration/cli_options/#enabling-managed-downloads-by-the-node) .

----
url: https://www.selenium.dev/ja/documentation/test_practices/discouraged/
----

# 推奨されない行動

Seleniumでブラウザを自動化するときに避けるべきこと。

***

##### [CAPTCHA（キャプチャ）](/ja/documentation/test_practices/discouraged/captchas/)

##### [ファイルダウンロード](/ja/documentation/test_practices/discouraged/file_downloads/)

##### [HTTPレスポンスコード](/ja/documentation/test_practices/discouraged/http_response_codes/)

##### [Gmail、Eメール、Facebookログイン](/ja/documentation/test_practices/discouraged/gmail_email_and_facebook_logins/)

##### [テストの依存関係](/ja/documentation/test_practices/discouraged/test_dependency/)

##### [パフォーマンステスト](/ja/documentation/test_practices/discouraged/performance_testing/)

##### [リンクスパイダー](/ja/documentation/test_practices/discouraged/link_spidering/)

##### [二要素認証](/ja/documentation/test_practices/discouraged/two_factor_authentication/)

----
url: https://www.selenium.dev/pt-br/_print/documentation/test_practices/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/test_practices/).

# Diretrizes e recomendações

Guias e recomendações ao preparar soluções de testes com o projecto Selenium.

* 1: [Design patterns and development strategies](#pg-41b48c998b0eb67a902ff9ed4be1e4f2)
* 2: [Sobre automação de testes](#pg-dd8e59352a81d0dd14725ea5ac1acf6b)
* 3: [Tipos de teste](#pg-66992012687d920f99acd526b6c65d88)
* 4: [Diretrizes e recomendações](#pg-2ca3e3d8ec6126dd6459ffc3adfde4b5)
* * 4.1: [Modelos de objetos de página](#pg-fa4eae362230005dc133eaccc8f3c3e8)
  * 4.2: [Linguagem específica de domínio (DSL)](#pg-4343e59eb52d202f26ceb385a8b56fa6)
  * 4.3: [Gerando estado da aplicação](#pg-edd30564b73abba307b40f4351d2b249)
  * 4.4: [Simulação de serviços externos](#pg-58945a8c3e84861fda4825f09e9cd2e0)
  * 4.5: [Relatórios melhorados](#pg-c6cc073467223ae721b34c947936cbf9)
  * 4.6: [Evite compartilhamento de estado](#pg-f155e13b0c999e5f3c5f56fef53fc47b)
  * 4.7: [Tips on working with locators](#pg-51a63c6ce7dd64b1ecddf236663ecb74)
  * 4.8: [Independência de Testes](#pg-a43c32fda8a8fa76d1487e152b4c1998)
  * 4.9: [Considere usar uma API fluente](#pg-1ae8894e692552d092b8b8a00eee7702)
  * 4.10: [Navegador novo por teste](#pg-eae471af628f9dd496b080eac9d94ac8)
  5: [Piores práticas](#pg-00c756826866d1deecc6dac2d5739aee)
  * 5.1: [Captchas](#pg-b9472460f277ae413b03898b8ebef6b7)
  * 5.2: [Downloads de arquivo](#pg-c79dca2107c3188889176374ce3f58ff)
  * 5.3: [Códigos de respostas HTTP](#pg-2d5ad114868779f863121d44ce8df24f)
  * 5.4: [Login via Gmail, email e Facebook](#pg-3a9d097074ef98e8fa2e2aacf6e14dc2)
  * 5.5: [Dependência entre testes](#pg-69552aacfd36f7ebd616975dfd16cc9c)
  * 5.6: [Teste de performance/desempenho](#pg-c613ed467d082d32cb7c5294b94a1280)
  * 5.7: [Navegação por links](#pg-559e8e8a1ac67ab5eeb8d552a7c78c22)
  * 5.8: [Autenticação de Dois Fatores (2FA)](#pg-434101f95bfac0d5faefe0b450574456)

Uma nota sobre “Melhores práticas”: evitamos intencionalmente a frase “Melhores Práticas” nesta documentação. Nenhuma abordagem funciona para todas as situações. Preferimos a ideia de “Diretrizes e Recomendações”. Nós encorajamos que você leia e decida cuidadosamente quais abordagens funcionarão para você em seu ambiente específico.

O teste funcional é difícil de acertar por muitos motivos. Como se o estado, a complexidade e as dependências do aplicativo não tornassem o teste suficientemente difícil, lidar com navegadores (especialmente com incompatibilidades entre navegadores) torna a escrita de bons testes um desafio.

Selenium fornece ferramentas para facilitar a interação funcional do usuário, mas não o ajuda a escrever suítes de teste bem arquitetadas. Neste capítulo, oferecemos conselhos, diretrizes e recomendações sobre como abordar a automação funcional de páginas da web.

Este capítulo registra os padrões de design de software populares entre muitos dos usuários do Selenium que tiveram sucesso ao longo dos anos.

# 1 - Design patterns and development strategies

```java
package com.example.webdriver;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

public class EditIssue {

  private final WebDriver driver;

  public EditIssue(WebDriver driver) {
    this.driver = driver;
  }

  public void setTitle(String title) {
    WebElement field = driver.findElement(By.id("issue_title")));
    clearAndType(field, title);
  }

  public void setBody(String body) {
    WebElement field = driver.findElement(By.id("issue_body"));
    clearAndType(field, body);
  }

  public void setHowToReproduce(String howToReproduce) {
    WebElement field = driver.findElement(By.id("issue_form_repro-command"));
    clearAndType(field, howToReproduce);
  }

  public void setLogOutput(String logOutput) {
    WebElement field = driver.findElement(By.id("issue_form_logs"));
    clearAndType(field, logOutput);
  }

  public void setOperatingSystem(String operatingSystem) {
    WebElement field = driver.findElement(By.id("issue_form_operating-system"));
    clearAndType(field, operatingSystem);
  }

  public void setSeleniumVersion(String seleniumVersion) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-version"));
    clearAndType(field, logOutput);
  }

  public void setBrowserVersion(String browserVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-versions"));
    clearAndType(field, browserVersion);
  }

  public void setDriverVersion(String driverVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-driver-versions"));
    clearAndType(field, driverVersion);
  }

  public void setUsingGrid(String usingGrid) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-grid-version"));
    clearAndType(field, usingGrid);
  }

  public IssueList submit() {
    driver.findElement(By.cssSelector("button[type='submit']")).click();
    return new IssueList(driver);
  }

  private void clearAndType(WebElement field, String text) {
    field.clear();
    field.sendKeys(text);
  }
}
```

In order to turn this into a LoadableComponent, all we need to do is to set that as the base type:

```java
public class EditIssue extends LoadableComponent<EditIssue> {
  // rest of class ignored for now
}
```

This signature looks a little unusual, but it all means is that this class represents a LoadableComponent that loads the EditIssue page.

By extending this base class, we need to implement two new methods:

```java
  @Override
  protected void load() {
    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();
    assertTrue("Not on the issue entry page: " + url, url.endsWith("/new"));
  }
```

The `load` method is used to navigate to the page, whilst the `isLoaded` method is used to determine whether we are on the right page. Although the method looks like it should return a boolean, instead it performs a series of assertions using JUnit’s Assert class. There can be as few or as many assertions as you like. By using these assertions it’s possible to give users of the class clear information that can be used to debug tests.

With a little rework, our PageObject looks like:

```java
package com.example.webdriver;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.FindBy;
import org.openqa.selenium.support.PageFactory;

import static junit.framework.Assert.assertTrue;

public class EditIssue extends LoadableComponent<EditIssue> {

  private final WebDriver driver;
  
  // By default the PageFactory will locate elements with the same name or id
  // as the field. Since the issue_title element has an id attribute of "issue_title"
  // we don't need any additional annotations.
  private WebElement issue_title;
  
  // But we'd prefer a different name in our code than "issue_body", so we use the
  // FindBy annotation to tell the PageFactory how to locate the element.
  @FindBy(id = "issue_body") private WebElement body;
  
  public EditIssue(WebDriver driver) {
    this.driver = driver;
    
    // This call sets the WebElement fields.
    PageFactory.initElements(driver, this);
  }

  @Override
  protected void load() {
    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();
    assertTrue("Not on the issue entry page: " + url, url.endsWith("/new"));
  }

  public void setHowToReproduce(String howToReproduce) {
    WebElement field = driver.findElement(By.id("issue_form_repro-command"));
    clearAndType(field, howToReproduce);
  }

  public void setLogOutput(String logOutput) {
    WebElement field = driver.findElement(By.id("issue_form_logs"));
    clearAndType(field, logOutput);
  }

  public void setOperatingSystem(String operatingSystem) {
    WebElement field = driver.findElement(By.id("issue_form_operating-system"));
    clearAndType(field, operatingSystem);
  }

  public void setSeleniumVersion(String seleniumVersion) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-version"));
    clearAndType(field, logOutput);
  }

  public void setBrowserVersion(String browserVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-versions"));
    clearAndType(field, browserVersion);
  }

  public void setDriverVersion(String driverVersion) {
    WebElement field = driver.findElement(By.id("issue_form_browser-driver-versions"));
    clearAndType(field, driverVersion);
  }

  public void setUsingGrid(String usingGrid) {
    WebElement field = driver.findElement(By.id("issue_form_selenium-grid-version"));
    clearAndType(field, usingGrid);
  }

  public IssueList submit() {
    driver.findElement(By.cssSelector("button[type='submit']")).click();
    return new IssueList(driver);
  }

  private void clearAndType(WebElement field, String text) {
    field.clear();
    field.sendKeys(text);
  }
}
```

That doesn’t seem to have bought us much, right? One thing it has done is encapsulate the information about how to navigate to the page into the page itself, meaning that this information’s not scattered through the code base. It also means that we can do this in our tests:

```java
EditIssue page = new EditIssue(driver).get();
```

This call will cause the driver to navigate to the page if that’s necessary.

### Nested Components

LoadableComponents start to become more useful when they are used in conjunction with other LoadableComponents. Using our example, we could view the “edit issue” page as a component within a project’s website (after all, we access it via a tab on that site). You also need to be logged in to file an issue. We could model this as a tree of nested components:

```
 + ProjectPage
 +---+ SecuredPage
     +---+ EditIssue
```

What would this look like in code? For a start, each logical component would have its own class. The “load” method in each of them would “get” the parent. The end result, in addition to the EditIssue class above is:

ProjectPage.java:

```java
package com.example.webdriver;

import org.openqa.selenium.WebDriver;

import static org.junit.Assert.assertTrue;

public class ProjectPage extends LoadableComponent<ProjectPage> {

  private final WebDriver driver;
  private final String projectName;

  public ProjectPage(WebDriver driver, String projectName) {
    this.driver = driver;
    this.projectName = projectName;
  }

  @Override
  protected void load() {
    driver.get("http://" + projectName + ".googlecode.com/");
  }

  @Override
  protected void isLoaded() throws Error {
    String url = driver.getCurrentUrl();

    assertTrue(url.contains(projectName));
  }
}
```

and SecuredPage.java:

```java
package com.example.webdriver;

import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import static org.junit.Assert.fail;

public class SecuredPage extends LoadableComponent<SecuredPage> {

  private final WebDriver driver;
  private final LoadableComponent<?> parent;
  private final String username;
  private final String password;

  public SecuredPage(WebDriver driver, LoadableComponent<?> parent, String username, String password) {
    this.driver = driver;
    this.parent = parent;
    this.username = username;
    this.password = password;
  }

  @Override
  protected void load() {
    parent.get();

    String originalUrl = driver.getCurrentUrl();

    // Sign in
    driver.get("https://www.google.com/accounts/ServiceLogin?service=code");
    driver.findElement(By.name("Email")).sendKeys(username);
    WebElement passwordField = driver.findElement(By.name("Passwd"));
    passwordField.sendKeys(password);
    passwordField.submit();

    // Now return to the original URL
    driver.get(originalUrl);
  }

  @Override
  protected void isLoaded() throws Error {
    // If you're signed in, you have the option of picking a different login.
    // Let's check for the presence of that.

    try {
      WebElement div = driver.findElement(By.id("multilogin-dropdown"));
    } catch (NoSuchElementException e) {
      fail("Cannot locate user name link");
    }
  }
}
```

The “load” method in EditIssue now looks like:

```java
  @Override
  protected void load() {
    securedPage.get();

    driver.get("https://github.com/SeleniumHQ/selenium/issues/new?assignees=&labels=I-defect%2Cneeds-triaging&projects=&template=bug-report.yml&title=%5B%F0%9F%90%9B+Bug%5D%3A+");
  }
```

This shows that the components are all “nested” within each other. A call to `get()` in EditIssue will cause all its dependencies to load too. The example usage:

```java
public class FooTest {
  private EditIssue editIssue;

  @Before
  public void prepareComponents() {
    WebDriver driver = new FirefoxDriver();

    ProjectPage project = new ProjectPage(driver, "selenium");
    SecuredPage securedPage = new SecuredPage(driver, project, "example", "top secret");
    editIssue = new EditIssue(driver, securedPage);
  }

  @Test
  public void demonstrateNestedLoadableComponents() {
    editIssue.get();

    editIssue.title.sendKeys('Title');
    editIssue.body.sendKeys('What Happened');
    editIssue.setHowToReproduce('How to Reproduce');
    editIssue.setLogOutput('Log Output');
    editIssue.setOperatingSystem('Operating System');
    editIssue.setSeleniumVersion('Selenium Version');
    editIssue.setBrowserVersion('Browser Version');
    editIssue.setDriverVersion('Driver Version');
    editIssue.setUsingGrid('I Am Using Grid');
  }
}
```

If you’re using a library such as [Guiceberry](https://github.com/zorzella/guiceberry) in your tests, the preamble of setting up the PageObjects can be omitted leading to nice, clear, readable tests.

## Bot Pattern

(previously located: <https://github.com/SeleniumHQ/selenium/wiki/Bot-Style-Tests>)

Although PageObjects are a useful way of reducing duplication in your tests, it’s not always a pattern that teams feel comfortable following. An alternative approach is to follow a more “command-like” style of testing.

A “bot” is an action-oriented abstraction over the raw Selenium APIs. This means that if you find that commands aren’t doing the Right Thing for your app, it’s easy to change them. As an example:

```java
public class ActionBot {
  private final WebDriver driver;

  public ActionBot(WebDriver driver) {
    this.driver = driver;
  }

  public void click(By locator) {
    driver.findElement(locator).click();
  }

  public void submit(By locator) {
    driver.findElement(locator).submit();
  }

  /** 
   * Type something into an input field. WebDriver doesn't normally clear these
   * before typing, so this method does that first. It also sends a return key
   * to move the focus out of the element.
   */
  public void type(By locator, String text) { 
    WebElement element = driver.findElement(locator);
    element.clear();
    element.sendKeys(text + "\n");
  }
}
```

```py
import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L6-L26)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L28-L65)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L67-L80)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L82-L172)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

```py
@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/design_strategy/using_best_practice.py#L174-L240)

##### /examples/python/tests/design\_strategy/using\_best\_practice.py

```py
"""
An example of `python + pytest + selenium` 
which implemented "**Action Bot**, **Loadable Component** and **Page Object**".
"""

import pytest
from selenium import webdriver
from selenium.common import (
    ElementNotInteractableException,
    NoSuchElementException,
    StaleElementReferenceException,
)
from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait


@pytest.fixture(scope="function")
def chrome_driver():
    with webdriver.Chrome() as driver:
        driver.set_window_size(1024, 768)
        driver.implicitly_wait(0.5)
        yield driver


class ActionBot:
    def __init__(self, driver) -> None:
        self.driver = driver
        self.wait = WebDriverWait(
            driver,
            timeout=10,
            poll_frequency=2,
            ignored_exceptions=[
                NoSuchElementException,
                StaleElementReferenceException,
                ElementNotInteractableException,
            ],
        )

    def element(self, locator: tuple) -> WebElement:
        self.wait.until(lambda driver: driver.find_element(*locator))
        return self.driver.find_element(*locator)

    def elements(self, locator: tuple) -> list[WebElement]:
        return self.driver.find_elements(*locator)

    def hover(self, locator: tuple) -> None:
        element = self.element(locator)
        ActionChains(self.driver).move_to_element(element).perform()

    def click(self, locator: tuple) -> None:
        element = self.element(locator)
        element.click()

    def type(self, locator: tuple, value: str) -> None:
        element = self.element(locator)
        element.clear()
        element.send_keys(value)

    def text(self, locator: tuple) -> str:
        element = self.element(locator)
        return element.text


class LoadableComponent:
    def load(self):
        raise NotImplementedError("Subclasses must implement this method")

    def is_loaded(self):
        raise NotImplementedError("Subclasses must implement this method")

    def get(self):
        if not self.is_loaded():
            self.load()
        if not self.is_loaded():
            raise Exception("Page not loaded properly.")
        return self


class TodoPage(LoadableComponent):
    url = "https://todomvc.com/examples/react/dist/"

    new_todo_by = (By.CSS_SELECTOR, "input.new-todo")
    count_todo_left_by = (By.CSS_SELECTOR, "span.todo-count")
    todo_items_by = (By.CSS_SELECTOR, "ul.todo-list>li")

    view_all_by = (By.LINK_TEXT, "All")
    view_active_by = (By.LINK_TEXT, "Active")
    view_completed_by = (By.LINK_TEXT, "Completed")

    toggle_all_by = (By.CSS_SELECTOR, "input.toggle-all")
    clear_completed_by = (By.CSS_SELECTOR, "button.clear-completed")

    @staticmethod
    def build_todo_by(s: str) -> tuple:
        p = f"//li[.//label[contains(text(), '{s}')]]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_label_by(s: str) -> tuple:
        p = f"//label[contains(text(), '{s}')]"
        return By.XPATH, p

    @staticmethod
    def build_todo_item_toggle_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../input[@class='toggle']"
        return by, p

    @staticmethod
    def build_todo_item_delete_by(s: str) -> tuple:
        by, using = TodoPage.build_todo_item_label_by(s)
        p = f"{using}/../button[@class='destroy']"
        return by, p

    def build_count_todo_left(self, count: int) -> str:
        if count == 1:
            return "1 item left!"
        else:
            return f"{count} items left!"

    def __init__(self, driver):
        self.driver = driver
        self.bot = ActionBot(driver)

    def load(self):
        self.driver.get(self.url)

    def is_loaded(self):
        try:
            WebDriverWait(self.driver, 10).until(EC.visibility_of_element_located(self.new_todo_by))
            return True
        except:
            return False

    # business domain below
    def count_todo_items_left(self) -> str:
        return self.bot.text(self.count_todo_left_by)

    def todo_count(self) -> int:
        return len(self.bot.elements(self.todo_items_by))

    def new_todo(self, s: str):
        self.bot.type(self.new_todo_by, s + "\n")

    def toggle_todo(self, s: str):
        self.bot.click(self.build_todo_item_toggle_by(s))

    def hover_todo(self, s: str) -> None:
        self.bot.hover(self.build_todo_by(s))

    def delete_todo(self, s: str):
        self.hover_todo(s)
        self.bot.click(self.build_todo_item_delete_by(s))

    def clear_completed_todo(self):
        self.bot.click(self.clear_completed_by)

    def toggle_all_todo(self):
        self.bot.click(self.toggle_all_by)

    def view_all_todo(self):
        self.bot.click(self.view_all_by)

    def view_active_todo(self):
        self.bot.click(self.view_active_by)

    def view_completed_todo(self):
        self.bot.click(self.view_completed_by)


@pytest.fixture
def page(chrome_driver) -> TodoPage:
    driver = chrome_driver
    return TodoPage(driver).get()


class TestTodoPage:
    def test_new_todo(self, page: TodoPage):
        assert page.todo_count() == 0
        page.new_todo("aaa")
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_toggle(self, page: TodoPage):
        s = "aaa"
        page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(0)

        page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

    def test_todo_delete(self, page: TodoPage):
        s1 = "aaa"
        s2 = "bbb"
        page.new_todo(s1)
        page.new_todo(s2)
        assert page.count_todo_items_left() == page.build_count_todo_left(2)

        page.delete_todo(s1)
        assert page.count_todo_items_left() == page.build_count_todo_left(1)

        page.delete_todo(s2)
        assert page.todo_count() == 0

    def test_new_100_todo(self, page: TodoPage):
        for i in range(100):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(100)

    def test_toggle_all_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(0)
        assert page.todo_count() == 10

        page.toggle_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

    def test_clear_completed_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(10)
        assert page.todo_count() == 10

        for i in range(5):
            s = f"ToDo{i}"
            page.toggle_todo(s)
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 10

        page.clear_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(5)
        assert page.todo_count() == 5

    def test_view_todo(self, page: TodoPage):
        for i in range(10):
            s = f"ToDo{i}"
            page.new_todo(s)
        for i in range(4):
            s = f"ToDo{i}"
            page.toggle_todo(s)

        page.view_all_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 10

        page.view_active_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 6

        page.view_completed_todo()
        assert page.count_todo_items_left() == page.build_count_todo_left(6)
        assert page.todo_count() == 4
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

# 2 - Sobre automação de testes

```java
// Crie um usuário que tenha permissões somente leitura - eles podem configurar um unicórnio,
// mas eles não têm informações de pagamento configuradas, nem têm
// privilégios administrativos. No momento em que o usuário é criado, seu endereço
// de e-mail e senha são gerados aleatoriamente - você nem precisa
// conhecê-los.
User user = UserFactory.createCommonUser(); //Este método está definido em algum outro lugar.

// Faça login como este usuário.
// O login neste site leva você à sua página pessoal "Minha conta", e então
// o objeto AccountPage é retornado pelo método loginAs, permitindo que você
// execute ações da AccountPage.
AccountPage accountPage = loginAs(user.getEmail(), user.getPassword());
  
```

```python
# Crie um usuário que tenha permissões somente leitura - eles podem configurar um unicórnio,
# mas eles não têm informações de pagamento configuradas, nem têm
# privilégios administrativos. No momento em que o usuário é criado, seu endereço
# de e-mail e senha são gerados aleatoriamente - você nem precisa
# conhecê-los.
user = user_factory.create_common_user() #This method is defined elsewhere.

# Faça login como este usuário.
# O login neste site leva você à sua página pessoal "Minha conta", e então
# o objeto AccountPage é retornado pelo método loginAs, permitindo que você
# execute ações da AccountPage.
account_page = login_as(user.get_email(), user.get_password())
  
```

```csharp
// Crie um usuário que tenha permissões somente leitura - eles podem configurar um unicórnio,
// mas eles não têm informações de pagamento configuradas, nem têm
// privilégios administrativos. No momento em que o usuário é criado, seu endereço
// de e-mail e senha são gerados aleatoriamente - você nem precisa
// conhecê-los.
User user = UserFactory.CreateCommonUser(); //This method is defined elsewhere.

// Faça login como este usuário.
// O login neste site leva você à sua página pessoal "Minha conta", e então
// o objeto AccountPage é retornado pelo método loginAs, permitindo que você
// execute ações da AccountPage.
AccountPage accountPage = LoginAs(user.Email, user.Password);
  
```

```ruby
# Crie um usuário que tenha permissões somente leitura - eles podem configurar um unicórnio,
# mas eles não têm informações de pagamento configuradas, nem têm
# privilégios administrativos. No momento em que o usuário é criado, seu endereço
# de e-mail e senha são gerados aleatoriamente - você nem precisa
# conhecê-los.
user = UserFactory.create_common_user #This method is defined elsewhere.

# Faça login como este usuário.
# O login neste site leva você à sua página pessoal "Minha conta", e então
# o objeto AccountPage é retornado pelo método loginAs, permitindo que você
# execute ações da AccountPage.
account_page = login_as(user.email, user.password)
  
```

```javascript
// Crie um usuário que tenha permissões somente leitura - eles podem configurar um unicórnio,
// mas eles não têm informações de pagamento configuradas, nem têm
// privilégios administrativos. No momento em que o usuário é criado, seu endereço
// de e-mail e senha são gerados aleatoriamente - você nem precisa
// conhecê-los.
var user = userFactory.createCommonUser(); //This method is defined elsewhere.

// Faça login como este usuário.
// O login neste site leva você à sua página pessoal "Minha conta", e então
// o objeto AccountPage é retornado pelo método loginAs, permitindo que você
// execute ações da AccountPage.
var accountPage = loginAs(user.email, user.password);
  
```

```kotlin
// Crie um usuário que tenha permissões somente leitura - eles podem configurar um unicórnio,
// mas eles não têm informações de pagamento configuradas, nem têm
// privilégios administrativos. No momento em que o usuário é criado, seu endereço
// de e-mail e senha são gerados aleatoriamente - você nem precisa
// conhecê-los.
val user = UserFactory.createCommonUser() //This method is defined elsewhere.

// Faça login como este usuário.
// O login neste site leva você à sua página pessoal "Minha conta", e então
// o objeto AccountPage é retornado pelo método loginAs, permitindo que você
// execute ações da AccountPage.
val accountPage = loginAs(user.getEmail(), user.getPassword())
  
```

```java
// O Unicórnio é um objeto de nível superior - ele possui atributos, que são definidos aqui.
// Isso armazena apenas os valores; não preenche formulários da web nem interage
// com o navegador de qualquer forma.
Unicorn sparkles = new Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS);

// Uma vez que já estamos "na" página da conta, temos que usá-la para chegar ao
// lugar real onde você configura os unicórnios. Chamar o método "Add Unicorn"
// nos leva lá.
AddUnicornPage addUnicornPage = accountPage.addUnicorn();

// Agora que estamos na AddUnicornPage, passaremos o objeto "sparkles" para
// o método createUnicorn(). Este método pegará os atributos do Sparkles,
// preencher o formulário e clicar em enviar.
UnicornConfirmationPage unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles);
  
```

```python
# O Unicórnio é um objeto de nível superior - ele possui atributos, que são definidos aqui.
# Isso armazena apenas os valores; não preenche formulários da web nem interage
# com o navegador de qualquer forma.
sparkles = Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

# Uma vez que já estamos "na" página da conta, temos que usá-la para chegar ao
# lugar real onde você configura os unicórnios. Chamar o método "Add Unicorn"
# nos leva lá.
add_unicorn_page = account_page.add_unicorn()

# Agora que estamos na AddUnicornPage, passaremos o objeto "sparkles" para
# o método createUnicorn(). Este método pegará os atributos do Sparkles,
# preencher o formulário e clicar em enviar.
unicorn_confirmation_page = add_unicorn_page.create_unicorn(sparkles)
  
```

```csharp
// O Unicórnio é um objeto de nível superior - ele possui atributos, que são definidos aqui.
// Isso armazena apenas os valores; não preenche formulários da web nem interage
// com o navegador de qualquer forma.
Unicorn sparkles = new Unicorn("Sparkles", UnicornColors.Purple, UnicornAccessories.Sunglasses, UnicornAdornments.StarTattoos);

// Uma vez que já estamos "na" página da conta, temos que usá-la para chegar ao
// lugar real onde você configura os unicórnios. Chamar o método "Add Unicorn"
// nos leva lá.
AddUnicornPage addUnicornPage = accountPage.AddUnicorn();

// Agora que estamos na AddUnicornPage, passaremos o objeto "sparkles" para
// o método createUnicorn(). Este método pegará os atributos do Sparkles,
// preencher o formulário e clicar em enviar.
UnicornConfirmationPage unicornConfirmationPage = addUnicornPage.CreateUnicorn(sparkles);
  
```

```ruby
# O Unicórnio é um objeto de nível superior - ele possui atributos, que são definidos aqui.
# Isso armazena apenas os valores; não preenche formulários da web nem interage
# com o navegador de qualquer forma.
sparkles = Unicorn.new('Sparkles', UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

# Uma vez que já estamos "na" página da conta, temos que usá-la para chegar ao
# lugar real onde você configura os unicórnios. Chamar o método "Add Unicorn"
# nos leva lá.
add_unicorn_page = account_page.add_unicorn

# Agora que estamos na AddUnicornPage, passaremos o objeto "sparkles" para
# o método createUnicorn(). Este método pegará os atributos do Sparkles,
# preencher o formulário e clicar em enviar.
unicorn_confirmation_page = add_unicorn_page.create_unicorn(sparkles)
  
```

```javascript
// O Unicórnio é um objeto de nível superior - ele possui atributos, que são definidos aqui.
// Isso armazena apenas os valores; não preenche formulários da web nem interage
// com o navegador de qualquer forma.
var sparkles = new Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS);

// Uma vez que já estamos "na" página da conta, temos que usá-la para chegar ao
// lugar real onde você configura os unicórnios. Chamar o método "Add Unicorn"
// nos leva lá.
var addUnicornPage = accountPage.addUnicorn();

// Agora que estamos na AddUnicornPage, passaremos o objeto "sparkles" para
// o método createUnicorn(). Este método pegará os atributos do Sparkles,
// preencher o formulário e clicar em enviar.
var unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles);

  
```

```kotlin
// O Unicórnio é um objeto de nível superior - ele possui atributos, que são definidos aqui.
// Isso armazena apenas os valores; não preenche formulários da web nem interage
// com o navegador de qualquer forma.
val sparkles = Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

// Uma vez que já estamos "na" página da conta, temos que usá-la para chegar ao
// lugar real onde você configura os unicórnios. Chamar o método "Add Unicorn"
// nos leva lá.
val addUnicornPage = accountPage.addUnicorn()

// Agora que estamos na AddUnicornPage, passaremos o objeto "sparkles" para
// o método createUnicorn(). Este método pegará os atributos do Sparkles,
// preencher o formulário e clicar em enviar.
unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles)

  
```

```java
// O método exists() de UnicornConfirmationPage pegará o objeto
// Sparkles - uma especificação dos atributos que você deseja ver e compará-los
// com os campos na página
Assert.assertTrue("Sparkles should have been created, with all attributes intact", unicornConfirmationPage.exists(sparkles));
  
```

```python
# O método exists() de UnicornConfirmationPage pegará o objeto
# Sparkles - uma especificação dos atributos que você deseja ver e compará-los
# com os campos na página
assert unicorn_confirmation_page.exists(sparkles), "Sparkles should have been created, with all attributes intact"
  
```

```csharp
// O método exists() de UnicornConfirmationPage pegará o objeto
// Sparkles - uma especificação dos atributos que você deseja ver e compará-los
// com os campos na página
Assert.True(unicornConfirmationPage.Exists(sparkles), "Sparkles should have been created, with all attributes intact");
  
```

```ruby
# O método exists() de UnicornConfirmationPage pegará o objeto
# Sparkles - uma especificação dos atributos que você deseja ver e compará-los
# com os campos na página
expect(unicorn_confirmation_page.exists?(sparkles)).to be, 'Sparkles should have been created, with all attributes intact'
  
```

```javascript
// O método exists() de UnicornConfirmationPage pegará o objeto
// Sparkles - uma especificação dos atributos que você deseja ver e compará-los
// com os campos na página
assert(unicornConfirmationPage.exists(sparkles), "Sparkles should have been created, with all attributes intact");

  
```

```kotlin
// O método exists() de UnicornConfirmationPage pegará o objeto
// Sparkles - uma especificação dos atributos que você deseja ver e compará-los
// com os campos na página
assertTrue("Sparkles should have been created, with all attributes intact", unicornConfirmationPage.exists(sparkles))
  
```

Observe que o testador ainda não fez nada além de falar sobre unicórnios neste código– sem botões, sem localizadores, sem controles do navegador. Este método de *modelagem* do aplicativo permite que você mantenha esses comandos de nível de teste no lugar e imutáveis, mesmo se Larry decidir na próxima semana que não gosta mais de Ruby-on-Rails e decidir reimplementar todo o site em Haskell com um front-end Fortran.

Seus objetos de página exigirão alguma pequena manutenção para estar conformidade com o redesenho do site, mas esses testes permanecerão os mesmos. Pegando esse design básico, você desejará continuar seus fluxos de trabalho com o menor número possível de etapas voltadas para o navegador. Seu próximo fluxo de trabalho envolverá adicionar um unicórnio ao carrinho de compras. Provavelmente, você desejará muitas iterações deste teste para ter certeza de que o carrinho está mantendo o estado adequado: Existe mais de um unicórnio no carrinho antes de você começar? Quantos cabem no carrinho de compras? Se você criar mais de um com o mesmo nome e / ou recursos, ele falhará? Manterá apenas o existente ou acrescentará outro?

Cada vez que você passa pelo fluxo de trabalho, você deseja evitar ter que criar uma conta, fazer login como o usuário e configurar o unicórnio. Idealmente, você será capaz de criar uma conta e pré-configurar um unicórnio por meio da API ou banco de dados. Em seguida, tudo que você precisa fazer é fazer login como o usuário, localizar Sparkles, e adicioná-lo ao carrinho.

### Automatizar ou não automatizar?

A automação é sempre vantajosa? Quando se deve decidir automatizar os casos de teste?

Nem sempre é vantajoso automatizar casos de teste. Tem vezes que o teste manual pode ser mais apropriado. Por exemplo, se a interface do aplicativo mudará consideravelmente em um futuro próximo, então qualquer automação pode precisar ser reescrita de qualquer maneira. Além disso, às vezes simplesmente não há tempo suficiente para construir automação de testes. A curto prazo, o teste manual pode ser mais eficaz. Se um aplicativo tem um prazo muito curto, atualmente não há automação de teste disponível, e é imperativo que o teste seja feito dentro nesse período, o teste manual é a melhor solução.

# 3 - Tipos de teste

### Teste de aceitação

Este tipo de teste é feito para determinar se um recurso ou sistema atende às expectativas e requisitos do cliente. Este tipo de teste geralmente envolve cooperação ou feedback do cliente, sendo uma atividade de validação que responde a pergunta:

> Estamos construindo o produto ***certo***?.

Para aplicações web, a automação desse teste pode ser feita diretamente com o Selenium, simulando o comportamento esperado do usuário. Esta simulação pode ser feita por gravação / reprodução ou por meio dos diferentes idiomas suportados, conforme explicado nesta documentação. Observação: o teste de aceitação é um subtipo de ***teste funcional***, ao qual algumas pessoas também podem se referir.

### Teste funcional

Este tipo de teste é feito para determinar se um recurso ou sistema funciona corretamente sem problemas. Verifica o sistema em diferentes níveis para garantir que todos os cenários são cobertos e que o sistema faz *o que está* suposto fazer. É uma atividade de verificação que responde a pergunta:

> Estamos construindo o produto ***corretamente?***.

Isso geralmente inclui: os testes funcionam sem erros (404, exceções …), de forma utilizável (redirecionamentos corretos), de forma acessível e atendendo às suas especificações (consulte ***teste de aceitação*** acima).

Para aplicativos da web, a automação desse teste pode ser feito diretamente com o Selenium, simulando os retornos esperados. Esta simulação pode ser feita por gravação / reprodução ou por meio de os diferentes idiomas suportados, conforme explicado nesta documentação.

### Testes de Integração

Os testes de integração verificam as interações entre diferentes componentes ou módulos de um sistema. Vários módulos são testados juntos. O objetivo dos testes de integração é garantir que todos os módulos se integrem e funcionem juntos conforme esperado. Os testes de integração automatizados ajudam a garantir que essas interações funcionem conforme o esperado e que os componentes integrados funcionem corretamente juntos.

> Por exemplo, ***Testando o fluxo de pedido de um item em um site de comércio eletrônico junto com o pagamento.***

### Testes de sistema

O System Testing é um teste de produto completo e totalmente integrado. É um teste ponta a ponta onde o ambiente de teste é semelhante ao ambiente de produção. Aqui, navegamos por todos os recursos do software e testamos se o negócio final/recurso final funciona. Apenas testamos o recurso final e não verificamos o fluxo de dados, nem fazemos testes funcionais e tudo mais.

> Por exemplo, ***Testando o fluxo de ponta a ponta desde o login até a colocação e pedido e verificando novamente o pedido na página Meus Pedidos e logoff de um site de comércio eletrônico.***

### Teste de performance/desempenho

Como o próprio nome indica, testes de desempenho são feitos para medir o desempenho de um aplicativo.

Existem dois subtipos principais para testes de desempenho:

#### Teste de carga

O teste de carga é feito para verificar o quão bem o aplicativo funciona sob diferentes cargas definidas (geralmente um determinado número de usuários conectados ao mesmo tempo).

> For example, ***Testing that the site can handle numerous orders/users at once.***

#### Teste de estresse

O teste de estresse é feito para verificar o quão bem a aplicação funciona sob estresse (ou acima da carga máxima suportada).

> For example, ***Testing that your ecommerce site can handle Black Friday***

> For example, ***Testing that your new search bar doesn’t break the other buttons on the menu***

# 4 - Diretrizes e recomendações

Guias e recomendações ao preparar soluções de testes com o projecto Selenium.

Uma nota sobre “Melhores práticas”: evitamos intencionalmente a frase “Melhores Práticas” nesta documentação. Nenhuma abordagem funciona para todas as situações. Preferimos a ideia de “Diretrizes e Recomendações”. Nós encorajamos que você leia e decida cuidadosamente quais abordagens funcionarão para você em seu ambiente específico.

O teste funcional é difícil de acertar por muitos motivos. Como se o estado, a complexidade e as dependências do aplicativo não tornassem o teste suficientemente difícil, lidar com navegadores (especialmente com incompatibilidades entre navegadores) torna a escrita de bons testes um desafio.

Selenium fornece ferramentas para facilitar a interação funcional do usuário, mas não o ajuda a escrever suítes de teste bem arquitetadas. Neste capítulo, oferecemos conselhos, diretrizes e recomendações sobre como abordar a automação funcional de páginas da web.

Este capítulo registra os padrões de design de software populares entre muitos dos usuários do Selenium que tiveram sucesso ao longo dos anos.

# 4.1 - Modelos de objetos de página

```java
/***
 * Tests login feature
 */
public class Login {

  public void testLogin() {
    // fill login data on sign-in page
    driver.findElement(By.name("user_name")).sendKeys("userName");
    driver.findElement(By.name("password")).sendKeys("my supersecret password");
    driver.findElement(By.name("sign-in")).click();

    // verify h1 tag is "Hello userName" after login
    driver.findElement(By.tagName("h1")).isDisplayed();
    assertThat(driver.findElement(By.tagName("h1")).getText(), is("Hello userName"));
  }
}
```

There are two problems with this approach.

* There is no separation between the test method and the AUT’s locators (IDs in this example); both are intertwined in a single method. If the AUT’s UI changes its identifiers, layout, or how a login is input and processed, the test itself must change.
* The ID-locators would be spread in multiple tests, in all tests that had to use this login page.

Applying the page object model, this example could be rewritten like this in the following example of a page object for a Sign-in page.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Sign-in page.
 */
public class SignInPage {
  protected WebDriver driver;

  // <input name="user_name" type="text" value="">
  private By usernameBy = By.name("user_name");
  // <input name="password" type="password" value="">
  private By passwordBy = By.name("password");
  // <input name="sign_in" type="submit" value="SignIn">
  private By signinBy = By.name("sign_in");

  public SignInPage(WebDriver driver){
    this.driver = driver;
     if (!driver.getTitle().equals("Sign In Page")) {
      throw new IllegalStateException("This is not Sign In Page," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Login as valid user
    *
    * @param userName
    * @param password
    * @return HomePage object
    */
  public HomePage loginValidUser(String userName, String password) {
    driver.findElement(usernameBy).sendKeys(userName);
    driver.findElement(passwordBy).sendKeys(password);
    driver.findElement(signinBy).click();
    return new HomePage(driver);
  }
}
```

and page object for a Home page could look like this.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Home Page
 */
public class HomePage {
  protected WebDriver driver;

  // <h1>Hello userName</h1>
  private By messageBy = By.tagName("h1");

  public HomePage(WebDriver driver){
    this.driver = driver;
    if (!driver.getTitle().equals("Home Page of logged in user")) {
      throw new IllegalStateException("This is not Home Page of logged in user," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Get message (h1 tag)
    *
    * @return String message text
    */
  public String getMessageText() {
    return driver.findElement(messageBy).getText();
  }

  public HomePage manageProfile() {
    // Page encapsulation to manage profile functionality
    return new HomePage(driver);
  }
  /* More methods offering the services represented by Home Page
  of Logged User. These methods in turn might return more Page Objects
  for example click on Compose mail button could return ComposeMail class object */
}
```

So now, the login test would use these two page objects as follows.

```java
/***
 * Tests login feature
 */
public class TestLogin {

  @Test
  public void testLogin() {
    SignInPage signInPage = new SignInPage(driver);
    HomePage homePage = signInPage.loginValidUser("userName", "password");
    assertThat(homePage.getMessageText(), is("Hello userName"));
  }

}
```

```html
<!-- Products Page -->
<div class="header_container">
    <span class="title">Products</span>
</div>

<div class="inventory_list">
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
</div>
```

Each product is a component of the Products page.

```html
<!-- Inventory Item -->
<div class="inventory_item">
    <div class="inventory_item_name">Backpack</div>
    <div class="pricebar">
        <div class="inventory_item_price">$29.99</div>
        <button id="add-to-cart-backpack">Add to cart</button>
    </div>
</div>
```

The Products page HAS-A list of products. This object relationship is called Composition. In simpler terms, something is *composed of* another thing.

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

// Page Object
public class ProductsPage extends BasePage {
    public ProductsPage(WebDriver driver) {
        super(driver);
        // No assertions, throws an exception if the element is not loaded
        new WebDriverWait(driver, Duration.ofSeconds(3))
            .until(d -> d.findElement(By.className​("header_container")));
    }

    // Returning a list of products is a service of the page
    public List<Product> getProducts() {
        return driver.findElements(By.className​("inventory_item"))
            .stream()
            .map(e -> new Product(e)) // Map WebElement to a product component
            .toList();
    }

    // Return a specific product using a boolean-valued function (predicate)
    // This is the behavioral Strategy Pattern from GoF
    public Product getProduct(Predicate<Product> condition) {
        return getProducts()
            .stream()
            .filter(condition) // Filter by product name or price
            .findFirst()
            .orElseThrow(() -> new RuntimeException("Product not found")); // Error thrown during actual test run
    }
}
```

The Product component object is used inside the Products page object.

```java
public abstract class BaseComponent {
    protected WebElement root;

    public BaseComponent(WebElement root) {
        this.root = root;
    }
}

// Page Component Object
public class Product extends BaseComponent {
    // The root element contains the entire component
    public Product(WebElement root) {
        super(root); // inventory_item
    }

    public String getName() {
        // Locating an element begins at the root of the component
        return root.findElement(By.className("inventory_item_name")).getText();
    }

    public BigDecimal getPrice() {
        return new BigDecimal(
                root.findElement(By.className("inventory_item_price"))
                    .getText()
                    .replace("$", "")
            ).setScale(2, RoundingMode.UNNECESSARY); // Sanitation and formatting
    }

    public void addToCart() {
        root.findElement(By.id("add-to-cart-backpack")).click();
    }
}
```

So now, the products test would use the page object and the page component object as follows.

```java
public class ProductsTest {
    @Test
    public void testProductInventory() {
        var productsPage = new ProductsPage(driver); // page object
        var products = productsPage.getProducts();
        assertEquals(6, products.size()); // expected, actual
    }
    
    @Test
    public void testProductPrices() {
        var productsPage = new ProductsPage(driver);

        // Pass a lambda expression (predicate) to filter the list of products
        // The predicate or "strategy" is the behavior passed as parameter
        var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); // page component object
        var bikeLight = productsPage.getProduct(p -> p.getName().equals("Bike Light"));

        assertEquals(new BigDecimal("29.99"), backpack.getPrice());
        assertEquals(new BigDecimal("9.99"), bikeLight.getPrice());
    }
}
```

```java
public class LoginPage {
    public HomePage loginAs(String username, String password) {
        // ... clever magic happens here
    }
    
    public LoginPage loginAsExpectingError(String username, String password) {
        //  ... failed login here, maybe because one or both of the username and password are wrong
    }
    
    public String getErrorMessage() {
        // So we can verify that the correct error is shown
    }
}
```

The code presented above shows an important point: the tests, not the Page Objects, should be responsible for making assertions about the state of a page. For example:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    inbox.assertMessageWithSubjectIsUnread("I like cheese");
    inbox.assertMessageWithSubjectIsNotUnread("I'm not fond of tofu");
}
```

could be re-written as:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    assertTrue(inbox.isMessageWithSubjectIsUnread("I like cheese"));
    assertFalse(inbox.isMessageWithSubjectIsUnread("I'm not fond of tofu"));
}
```

```java
public class LoginPage {
    private final WebDriver driver;

    public LoginPage(WebDriver driver) {
        this.driver = driver;

        // Check that we're on the right page.
        if (!"Login".equals(driver.getTitle())) {
            // Alternatively, we could navigate to the login page, perhaps logging out first
            throw new IllegalStateException("This is not the login page");
        }
    }

    // The login page contains several HTML elements that will be represented as WebElements.
    // The locators for these elements should only be defined once.
        By usernameLocator = By.id("username");
        By passwordLocator = By.id("passwd");
        By loginButtonLocator = By.id("login");

    // The login page allows the user to type their username into the username field
    public LoginPage typeUsername(String username) {
        // This is the only place that "knows" how to enter a username
        driver.findElement(usernameLocator).sendKeys(username);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to type their password into the password field
    public LoginPage typePassword(String password) {
        // This is the only place that "knows" how to enter a password
        driver.findElement(passwordLocator).sendKeys(password);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to submit the login form
    public HomePage submitLogin() {
        // This is the only place that submits the login form and expects the destination to be the home page.
        // A seperate method should be created for the instance of clicking login whilst expecting a login failure. 
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the login page ever
        // go somewhere else (for example, a legal disclaimer) then changing the method signature
        // for this method will mean that all tests that rely on this behaviour won't compile.
        return new HomePage(driver);	
    }

    // The login page allows the user to submit the login form knowing that an invalid username and / or password were entered
    public LoginPage submitLoginExpectingFailure() {
        // This is the only place that submits the login form and expects the destination to be the login page due to login failure.
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the user ever be navigated to the home page after submiting a login with credentials 
        // expected to fail login, the script will fail when it attempts to instantiate the LoginPage PageObject.
        return new LoginPage(driver);	
    }

    // Conceptually, the login page offers the user the service of being able to "log into"
    // the application using a user name and password. 
    public HomePage loginAs(String username, String password) {
        // The PageObject methods that enter username, password & submit login have already defined and should not be repeated here.
        typeUsername(username);
        typePassword(password);
        return submitLogin();
    }
}
```

# 4.2 - Linguagem específica de domínio (DSL)

```java
/**
 * Recebe um username e password, prrenche os campos, e clica em "login".
 * @return Uma instância de AccountPage
 */
public AccountPage loginAsUser(String username, String password) {
  WebElement loginField = driver.findElement(By.id("loginField"));
  loginField.clear();
  loginField.sendKeys(username);

  // Preenche o campo password. O localizador que estamos usando é "By.id", e devemos
  // definí-lo em algum outro lugar dentro da Classe.
  WebElement passwordField = driver.findElement(By.id("password"));
  passwordField.clear();
  passwordField.sendKeys(password);

  // Clica o botão de login, que possui o id "submit".
  driver.findElement(By.id("submit")).click();

  // Cria e retorna uma nova instância de AccountPage (via o Selenium
  // PageFactory embutido).
  return PageFactory.newInstance(AccountPage.class);
}
```

Este método abstrai completamente os conceitos de campos de entrada, botões, cliques e até páginas do seu código de teste. Usando este abordagem, tudo o que o testador precisa fazer é chamar esse método. Isto dá uma vantagem de manutenção: se os campos de login mudaram, você teria apenas que alterar esse método - não seus testes.

```java
public void loginTest() {
    loginAsUser("cbrown", "cl0wn3");

    // Agora que estamos logados, fazemos alguma outra coisa--como usamos uma DSL para suportar
    // nossos testadores, é apenas escolher um dos métodos disponíveis.
    do.something();
    do.somethingElse();
    Assert.assertTrue("Algo deveria ter sido feito!", something.wasDone());

    // Note que ainda não nos referimos a nenhum botão ou web control nesse
    // script...
}
```

Vale a pena repetir: um de seus principais objetivos deve ser escrever um API que permite que seus testes resolvam **o problema em questão, e NÃO o problema da IU**. A IU é uma preocupação secundária para o seu usuários - eles não se importam com a interface do usuário, eles apenas querem fazer seu trabalho feito. Seus scripts de teste devem ser lidos como uma lista de itens sujos que o usuário deseja FAZER e as coisas que deseja SABER. Os testes não devem se preocupar com COMO a interface do usuário exige que você vá sobre isso.

\***AUT**: Application under test

# 4.3 - Gerando estado da aplicação

Selenium não deve ser usado para preparar um caso de teste. Tudo as ações repetitivas e preparações para um caso de teste devem ser feitas por meio de outros métodos. Por exemplo, a maioria das IUs da web tem autenticação (por exemplo, um formulário de login). Eliminar o login via navegador da web antes de cada teste irá melhorar a velocidade e estabilidade do teste. Um método deve ser criado para obter acesso à AUT\* (por exemplo, usando uma API para fazer login e definir um cookie). Além disso, a criação de métodos para pré-carregar dados para o teste não deve ser feito usando Selenium. Como dito anteriormente, APIs existentes devem ser aproveitadas para criar dados para a AUT \*.

\***AUT**: Application under test

# 4.4 - Simulação de serviços externos

Eliminar as dependências de serviços externos melhorará muito a velocidade e estabilidade de seus testes.

# 4.5 - Relatórios melhorados

O Selenium não foi projetado para relatar sobre o status de casos de teste. Aproveitar os recursos de relatórios integrados de frameworks de teste unitários é um bom começo. A maioria dos frameworks de teste unitários podem gerar relatórios formatados em xUnit ou HTML. Relatórios xUnit são populares para importar resultados para um servidor de integração contínua (CI) como Jenkins, Travis, Bamboo, etc. Aqui estão alguns links para obter mais informações sobre resultados de relatórios em vários idiomas.

[NUnit 3 Console Runner](//github.com/nunit/docs/wiki/Console-Runner)

[NUnit 3 Console Command Line](//github.com/nunit/docs/wiki/Console-Command-Line)

[xUnit getting test results in TeamCity](//xunit.net/docs/getting-test-results-in-teamcity)

[xUnit getting test results in CruiseControl.NET](//xunit.net/docs/getting-test-results-in-ccnet)

[xUnit getting test results in Azure DevOps](//xunit.net/docs/getting-test-results-in-azure-devops)

# 4.6 - Evite compartilhamento de estado

Embora mencionado em vários lugares, vale a pena mencionar novamente. Garanta que os testes são isolados uns dos outros.

* Não compartilhe dados de teste. Imagine vários testes em que cada um consulta o banco de dados para pedidos válidos antes de escolher um para executar uma ação. Caso dois testes peguem a mesma ordem, provavelmente você obterá um comportamento inesperado.

* Limpe dados desatualizados no aplicativo que podem ser obtidos por outro teste, por exemplo registros de pedidos inválidos.

* Crie uma nova instância do WebDriver por teste. Isso ajuda a garantir o isolamento do teste e torna a paralelização mais simples.

  * If you choose [pytest](https://pytest.org/) as your test runner, this can be easily done by yielding your driver in a global fixture. This way each test gets its own driver instance, and you can ensure that drivers always quit after a test is finished (pass or fail).

# 4.7 - Tips on working with locators

# 4.8 - Independência de Testes

Escreva cada teste como sua própria unidade. Escreva os testes de uma forma que não seja dependente de outros testes para concluir:

Digamos que existe um sistema de gerenciamento de conteúdo com o qual você pode criar algum conteúdo personalizado que então aparece em seu site como um módulo após publicação, e pode levar algum tempo para sincronizar entre o CMS e a aplicação.

Uma maneira errada de testar seu módulo é que o conteúdo seja criado e publicado em um teste e, em seguida, verificar o módulo em outro teste. Este teste não é viável, pois o conteúdo pode não estar disponível imediatamente para o outro teste após a publicação.

Em vez disso, você pode criar um conteúdo stub que pode ser ligado e desligado dentro do teste e use-o para validar o módulo. Contudo, para a criação de conteúdo, você ainda pode ter um teste separado.

# 4.9 - Considere usar uma API fluente

Martin Fowler cunhou o termo [“API Fluent”](//www.martinfowler.com/bliki/FluentInterface.html). Selenium já implementa algo assim em sua classe `FluentWait`, que é pretende ser uma alternativa à classe padrão `Wait`. Você pode habilitar o padrão de design de API fluente em seu objeto de página e, em seguida, consulte a página de pesquisa do Google com um snippet de código como este:

```java
driver.get( "http://www.google.com/webhp?hl=en&amp;tab=ww" );
GoogleSearchPage gsp = new GoogleSearchPage(driver);
gsp.setSearchString().clickSearchButton();
```

A classe de objeto da página do Google com este comportamento fluente pode ser assim:

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

public class GoogleSearchPage extends BasePage {
    public GoogleSearchPage(WebDriver driver) {
        super(driver);
        // Generally do not assert within pages or components.
        // Effectively throws an exception if the lambda condition is not met.
        new WebDriverWait(driver, Duration.ofSeconds(3)).until(d -> d.findElement(By.id("logo")));
    }

    public GoogleSearchPage setSearchString(String sstr) {
        driver.findElement(By.id("gbqfq")).sendKeys(sstr);
        return this;
    }

    public void clickSearchButton() {
        driver.findElement(By.id("gbqfb")).click();
    }
}
```

# 4.10 - Navegador novo por teste

Comece cada teste a partir de um estado limpo conhecido. Idealmente, ligue uma nova máquina virtual para cada teste. Se ligar uma nova máquina virtual não for prático, pelo menos inicie um novo WebDriver para cada teste. Most browser drivers like GeckoDriver and ChromeDriver will start with a clean known state with a new user profile, by default.

```java
WebDriver driver = new FirefoxDriver();
```

# 5 - Piores práticas

Temas a evitar quando automatizar navegadores com Selenium.

# 5.1 - Captchas

CAPTCHA, abreviação de *Completely Automated Public Turing test to tell Computers and Humans Apart*, foi projetado explicitamente para impedir a automação, portanto, não tente! Existem duas estratégias principais para contornar as verificações CAPTCHA:

* Desative CAPTCHAs em seu ambiente de teste
* Adicione um hook para permitir que os testes ignorem o CAPTCHA

# 5.2 - Downloads de arquivo

Embora seja possível iniciar um download clicando em um link com um navegador sob o controle do Selenium, a API não expõe o progresso do download, tornando-o menos do que ideal para testar arquivos baixados. Isso ocorre porque o download de arquivos não é considerado um aspecto importante de emular a interação do usuário com a plataforma da web. Em vez disso, encontre o link usando Selenium (e todos os cookies necessários) e passe este cookie para uma biblioteca de solicitação HTTP como [curl](https://curl.se/).

O [driver HtmlUnit](https://github.com/SeleniumHQ/htmlunit-driver) pode baixar anexos acessando-os como fluxos de entrada, implementando o [AttachmentHandler](https://htmlunit.sourceforge.io/apidocs/com/gargoylesoftware/htmlunit/attachment/AttachmentHandler.html). O AttachmentHandler pode ser adicionado ao WebClient [HtmlUnit](https://htmlunit.sourceforge.io/).

# 5.3 - Códigos de respostas HTTP

Para algumas configurações de navegador no Selenium RC, Selenium atuou como um proxy entre o navegador e o site sendo automatizado. Isso significa que todo o tráfego do navegador que passou pelo Selenium poderia ser capturado ou manipulado. O método `captureNetworkTraffic()` pretendia capturar todo o tráfego de rede entre o navegador e o site sendo automatizado, incluindo códigos de resposta HTTP.

Selenium WebDriver é uma abordagem completamente diferente para a automação do navegador, preferindo agir mais como um usuário. Isso é representado na maneira como você escreve testes com o WebDriver. Em testes funcionais automatizados, verificar o código de status não é um detalhe particularmente importante da falha de um teste; as etapas que o precederam são mais importantes.

O navegador sempre representará o código de status HTTP, imagine, por exemplo, uma página de erro 404 ou 500. Uma maneira simples de “falhar rapidamente” quando você encontrar uma dessas páginas de erro é verificar o título da página ou o conteúdo de um ponto confiável (por exemplo, a tag `<h1>`) após cada carregamento de página. Se você estiver usando o modelo de objeto de página, você pode incluir esta verificação em seu construtor de classe ou ponto semelhante onde o carregamento da página é esperado. Ocasionalmente, o código HTTP pode até ser representado na página de erro do navegador e você pode usar o WebDriver para ler isso e melhorar sua saída de depuração.

Verificar se a própria página da web está alinhada com a prática ideal do WebDriver de representar a visão do usuário do site.

Se você insiste, uma solução avançada para capturar códigos de status HTTP é replicar o comportamento do Selenium RC usando um proxy. A API WebDriver fornece a capacidade de definir um proxy para o navegador, e há uma série de proxies que irão permitir que você manipule de forma programática o conteúdo das solicitações enviadas e recebidas do servidor da web. Usar um proxy permite que você decida como deseja responder para códigos de resposta de redirecionamento. Além disso, nem todo navegador torna os códigos de resposta disponíveis para WebDriver, então optar por usar um proxy permite que você tenha uma solução que funciona para todos os navegadores.

# 5.4 - Login via Gmail, email e Facebook

Por vários motivos, fazer login em sites como Gmail e Facebook usando do WebDriver não é recomendado. Além de ser contra os termos de uso desses sites (onde você corre o risco de ter a conta encerrada), é lento e não confiável.

A prática ideal é usar as APIs que os provedores de e-mail oferecem, ou no caso do Facebook, o serviço de ferramentas para desenvolvedores que expõe uma API para criar contas de teste, amigos e assim por diante. Embora usar uma API possa parecer um pouco trabalhoso, você será recompensado em velocidade, confiabilidade e estabilidade. A API também não deve mudar, enquanto as páginas da web e os localizadores de HTML mudam frequentemente e exigem que você atualize sua estrutura de teste.

Login em sites de terceiros usando WebDriver em qualquer ponto do seu teste aumenta o risco de seu teste falhar porque torna o teste mais longo. Uma regra geral é que testes mais longos são mais frágeis e não confiáveis.

Implementações WebDriver que estão [em conformidade com W3C](//w3c.github.io/webdriver/webdriver-spec.html) também anotam o objeto `navigator` com uma propriedade `WebDriver` para que os ataques de negação de serviço possam ser mitigados.

# 5.5 - Dependência entre testes

Uma ideia comum e um equívoco sobre o teste automatizado é sobre uma ordem de testes específica. Seus testes devem ser executados em **qualquer** ordem, e não depender da conclusão de outros testes para ter sucesso.

# 5.6 - Teste de performance/desempenho

Teste de desempenho usando Selenium e WebDriver geralmente não é recomendado. Não porque é incapaz, mas porque não é otimizado para o trabalho e é improvável que você obtenha bons resultados.

Pode parecer ideal para teste de desempenho no contexto do usuário, mas um conjunto de testes WebDriver estão sujeitos a muitos pontos de fragilidade externa e interna que estão além do seu controle; por exemplo, velocidade de inicialização do navegador, velocidade dos servidores HTTP, resposta de servidores de terceiros que hospedam JavaScript ou CSS, e a penalidade de instrumentação da própria implementação do WebDriver. A variação nesses pontos causará variação em seus resultados. É difícil separar a diferença entre o desempenho do seu site e o desempenho de recursos externos, e também é difícil dizer qual é a penalidade de desempenho para usar WebDriver no navegador, especialmente se você estiver injetando scripts.

A outra atração potencial é “economizar tempo” - execução de testes funcionais e de desempenho ao mesmo tempo. No entanto, os testes funcionais e de desempenho têm objetivos opostos. Para testar a funcionalidade, um testador pode precisar ser paciente e aguarde o carregamento, mas isso irá turvar os resultados do teste de desempenho e vice-versa.

Para melhorar o desempenho do seu site, você precisará ser capaz de analisar o desempenho geral independente das diferenças de ambiente, identificar práticas de código ruins, repartição do desempenho de recursos individuais (ou seja, CSS ou JavaScript), para saber o que melhorar. Existem ferramentas de teste de desempenho disponíveis que podem fazer este trabalho, que fornecem relatórios e análises, e podem até fazer sugestões de melhorias.

Pacotes de exemplo (código aberto) a serem usados ​​são: [JMeter](/pt-br/)

# 5.7 - Navegação por links

Usar o WebDriver para navegar por links não é uma prática recomendada. Não porque não pode ser feito, mas porque WebDriver definitivamente não é a ferramenta ideal para isso. O WebDriver precisa de tempo para inicializar, e pode levar vários segundos, até um minuto dependendo de como seu teste é escrito, apenas para chegar à página e atravessar o DOM.

Em vez de usar o WebDriver para isso, você poderia economizar muito tempo executando um comando [curl](https://curl.se/), ou usando uma biblioteca como BeautifulSoup uma vez que esses métodos não dependem em criar um navegador e navegar para uma página. Você está economizando muito tempo por não usar o WebDriver para essa tarefa.

# 5.8 - Autenticação de Dois Fatores (2FA)

----
url: https://www.selenium.dev/pt-br/documentation/legacy/
----

# Legado

Nesta seção você pode encontrar toda a documentação relacionada aos componentes legados do Selenium. Isso deve ser mantido puramente por razões históricas e não como um incentivo para o uso obsoleto componentes.

**Most of the documentation found in this section is still in English. Please note we are not accepting pull requests to translate this content as translating documentation of legacy components does not add value to the community nor the project.

***

##### [Selenium RC (Selenium 1)](/pt-br/documentation/legacy/selenium_1/)

The original version of Selenium

##### [Selenium 2](/pt-br/documentation/legacy/selenium_2/)

Selenium 2 was a rewrite of Selenium 1 that was implemented with WebDriver code.

##### [Selenium 3](/pt-br/documentation/legacy/selenium_3/)

Selenium 3 was the implementation of WebDriver without the Selenium RC Code. It has since been replaced with Selenium 4, which implements the W3C WebDriver specification.

##### [Selenium IDE Legado](/pt-br/documentation/legacy/selenium_ide/)

----
url: https://www.selenium.dev/documentation/webdriver/getting_started/
----

# Getting started

If you are new to Selenium, we have a few resources that can help you get up to speed right away.

***

##### [Install a Selenium library](/documentation/webdriver/getting_started/install_library/)

Setting up the Selenium library for your favourite programming language.

##### [Write your first Selenium script](/documentation/webdriver/getting_started/first_script/)

Step-by-step instructions for constructing a Selenium script

##### [Organizing and Executing Selenium Code](/documentation/webdriver/getting_started/using_selenium/)

Scaling Selenium execution with an IDE and a Test Runner library

Last modified January 12, 2022: [Example code (#920) \[deploy site\] (d22cd1c186e)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/d22cd1c186e65418f289ba81455a2e1b7d4d12ab)

----
url: https://www.selenium.dev/documentation/grid/configuration/toml_options/
----

# TOML configuration options

```toml
[section1]
option1="value"

[section2]
option2=["value1","value2"]
option3=true
```

Below are some examples of Grid components configured with a Toml file, the component can be started in the following way:

```
java -jar selenium-server-<version>.jar <component> --config /path/to/file/<file-name>.toml
```

### Standalone

A Standalone server, running on port 4449, and a new session request timeout of 500 seconds.

```toml
[server]
port = 4449

[sessionqueue]
session-request-timeout = 500
```

### Specific browsers and a limit of max sessions

A Standalone server or a Node which only has Firefox and Chrome enabled by default.

```toml
[node]
drivers = ["chrome", "firefox"]
max-sessions = 3
```

### Configuring and customising drivers

Standalone or Node server with customised drivers, which allows things like having Firefox Beta or Nightly, and having different browser versions.

```toml
[node]
detect-drivers = false
[[node.driver-configuration]]
max-sessions = 100
display-name = "Firefox Nightly"
stereotype = "{\"browserName\": \"firefox\", \"browserVersion\": \"93\", \"platformName\": \"MAC\", \"moz:firefoxOptions\": {\"binary\": \"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"
[[node.driver-configuration]]
display-name = "Chrome Beta"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"94\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta\"}}"
[[node.driver-configuration]]
display-name = "Chrome Dev"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"95\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev\"}}"
webdriver-executable = '/path/to/chromedriver/95/chromedriver'
```

### Standalone or Node with Docker

A Standalone or Node server that is able to run each new session in a Docker container. Disabling drivers detection, having maximum 2 concurrent sessions. Stereotypes configured need to be mapped to a Docker image, and the Docker daemon needs to be exposed via http/tcp. In addition, it is possible to define which device files, accessible on the host, will be available in containers through the `devices` property. Refer to the [docker](https://docs.docker.com/engine/reference/commandline/run/#add-host-device-to-container---device) documentation for more information about how docker device mapping works.

```toml
[node]
detect-drivers = false
max-sessions = 2

[docker]
configs = [
    "selenium/standalone-chrome:93.0", "{\"browserName\": \"chrome\", \"browserVersion\": \"91\"}", 
    "selenium/standalone-firefox:92.0", "{\"browserName\": \"firefox\", \"browserVersion\": \"92\"}"
]
#Optionally define all device files that should be mapped to docker containers
#devices = [
#    "/dev/kvm:/dev/kvm"
#]
url = "http://localhost:2375"
video-image = "selenium/video:latest"
```

### Relaying commands to a service endpoint that supports WebDriver

It is useful to connect an external service that supports WebDriver to Selenium Grid. An example of such service could be a cloud provider or an Appium server. In this way, Grid can enable more coverage to platforms and versions not present locally.

The following is an en example of connecting an Appium server to Grid.

```toml
[node]
detect-drivers = false

[relay]
# Default Appium/Cloud server endpoint
url = "http://localhost:4723/wd/hub"
status-endpoint = "/status"
# Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status (e.g. HTTP/1.1, HTTP/2)
protocol-version = "HTTP/1.1"
# Stereotypes supported by the service. The initial number is "max-sessions", and will allocate 
# that many test slots to that particular configuration
configs = [
  "5", "{\"browserName\": \"chrome\", \"platformName\": \"android\", \"appium:platformVersion\": \"11\"}"
]
```

### Basic auth enabled

It is possible to protect a Grid with basic auth by configuring the Router/Hub/Standalone with a username and password. This user/password combination will be needed when loading the Grid UI or starting a new session.

```toml
[router]
username = "admin"
password = "myStrongPassword"
```

Here is a Java example showing how to start a session using the configured user and password.

```java
ClientConfig clientConfig = ClientConfig.defaultConfig()
  .baseUrl(new URL("http://localhost:4444"))
  .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"));
HttpCommandExecutor executor = new HttpCommandExecutor(clientConfig);
RemoteWebDriver driver = new RemoteWebDriver(executor, new ChromeOptions());
```

In other languages, you can use the URL http\://admin:myStrongPassword\@localhost:4444

### Setting custom capabilities for matching specific Nodes

**Important:** Custom capabilities need to be set in the configuration in all Nodes. They also need to be included always in every session request.

```toml
[node]
detect-drivers = false

[[node.driver-configuration]]
display-name = "firefox"
stereotype = '{"browserName": "firefox", "platformName": "macOS", "browserVersion":"96", "networkname:applicationName":"node_1", "nodename:applicationName":"app_1" }'
max-sessions = 5
```

Here is a Java example showing how to match that Node

```java
FirefoxOptions options = new FirefoxOptions();
options.setCapability("networkname:applicationName", "node_1");
options.setCapability("nodename:applicationName", "app_1");
options.setBrowserVersion("96");
options.setPlatformName("macOS");
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

### Enabling Managed downloads by the Node.

The Node can be instructed to manage downloads automatically. This will cause the Node to save all files that were downloaded for a particular session into a temp directory, which can later be retrieved from the node. To turn this capability on, use the below configuration:

```toml
[node]
enable-managed-downloads = true
```

Refer to the [CLI section](https://www.selenium.dev/documentation/grid/configuration/cli_options/#enabling-managed-downloads-by-the-node) for a complete example.

Last modified April 23, 2024: [\[grid\] update list CLI/TOML options (#1683) (1f27efd060f)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/1f27efd060fbacdd93b29416182faa8636bd6604)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/bidi/logging/
----

# WebDriver BiDi Logging Features

These features are related to logging. Because “logging” can refer to so many different things, these methods are made available via a “script” namespace.

Remember that to use WebDriver BiDi, you must enable it in Options. For more details, see [Enabling BiDi](https://www.selenium.dev/pt-br/documentation/webdriver/bidi/)

```py
    driver.script.add_console_message_handler(log_entries.append)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/test_bidi_logging.py#L11)

##### /examples/python/tests/bidi/test\_bidi\_logging.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_console_message_handler(log_entries.append)

    driver.find_element(By.ID, "consoleLog").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Hello, world!"


@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0


@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_javascript_error_handler(log_entries.append)

    driver.find_element(By.ID, "jsException").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Error: Not working"


@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    log_entries = []
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/logging_spec.rb#L11)

##### /examples/ruby/spec/bidi/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_console_message_handler { |log| log_entries << log }

    driver.find_element(id: 'consoleLog').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Hello, world!'
  end

  it 'removes console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_console_message_handler { |log| log_entries << log }
    driver.script.remove_console_message_handler(id)

    driver.find_element(id: 'consoleLog').click
    expect(log_entries).to be_empty
  end

  it 'adds JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_javascript_error_handler { |error| log_entries << error }

    driver.find_element(id: 'jsException').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Error: Not working'
  end

  it 'removes JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_javascript_error_handler { |error| log_entries << error }
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(id: 'jsException').click
    expect(log_entries).to be_empty
  end
end
```

```py
    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/test_bidi_logging.py#L23-24)

##### /examples/python/tests/bidi/test\_bidi\_logging.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_console_message_handler(log_entries.append)

    driver.find_element(By.ID, "consoleLog").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Hello, world!"


@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0


@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_javascript_error_handler(log_entries.append)

    driver.find_element(By.ID, "jsException").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Error: Not working"


@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    log_entries = []
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/logging_spec.rb#L22-L23)

##### /examples/ruby/spec/bidi/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_console_message_handler { |log| log_entries << log }

    driver.find_element(id: 'consoleLog').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Hello, world!'
  end

  it 'removes console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_console_message_handler { |log| log_entries << log }
    driver.script.remove_console_message_handler(id)

    driver.find_element(id: 'consoleLog').click
    expect(log_entries).to be_empty
  end

  it 'adds JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_javascript_error_handler { |error| log_entries << error }

    driver.find_element(id: 'jsException').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Error: Not working'
  end

  it 'removes JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_javascript_error_handler { |error| log_entries << error }
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(id: 'jsException').click
    expect(log_entries).to be_empty
  end
end
```

```py
    driver.script.add_javascript_error_handler(log_entries.append)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/test_bidi_logging.py#L35)

##### /examples/python/tests/bidi/test\_bidi\_logging.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_console_message_handler(log_entries.append)

    driver.find_element(By.ID, "consoleLog").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Hello, world!"


@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0


@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_javascript_error_handler(log_entries.append)

    driver.find_element(By.ID, "jsException").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Error: Not working"


@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    log_entries = []
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/logging_spec.rb#L33)

##### /examples/ruby/spec/bidi/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_console_message_handler { |log| log_entries << log }

    driver.find_element(id: 'consoleLog').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Hello, world!'
  end

  it 'removes console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_console_message_handler { |log| log_entries << log }
    driver.script.remove_console_message_handler(id)

    driver.find_element(id: 'consoleLog').click
    expect(log_entries).to be_empty
  end

  it 'adds JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_javascript_error_handler { |error| log_entries << error }

    driver.find_element(id: 'jsException').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Error: Not working'
  end

  it 'removes JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_javascript_error_handler { |error| log_entries << error }
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(id: 'jsException').click
    expect(log_entries).to be_empty
  end
end
```

```py
    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/test_bidi_logging.py#L47-48)

##### /examples/python/tests/bidi/test\_bidi\_logging.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.driver_type("bidi")
def test_add_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_console_message_handler(log_entries.append)

    driver.find_element(By.ID, "consoleLog").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Hello, world!"


@pytest.mark.driver_type("bidi")
def test_remove_console_log_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_console_message_handler(log_entries.append)
    driver.script.remove_console_message_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0


@pytest.mark.driver_type("bidi")
def test_add_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    driver.script.add_javascript_error_handler(log_entries.append)

    driver.find_element(By.ID, "jsException").click()
    WebDriverWait(driver, 5).until(lambda _: log_entries)
    assert log_entries[0].text == "Error: Not working"


@pytest.mark.driver_type("bidi")
def test_remove_js_exception_handler(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    log_entries = []

    id = driver.script.add_javascript_error_handler(log_entries.append)
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(By.ID, "consoleLog").click()
    assert len(log_entries) == 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    log_entries = []
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/logging_spec.rb#L44-L45)

##### /examples/ruby/spec/bidi/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_bidi_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'adds console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_console_message_handler { |log| log_entries << log }

    driver.find_element(id: 'consoleLog').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Hello, world!'
  end

  it 'removes console message handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_console_message_handler { |log| log_entries << log }
    driver.script.remove_console_message_handler(id)

    driver.find_element(id: 'consoleLog').click
    expect(log_entries).to be_empty
  end

  it 'adds JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    driver.script.add_javascript_error_handler { |error| log_entries << error }

    driver.find_element(id: 'jsException').click
    wait.until { log_entries.any? }
    expect(log_entries.first&.text).to eq 'Error: Not working'
  end

  it 'removes JavaScript error handler' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html'
    log_entries = []

    id = driver.script.add_javascript_error_handler { |error| log_entries << error }
    driver.script.remove_javascript_error_handler(id)

    driver.find_element(id: 'jsException').click
    expect(log_entries).to be_empty
  end
end
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

Última modificação October 18, 2024: [add missing pages for netowrk and logging (670665592ab)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/670665592ab989df69a847b0ca71d1e081c3138f)

----
url: https://www.selenium.dev/pt-br/documentation/overview/components/
----

# Entendendo os componentes

Última modificação October 29, 2025: [Robotium does not support natural language features. Robot Framework … (#2508) (9667de56d4f)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/9667de56d4f85dfa29d81741893570c0b7ae4cdd)

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/discouraged/two_factor_authentication/
----

# Autenticação de Dois Fatores (2FA)

A autenticação de dois fatores, conhecida como *2FA*, é um mecanismo de autorização onde a senha de uso único (OTP) é gerada usando aplicativos móveis “Autenticadores”, como “Google Authenticator”, “Microsoft Authenticator” etc., ou por SMS, e-mail para autenticação. Automatizar isso perfeitamente e consistentemente é um grande desafio no Selenium. Existem algumas maneiras para automatizar este processo. Mas essa será outra camada em cima de nossos testes Selenium e não protegidos também. Portanto, você pode evitar a automação do 2FA.

Existem algumas opções para contornar as verificações 2FA:

* Desative 2FA para determinados usuários no ambiente de teste, para que você possa usar essas credenciais de usuário na automação.
* Desative 2FA em seu ambiente de teste.
* Desative 2FA se você fizer o login de determinados IPs. Dessa forma, podemos configurar nosso teste os IPs da máquina para evitar isso.

----
url: https://www.selenium.dev/ja/documentation/webdriver/getting_started/install_library/
----

# Seleniumライブラリのインストール

```xml
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/pom.xml#L35-L38)

##### /examples/java/pom.xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>dev.selenium</groupId>
    <artifactId>selenium-examples</artifactId>
    <version>1.0.0</version>

    <properties>
        <surefire.parallel>1</surefire.parallel>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <selenium.version>4.41.0</selenium.version>
    </properties>

    <repositories>
        <repository>
            <name>Central Portal Snapshots</name>
            <id>central-portal-snapshots</id>
            <url>https://central.sonatype.com/repository/maven-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-grid</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>6.0.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.titusfortner</groupId>
            <artifactId>selenium-logger</artifactId>
            <version>2.4.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.5.5</version>
                <configuration>
                    <properties>
                        <configurationParameters>
                            junit.jupiter.execution.parallel.enabled = true
                            junit.jupiter.execution.parallel.mode.default = concurrent
                            junit.jupiter.execution.parallel.config.strategy = fixed
                            junit.jupiter.execution.parallel.config.fixed.parallelism = ${surefire.parallel}
                            junit.jupiter.execution.parallel.config.fixed.max-pool-size = ${surefire.parallel}
                        </configurationParameters>
                    </properties>
                    <rerunFailingTestsCount>3</rerunFailingTestsCount>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
```

### Gradle

プロジェクトの ‘build.gradle’ ファイル内の依存関係を ’testImplementation’ として指定します:

```gradle

dependencies {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/build.gradle#L13-L14)

##### /examples/java/build.gradle

```gradle
plugins {
    id 'java'
}

group 'dev.selenium'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

ext['seleniumVersion'] = System.getProperty('selenium.version', '4.41.0')

dependencies {
    testImplementation "org.seleniumhq.selenium:selenium-java:${seleniumVersion}"
    testImplementation "org.seleniumhq.selenium:selenium-grid:${seleniumVersion}"
    testImplementation platform("org.junit:junit-bom:6.0.2")
    testImplementation 'org.junit.jupiter:junit-jupiter-engine'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    testImplementation 'com.titusfortner:selenium-logger:2.4.0'
}

test {
    useJUnitPlatform()
}
```

各 Selenium バージョンでサポートされている最小 Python バージョンについては、次の場所にあります `サポートされている Python バージョン` オン [PyPi](https://pypi.org/project/selenium/)。

Seleniumをインストールするには、いくつかの方法があります。

### Pip

```shell
pip install selenium
```



### ダウンロード

または、ダウンロードすることもできます[PyPI ソースアーカイブ](https://pypi.org/project/selenium/#files) (selenium-x.x.x.-py3-none-any.whl) を使用してインストールします *pip*:

```shell
pip install selenium-x.x.x.-py3-none-any.whl
```



### プロジェクトで必要

プロジェクトで使用するには、requirements.txt ファイルに追加します:

```txt
selenium==4.41.0
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/requirements.txt#L1)

##### /examples/python/requirements.txt

```txt
selenium==4.41.0
pytest==9.0.3
trio==0.31.0
pytest-trio==0.8.0
pytest-rerunfailures==16.1
flake8==7.3.0
requests==2.33.0
tox==4.32.0
pytest-xdist==3.8.0
```

Seleniumの各バージョンでサポートされているすべてのフレームワークのリスト で利用可能です[Nuget](https://www.nuget.org/packages/Selenium.WebDriver)

Seleniumのインストールにはいくつかのオプションがあります。

### パケットマネージャー

```shell
Install-Package Selenium.WebDriver
```



### .NET CLI

```shell
dotnet add package Selenium.WebDriver
```



### CSProj

プロジェクトの `csproj`ファイルで、`ItemGroup` の `PackageReference`として依存関係を指定します。:

```csproj
      <PackageReference Include="Selenium.WebDriver" Version="4.41.0" />
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/SeleniumDocs.csproj#L14)

##### /examples/dotnet/SeleniumDocs/SeleniumDocs.csproj

```csproj
<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <GenerateProgramFile>false</GenerateProgramFile>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
      <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="7.7.1" />
      <PackageReference Include="MSTest.TestAdapter" Version="3.6.0" />
      <PackageReference Include="MSTest.TestFramework" Version="3.6.0" />
      <PackageReference Include="Selenium.Support" Version="4.41.0" />
      <PackageReference Include="Selenium.WebDriver" Version="4.41.0" />
    </ItemGroup>

    <ItemGroup>
      <Folder Include="LocalPackages" />
    </ItemGroup>

</Project>
```

### その他の考慮事項

その他、使用上の注意点 Visual Studio Code (vscode) そして C#

上記のセクションに従って、互換性のある .NET SDK をインストールします。 また、C# と NuGet の vscode 拡張機能 (Ctrl-Shift-X) もインストールします。に従ってください[指示はこちら](https://docs.microsoft.com/en-us/dotnet/core/tutorials/with-visual-studio-code?pivots=dotnet-5-0) C# を使用して “Hello World” コンソール プロジェクトを作成および実行します。 コマンドラインを使用してNUnitスタータープロジェクトを作成することもできます `dotnet new NUnit`. ファイルを確認してください `%appdata%\NuGet\nuget.config`一部の開発者がいくつかの問題のために空になると報告したため、適切に構成されています。 もし`nuget.config`が空であるか、正しく構成されていない場合、Selenium プロジェクトの .NET ビルドは失敗します。 次のセクションをファイルに追加します`nuget.config` 空の場合:

```
<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />   
  </packageSources>
...
```

詳細については、`nuget.config` [ここをクリック](https://docs.microsoft.com/en-us/nuget/reference/nuget-config-file). カスタマイズする必要があるかもしれません `nuget.config` あなたのニーズを満たすために。

さて、戻ってください vscode、プレス Ctrl-Shift-P、およびタイプ “NuGet Add Package"をクリックし、必要な Selenium パッケージ `Selenium.WebDriver`. Enter キーを押して、バージョンを選択します。 これで、C# と vscode に関連するドキュメントの例を使用できるようになりました。

特定の Selenium バージョンに対して最低限必要な Ruby のバージョンを確認できます オン [rubygems.org](https://rubygems.org/gems/selenium-webdriver/)

Seleniumは2つの異なる方法でインストールできます。

### 手動でインストールする

```shell
gem install selenium-webdriver
```



### プロジェクトの gemfile に追加

```gemfile
gem 'selenium-devtools', '= 0.147.0'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/Gemfile#L10)

##### /examples/ruby/Gemfile

```gemfile
# frozen_string_literal: true

source 'https://rubygems.org'

gem 'ffi', '~> 1.15', '>= 1.15.5' if Gem.win_platform? # Windows only
gem 'rake', '~> 13.0'
gem 'rspec', '~> 3.0'
gem 'rubocop', '~> 1.35'
gem 'rubocop-rspec', '~> 3.0'
gem 'selenium-devtools', '= 0.147.0'
gem 'selenium-webdriver', '= 4.43.0'
```

Seleniumの特定のバージョンに最低限必要なNodeのバージョンは、`Node Support Policy` 節 オン [npmjs](https://www.npmjs.com/package/selenium-webdriver)

Seleniumは通常、npmを使用してインストールされます。

### ローカルにインストールする

```shell
npm install selenium-webdriver
```



### プロジェクトに加える

プロジェクトの `package.json`で、要件を `dependencies`:

```json
        "mocha": "11.7.5"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/package.json#L14)

##### /examples/javascript/package.json

```json
{
    "name": "javascript-examples",
    "version": "1.0.0",
    "scripts": {
        "test": "npx mocha test/**/*.spec.js --timeout 120000 --parallel --retries 2"
    },
    "author": "The Selenium project",
    "license": "Apache-2.0",
    "dependencies": {
        "assert": "2.1.0",
        "selenium-webdriver": "4.41.0"
    },
    "devDependencies": {
        "mocha": "11.7.5"
    }
}
```

Kotlin の Java バインディングを使用します。

## 次のステップ

[初めてのSeleniumスクリプトを作成する](https://www.selenium.dev/ja/documentation/webdriver/getting_started/first_script/)

最終更新 September 2, 2025: [fixed line number to show case selenium maven dependency (#2450) (845ea50bbac)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/845ea50bbac1131c18ea2735554c1611e5369777)

----
url: https://www.selenium.dev/documentation/webdriver/interactions/frames/
----

# Working with IFrames and frames

Frames are a now deprecated means of building a site layout from multiple documents on the same domain. You are unlikely to work with them unless you are working with an pre HTML5 webapp. Iframes allow the insertion of a document from an entirely different domain, and are still commonly used.

If you need to work with frames or iframes, WebDriver allows you to work with them in the same way. Consider a button within an iframe. If we inspect the element using the browser development tools, we might see the following:

```html
<div id="modal">
  <iframe id="buttonframe" name="myframe"  src="https://seleniumhq.github.io">
   <button>Click here</button>
 </iframe>
</div>
```

```java
//This won't work
driver.findElement(By.tagName("button")).click();
  
```

```python
    # This Wont work
driver.find_element(By.TAG_NAME, 'button').click()
  
```

```csharp
//This won't work
driver.FindElement(By.TagName("button")).Click();
  
```

```ruby
    # This won't work
driver.find_element(:tag_name,'button').click
  
```

```javascript
// This won't work
await driver.findElement(By.css('button')).click();
  
```

```kotlin
//This won't work
driver.findElement(By.tagName("button")).click()
  
```

```java
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L38-L46)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L24-L32)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L38-L46)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L26-L33)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Store the web element
const iframe = driver.findElement(By.css('#modal > iframe'));

// Switch to the frame
await driver.switchTo().frame(iframe);

// Now we can click the button
await driver.findElement(By.css('button')).click();
  
```

```kotlin
//Store the web element
val iframe = driver.findElement(By.cssSelector("#modal>iframe"))

//Switch to the frame
driver.switchTo().frame(iframe)

//Now we can click the button
driver.findElement(By.tagName("button")).click()
  
```

```java
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L50-L58)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L34-L42)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L50-L58)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L36-L43)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Using the ID
await driver.switchTo().frame('buttonframe');

// Or using the name instead
await driver.switchTo().frame('myframe');

// Now we can click the button
await driver.findElement(By.css('button')).click();
  
```

```kotlin
//Using the ID
driver.switchTo().frame("buttonframe")

//Or using the name instead
driver.switchTo().frame("myframe")

//Now we can click the button
driver.findElement(By.tagName("button")).click()
  
```

```java
         //switch To IFrame using index
         driver.switchTo().frame(0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L62-L63)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L45-L46)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L62-L63)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L46-L47)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Switches to the second frame
await driver.switchTo().frame(1);
  
```

```kotlin
// Switches to the second frame
driver.switchTo().frame(1)
  
```

```java
         //leave frame
         driver.switchTo().defaultContent();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L66-L67)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L49-L50)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //leave frame
            driver.SwitchTo().DefaultContent();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L66-L67)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L49-L50)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Return to the top level
await driver.switchTo().defaultContent();
  
```

```kotlin
// Return to the top level
driver.switchTo().defaultContent()
  
```

----
url: https://www.selenium.dev/documentation/legacy/developers/crazy_fun_build/
----

# Crazy Fun Build Tool

The original Selenium Build Tool that grew from nothing to be extremely unwieldy, making it both crazy and “fun” to work with.

This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/Crazy-Fun-Build)

WebDriver is a large project: if we tried to push everything into a single monolithic build file it eventually becomes unmanageable. We know this. We’ve tried it. So we broke the single Rakefile into a series of `build.desc` files. Each of these describe a part of the build.

Let’s take a look at a build.desc file. This is part of the [main test build.desc](https://github.com/SeleniumHQ/selenium/blob/master/java/client/test/org/openqa/selenium/build.desc):

```
java_test(name = "single",
  srcs = [
    "SingleTestSuite.java",
  ],
  deps = [
    ":tests",
    "//java/server/src/org/openqa/selenium/server",
    "//java/client/test/org/openqa/selenium/v1:selenium-backed-webdriver-test",
    "//java/client/test/org/openqa/selenium/firefox:test",
  ]  ])
```

```
./go -T
```

Being a brief description of the available targets that you can use.

### Common Attributes

The following attributes are required for all build targets:

| **Attribute Name** | **Type** | **Meaning**                                                                 |
| ------------------ | -------- | --------------------------------------------------------------------------- |
| name               | string   | Used to derive the rake target and (often) the name of the generated binary |

The following attributes are commonly used:

| **Attribute Name** | **Type** | **Meaning**                                |
| ------------------ | -------- | ------------------------------------------ |
| srcs               | array    | The raw source to be build for this target |
| deps               | array    | Prerequisites of this target               |

### java\_library

* **Output:** JAR file named after the “name” attribute if the “srcs” attribute is set.
* **Implicit Targets:** run (if “main” attribute specifiec), project, project-srcs, uber, zip
* **Required Attributes:** “name” and at least one of “srcs” or “deps”.

| **Attribute Name** | **Type** | **Meaning**                                                                         |
| ------------------ | -------- | ----------------------------------------------------------------------------------- |
| deps               | array    | As above                                                                            |
| srcs               | array    | As above                                                                            |
| resources          | array    | Any resources that should be copied into the jar file.                              |
| main               | string   | The full classname of the main class of the jar (used for creating executable jars) |

### java\_test

* **Output:** JAR file named after the “name” attribute if the “srcs” attribute is set.
* **Implicit Targets:** run, project, project-srcs, uber, zip
* **Required Attributes:** “name” and at least one of “srcs” or “deps”.

| **Attribute Name** | **Type** | **Meaning**                                                      |
| ------------------ | -------- | ---------------------------------------------------------------- |
| deps               | array    | As above.                                                        |
| srcs               | array    | As above.                                                        |
| resources          | array    | Any resources that should be copied into the jar file.           |
| main               | string   | The alternative class to use for running these tests.            |
| args               | string   | The argument line to pass to the main class                      |
| sysproperties      | array    | An array of maps containing System properties that should be set |

### js\_deps

* **Output:** Marker file to indicate task is up to date.
* **Implicit Targets:** None
* **Required Attributes:** “name” and “srcs”

| **Attribute Name** | **Type** | **Meaning** |
| ------------------ | -------- | ----------- |
| name               | string   | As above    |
| srcs               | array    | As above    |
| deps               | array    | As above    |

### js\_binary

* **Output:** A monolithic JS file containing all dependencies and sources compiled using the closure compiler without optimizations.
* **Implicit Targets:** None
* **Required Attributes:** At least one of srcs or deps.

| **Attribute Name** | **Type** | **Meaning** |
| ------------------ | -------- | ----------- |
| name               | string   | As above    |
| srcs               | array    | As above    |
| deps               | array    | As above    |

### js\_fragment

* **Output:** Source of an anonymous function representing the exported function, compiled by the closure compiler with all optimizations turned on.
* **Implicit Targets:** None
* **Required Attributes:** name, module, function, deps

| **Attribute Name** | **Type** | **Meaning**                                    |
| ------------------ | -------- | ---------------------------------------------- |
| name               | string   | As above                                       |
| module             | string   | The name of the module containing the function |
| function           | string   | The full name of the function to export        |
| deps               | array    | As above                                       |

### js\_fragment\_header

* **Output:** A C header file with all js\_fragment dependencies declared as constants.
* **Implicit Targets:** None
* **Required Attributes:** name, deps

| **Attribute Name** | **Type** | **Meaning** |
| ------------------ | -------- | ----------- |
| name               | string   | As above    |
| srcs               | array    | As above    |
| deps               | array    | As above    |

### js\_test

* **Output:**
* **Implicit Targets:** `_`BROWSER:run, run
* **Required Attributes:** None.

| **Attribute Name** | **Type** | **Meaning**                                                                                                                                                                                                 |
| ------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| deps               | array    | As above.                                                                                                                                                                                                   |
| srcs               | array    | As above.                                                                                                                                                                                                   |
| path               | string   | The path at which to expect the test files to be hosted on the test server.                                                                                                                                 |
| browsers           | array    | List of browsers, from rake\_tasks/browsers.rb, to run the tests in. Will only attempt to run tests in those browsers which are available on the system. If absent, defaults to all browsers on the system. |

Assuming browsers = \[‘ff’, ‘chrome’], for target //foo, the implicit targets: //foo\_ff:run and //foo\_chrome:run will be generated, which run the tests in each of those browsers, and the implicit target //foo:run will be generated, which runs the tests in both ff and chrome.

### py\_test

* **Output:** Creates the directory structure required to run the listed python tests.
* **Implicit Targets:** `_`BROWSER:run, run
* **Required Attributes:** name.

| **Attribute Name**       | **Type** | **Meaning**                                                                                                                                                                                                     |
| ------------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| deps                     | array    | Other py\_test rule(s), whose tests should also be run.                                                                                                                                                         |
| common\_tests            | array    | Test file(s) to be run in all browsers. These tests will be passed through a template, with browser-specific substitutions, so that they are laid out properly for each browser in the python output file tree. |
| BROWSER\_specific\_tests | array    | Test file(s) to be run only in browser BROWSER.                                                                                                                                                                 |
| resources                | array    | Resources which should be copied to the python directory structure.                                                                                                                                             |
| browsers                 | array    | List of browsers, from rake\_tasks/browsers.rb, to run the tests in. Will only attempt to run tests in those browsers which are available on the system. If absent, defaults to all browsers on the system.     |

Note: Every py\_test invocation is performed in a new virtualenv.

### rake\_task

* **Output:** A crazy fun build rule that can be referred to “blow the escape” hatch and use ordinary rake targets.
* **Implicit Targets:** None
* **Required Attributes:** name, task\_name, out.

| **Attribute Name** | **Type** | **Meaning**                                          |
| ------------------ | -------- | ---------------------------------------------------- |
| name               | string   | As above                                             |
| task\_name         | string   | The ordinary rake target to call                     |
| out                | string   | The file that is generated, relative to the Rakefile |

### gcc\_library

* **Output:** Shared library file named after the “name” attribute if the “srcs” attribute is set.
* **Implicit Targets:** None.
* **Required Attributes:** “name” and “srcs”.

| **Attribute Name** | **Type** | **Meaning**                                          |
| ------------------ | -------- | ---------------------------------------------------- |
| srcs               | array    | As above                                             |
| arch               | string   | “amd64” for 64-bit builds, “i386” for 32-bit builds. |
| args               | string   | Arguments to the compiler (-I flags, for example).   |
| link\_args         | string   | Arguments to the linker (-l flags, for example)      |

Note: When building a new library for the first time, the build will succeed but copying to pre-built will fail with a similar message:

```
cp build/cpp/amd64/libimetesthandler64.so 
go aborted!
can't convert nil into String
```

Solution: Copy the just-built library to the appropriate prebuilt folder (cpp/prebuilt/arch/).

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/discouraged/
----

# 不鼓励的行为

使用Selenium自动化浏览器时应避免的事项.

***

##### [验证码](/zh-cn/documentation/test_practices/discouraged/captchas/)

##### [文件下载](/zh-cn/documentation/test_practices/discouraged/file_downloads/)

##### [HTTP响应码](/zh-cn/documentation/test_practices/discouraged/http_response_codes/)

##### [Gmail, email 和 Facebook 登录](/zh-cn/documentation/test_practices/discouraged/gmail_email_and_facebook_logins/)

##### [测试依赖](/zh-cn/documentation/test_practices/discouraged/test_dependency/)

##### [性能测试](/zh-cn/documentation/test_practices/discouraged/performance_testing/)

##### [爬取链接](/zh-cn/documentation/test_practices/discouraged/link_spidering/)

##### [双因素认证](/zh-cn/documentation/test_practices/discouraged/two_factor_authentication/)

----
url: https://www.selenium.dev/ja/documentation/webdriver/actions_api/mouse/
----

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L22-L25)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L14-L17)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L11-L14)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    let clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.move({origin: clickable}).press().perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/clickAndHold.spec.js#L14-L16)

##### /examples/javascript/test/actionsApi/mouse/clickAndHold.spec.js

```js
const {By, Builder} = require('selenium-webdriver');

describe('Click and hold', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and mouseDown on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    let clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.move({origin: clickable}).press().perform();
  });
});
```

```kt
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L23-L26)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L34-L37)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L26-L29)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L30-L33)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L22-L25)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    let click = driver.findElement(By.id("click"));
    const actions = driver.actions({async: true});
    await actions.move({origin: click}).click().perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/clickAndRelease.spec.js#L14-L16)

##### /examples/javascript/test/actionsApi/mouse/clickAndRelease.spec.js

```js
const {By,Builder} = require('selenium-webdriver');

describe('Click and release', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    let click = driver.findElement(By.id("click"));
    const actions = driver.actions({async: true});
    await actions.move({origin: click}).click().perform();
  });
});
```

```kt
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L35-L38)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L46-L49)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L37-L40)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L43-L46)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L34-L37)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.contextClick(clickable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/rightClick.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/rightClick.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Right click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and right click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.contextClick(clickable).perform();

    await driver.sleep(500);
    const clicked = await driver.findElement(By.id('click-status')).getText();
    assert.deepStrictEqual(clicked, `context-clicked`)
  });
});
```

```kt
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L47-L50)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L60-L66)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L51-L54)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L59-L63)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L47-L50)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js#L19-L20)

##### /examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js

```js
const {By, Button, Browser, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Should be able to perform BACK click and FORWARD click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Back click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)

    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)
  });

  it('Forward click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();
    await driver.navigate().back();

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)

    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L61-L67)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L78-L84)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L65-L68)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L77-L81)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L61-L64)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js#L32-L33)

##### /examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js

```js
const {By, Button, Browser, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Should be able to perform BACK click and FORWARD click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Back click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)

    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)
  });

  it('Forward click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();
    await driver.navigate().back();

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)

    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L79-L85)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L93-L96)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L76-L79)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L91-L94)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L73-L76)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.doubleClick(clickable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/doubleClick.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/doubleClick.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Double click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Double-click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.doubleClick(clickable).perform();

    await driver.sleep(500);
    const status = await driver.findElement(By.id('click-status')).getText();
    assert.deepStrictEqual(status, `double-clicked`)
  });
});
```

```kt
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L94-L97)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L105-L108)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L87-L90)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L104-L107)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L84-L87)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const hoverable = driver.findElement(By.id("hover"));
    const actions = driver.actions({async: true});
    await actions.move({origin: hoverable}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveToElement.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/moveToElement.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Move to element', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move into an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const hoverable = driver.findElement(By.id("hover"));
    const actions = driver.actions({async: true});
    await actions.move({origin: hoverable}).perform();

    const status = await driver.findElement(By.id('move-status')).getText();
    assert.deepStrictEqual(status, `hovered`)
  });
});
```

```kt
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L106-L109)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L118-L121)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L98-L101)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L132-L135)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L97-L100)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L119-L122)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L131-L136)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L110-L112)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L146-L150)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      driver.action
            .move_to_location(8, 12)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L114-L116)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L27-L28)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L132-L137)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L153-L155)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L126-L128)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L167-L169)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      driver.action
            .move_by(13, 15)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L128-L130)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L40)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L154-L156)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L166-L170)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L139-L143)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L181-L185)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L141-L145)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js#L27-L30)

##### /examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Drag and Drop', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('By Offset', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });

  it('Onto Element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });
});
```

```kt
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L167-L171)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L179-L184)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L151-L156)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L195-L200)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L153-L158)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js#L15-L19)

##### /examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Drag and Drop', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('By Offset', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });

  it('Onto Element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });
});
```

```kt
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L180-L185)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

----
url: https://www.selenium.dev/ja/documentation/ide/
----

# Selenium IDE

Selenium IDEは、ユーザーのアクションを記録および再生するブラウザー拡張機能です。

Seleniumの統合開発環境（[Selenium IDE](//selenium.dev/selenium-ide)）は、 各要素のコンテキストによって定義されたパラメーターを使用して、 既存のSeleniumコマンドを使用してブラウザーでのユーザーのアクションを記録する、使いやすいブラウザー拡張機能です。 これは、Seleniumの構文を学習するための優れた方法を提供します。 Google Chrome、Mozilla Firefox、およびMicrosoftEdgeで利用できます。

詳細については、充実している[Selenium IDE ドキュメント](https://www.selenium.dev/selenium-ide/docs/en/introduction/getting-started)をご覧ください。

最終更新 December 20, 2021: [Japanese Translation of Selenium IDE (#893)\[deploy site\] (121f6ab814b)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/121f6ab814b25bb25866c8e80e1ebc4670b220fd)

----
url: https://www.selenium.dev/ja/documentation/webdriver/bidi/w3c/log/
----

# BiDirectional API (W3C compliant)

```java
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L33-L39)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/logInspector.spec.js#L23-37)

##### /examples/javascript/test/bidirectional/logInspector.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const LogInspector = require('selenium-webdriver/bidi/logInspector');
const {Builder} = require("selenium-webdriver");


describe('Log Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test listen to console log', async function () {
    let logEntry = null
    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)

    await inspector.close()
  })

  it('test listen to javascript error log', async function () {
    let logEntry = null
    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')

    await inspector.close()
  })

  it('test retrieve stack trace for a log', async function () {
    let logEntry = null
    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()

    const stackTrace = logEntry.stackTrace
    assert.notEqual(stackTrace, null)
    assert.equal(stackTrace.callFrames.length, 3)

    await inspector.close()
  })

  it('test listen to logs with multiple consumers', async function () {
    let logEntry1 = null
    let logEntry2 = null
    const inspector = await LogInspector(driver)
    await inspector.onJavascriptException(function (log) {
      logEntry1 = log
    })
    await inspector.onJavascriptException(function (log) {
      logEntry2 = log
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    await driver.findElement({id: 'jsException'}).click()

    assert.equal(logEntry1.text, 'Error: Not working')
    assert.equal(logEntry1.type, 'javascript')
    assert.equal(logEntry1.level, 'error')

    assert.equal(logEntry2.text, 'Error: Not working')
    assert.equal(logEntry2.type, 'javascript')
    assert.equal(logEntry2.level, 'error')

    await inspector.close()
  })
})
```

```java
            logInspector.onJavaScriptException(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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L73-L78)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/logInspector.spec.js#L44-54)

##### /examples/javascript/test/bidirectional/logInspector.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const LogInspector = require('selenium-webdriver/bidi/logInspector');
const {Builder} = require("selenium-webdriver");


describe('Log Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test listen to console log', async function () {
    let logEntry = null
    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)

    await inspector.close()
  })

  it('test listen to javascript error log', async function () {
    let logEntry = null
    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')

    await inspector.close()
  })

  it('test retrieve stack trace for a log', async function () {
    let logEntry = null
    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()

    const stackTrace = logEntry.stackTrace
    assert.notEqual(stackTrace, null)
    assert.equal(stackTrace.callFrames.length, 3)

    await inspector.close()
  })

  it('test listen to logs with multiple consumers', async function () {
    let logEntry1 = null
    let logEntry2 = null
    const inspector = await LogInspector(driver)
    await inspector.onJavascriptException(function (log) {
      logEntry1 = log
    })
    await inspector.onJavascriptException(function (log) {
      logEntry2 = log
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    await driver.findElement({id: 'jsException'}).click()

    assert.equal(logEntry1.text, 'Error: Not working')
    assert.equal(logEntry1.type, 'javascript')
    assert.equal(logEntry1.level, 'error')

    assert.equal(logEntry2.text, 'Error: Not working')
    assert.equal(logEntry2.type, 'javascript')
    assert.equal(logEntry2.level, 'error')

    await inspector.close()
  })
})
```

```java
            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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L55-L60)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

最終更新 December 16, 2024: [\[java\] Remove a wrong code example and update code lines (#2104) (6b3cccc0e32)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/6b3cccc0e32b97a2a88350983e4b7c73836e0733)

----
url: https://www.selenium.dev/pt-br/_print/documentation/legacy/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/legacy/).

# Legado

Nesta seção você pode encontrar toda a documentação relacionada aos componentes legados do Selenium. Isso deve ser mantido puramente por razões históricas e não como um incentivo para o uso obsoleto componentes.

* 1: [Selenium RC (Selenium 1)](#pg-081aa9879433cf6a6bdb7c0adfc99de2)
* 2: [Selenium 2](#pg-a5bdeb24f81e3b25ee2f18f9e4e30b5f)
* * 2.1: [Migrando do RC para WebDriver](#pg-25a61dabe1d835dcab4b1fffc7ff6b8b)
  * 2.2: [Servidor do WebDriver remoto](#pg-2de1674c55bc150347c683000f704dc2)
  3: [Selenium 3](#pg-117e689de89ff15e11d1734c96bf618c)
* * 3.1: [Grid 3](#pg-22c4f48b7072956000ca38f27da0cc05)
  * 3.2: [Configurando a sua](#pg-695883420ae17227d8cc8d4d50b0aa70)
  * 3.3: [Componentes](#pg-cc6eb5c9bdbe3ebfd6bff949748a4ae0)
  4: [Selenium IDE Legado](#pg-71132677bae074d7a87bd59930add63b)
  * 4.1: [HTML runner](#pg-32119150ec982f9d853272754ecb1138)

**Most of the documentation found in this section is still in English. Please note we are not accepting pull requests to translate this content as translating documentation of legacy components does not add value to the community nor the project.

# 1 - Selenium RC (Selenium 1)

```shell
    java -jar selenium-server-standalone-<version-number>.jar
```

Isso pode ser simplificado criando um arquivo executável em lote ou shell (.bat no Windows e .sh no Linux) contendo o comando acima. Em seguida, faça um atalho para esse executável em seu desktop e simplesmente clique duas vezes no ícone para iniciar o servidor.

Para o servidor funcionar, você precisa do Java instalado e a variável de ambiente PATH configurada corretamente para executá-lo a partir do console. Você pode verificar se o Java está instalado corretamente executando o seguinte em um console.

```shell
       java -version
```

|                   |                            |             |
| ----------------- | -------------------------- | ----------- |
| open              | /                          |             |
| type              | q                          | selenium rc |
| clickAndWait      | btnG                       |             |
| assertTextPresent | Results \* for selenium rc |             |

Observação: este exemplo funcionaria com a página de pesquisa do Google <http://www.google.com>

### Selenese como código

Aqui está o script de teste exportado (via Selenium-IDE) para cada uma das linguagens de programação. Se você tem pelo menos conhecimento básico de linguagem de programação orientada a objetos (OOP), você vai entender como o Selenium executa comandos em Selenese lendo um destes exemplos. Para ver um exemplo em uma linguagem específica, selecione um desses botões.

#### CSharp

```csharp

        using System;
        using System.Text;
        using System.Text.RegularExpressions;
        using System.Threading;
        using NUnit.Framework;
        using Selenium;

        namespace SeleniumTests
        {
            [TestFixture]
            public class NewTest
            {
                private ISelenium selenium;
                private StringBuilder verificationErrors;
                
                [SetUp]
                public void SetupTest()
                {
                    selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
                    selenium.Start();
                    verificationErrors = new StringBuilder();
                }
                
                [TearDown]
                public void TeardownTest()
                {
                    try
                    {
                        selenium.Stop();
                    }
                    catch (Exception)
                    {
                        // Ignore errors if unable to close the browser
                    }
                    Assert.AreEqual("", verificationErrors.ToString());
                }
                
                [Test]
                public void TheNewTest()
                {
                    selenium.Open("/");
                    selenium.Type("q", "selenium rc");
                    selenium.Click("btnG");
                    selenium.WaitForPageToLoad("30000");
                    Assert.AreEqual("selenium rc - Google Search", selenium.GetTitle());
                }
            }
        }
```

#### Java

```java
      
	  /** Add JUnit framework to your classpath if not already there 
	   *  for this example to work
	  */
      package com.example.tests;

      import com.thoughtworks.selenium.*;
      import java.util.regex.Pattern;

      public class NewTest extends SeleneseTestCase {
          public void setUp() throws Exception {
              setUp("http://www.google.com/", "*firefox");
          }
            public void testNew() throws Exception {
                selenium.open("/");
                selenium.type("q", "selenium rc");
                selenium.click("btnG");
                selenium.waitForPageToLoad("30000");
                assertTrue(selenium.isTextPresent("Results * for selenium rc"));
          }
      }
```

#### Php

```php
      <?php

      require_once 'PHPUnit/Extensions/SeleniumTestCase.php';

      class Example extends PHPUnit_Extensions_SeleniumTestCase
      {
        function setUp()
        {
          $this->setBrowser("*firefox");
          $this->setBrowserUrl("http://www.google.com/");
        }

        function testMyTestCase()
        {
          $this->open("/");
          $this->type("q", "selenium rc");
          $this->click("btnG");
          $this->waitForPageToLoad("30000");
          $this->assertTrue($this->isTextPresent("Results * for selenium rc"));
        }
      }
      ?>
```

#### Python

```python

     from selenium import selenium
      import unittest, time, re

      class NewTest(unittest.TestCase):
          def setUp(self):
              self.verificationErrors = []
              self.selenium = selenium("localhost", 4444, "*firefox",
                      "http://www.google.com/")
              self.selenium.start()
         
          def test_new(self):
              sel = self.selenium
              sel.open("/")
              sel.type("q", "selenium rc")
              sel.click("btnG")
              sel.wait_for_page_to_load("30000")
              self.failUnless(sel.is_text_present("Results * for selenium rc"))
         
          def tearDown(self):
              self.selenium.stop()
              self.assertEqual([], self.verificationErrors)
```

#### Ruby

```ruby

      require "selenium/client"
      require "test/unit"

      class NewTest < Test::Unit::TestCase
        def setup
          @verification_errors = []
          if $selenium
            @selenium = $selenium
          else
            @selenium =  Selenium::Client::Driver.new("localhost", 4444, "*firefox", "http://www.google.com/", 60);
            @selenium.start
          end
          @selenium.set_context("test_new")
        end

        def teardown
          @selenium.stop unless $selenium
          assert_equal [], @verification_errors
        end

        def test_new
          @selenium.open "/"
          @selenium.type "q", "selenium rc"
          @selenium.click "btnG"
          @selenium.wait_for_page_to_load "30000"
          assert @selenium.is_text_present("Results * for selenium rc")
        end
      end
```

```java
    selenium = new DefaultSelenium("localhost", 4444, "*iehta", "http://www.google.com/");
```

O código gerado pela Selenium-IDE terá a seguinte aparência. Este exemplo tem comentários adicionados manualmente para maior clareza.

```java
   package com.example.tests;
   // We specify the package of our tests

   import com.thoughtworks.selenium.*;
   // This is the driver's import. You'll use this for instantiating a
   // browser and making it do what you need.

   import java.util.regex.Pattern;
   // Selenium-IDE add the Pattern module because it's sometimes used for 
   // regex validations. You can remove the module if it's not used in your 
   // script.

   public class NewTest extends SeleneseTestCase {
   // We create our Selenium test case

         public void setUp() throws Exception {
           setUp("http://www.google.com/", "*firefox");
                // We instantiate and start the browser
         }

         public void testNew() throws Exception {
              selenium.open("/");
              selenium.type("q", "selenium rc");
              selenium.click("btnG");
              selenium.waitForPageToLoad("30000");
              assertTrue(selenium.isTextPresent("Results * for selenium rc"));
              // These are the real test steps
        }
   }
```

### `C#`

O driver do cliente .NET funciona com o Microsoft.NET. Pode ser usado com qualquer framework de teste .NET como o NUnit ou o Visual Studio 2005 Team System.

Selenium-IDE assume que você usará NUnit como sua estrutura de teste. Você pode ver isso no código gerado abaixo. Inclui a declaração *using* para NUnit junto com os atributos NUnit correspondentes que identificam o papel de cada função-membro da classe de teste.

Você provavelmente terá que renomear a classe de teste de “NewTest” para algo de sua própria escolha. Além disso, você precisará alterar os parâmetros abertos pelo navegador na declaração

```csharp
    selenium = new DefaultSelenium("localhost", 4444, "*iehta", "http://www.google.com/");
```

O código gerado será semelhante a este.

```csharp

    using System;
    using System.Text;
    using System.Text.RegularExpressions;
    using System.Threading;
    using NUnit.Framework;
    using Selenium;
    
    namespace SeleniumTests

    {
        [TestFixture]

        public class NewTest

        {
        private ISelenium selenium;

        private StringBuilder verificationErrors;

        [SetUp]

        public void SetupTest()

        {
            selenium = new DefaultSelenium("localhost", 4444, "*iehta",
            "http://www.google.com/");

            selenium.Start();

            verificationErrors = new StringBuilder();
        }

        [TearDown]

        public void TeardownTest()
        {
            try
            {
            selenium.Stop();
            }

            catch (Exception)
            {
            // Ignore errors if unable to close the browser
            }

            Assert.AreEqual("", verificationErrors.ToString());
        }
        [Test]

        public void TheNewTest()
        {
            // Open Google search engine.        
            selenium.Open("http://www.google.com/"); 
            
            // Assert Title of page.
            Assert.AreEqual("Google", selenium.GetTitle());
            
            // Provide search term as "Selenium OpenQA"
            selenium.Type("q", "Selenium OpenQA");
            
            // Read the keyed search term and assert it.
            Assert.AreEqual("Selenium OpenQA", selenium.GetValue("q"));
            
            // Click on Search button.
            selenium.Click("btnG");
            
            // Wait for page to load.
            selenium.WaitForPageToLoad("5000");
            
            // Assert that "www.openqa.org" is available in search results.
            Assert.IsTrue(selenium.IsTextPresent("www.openqa.org"));
            
            // Assert that page title is - "Selenium OpenQA - Google Search"
            Assert.AreEqual("Selenium OpenQA - Google Search", 
                         selenium.GetTitle());
        }
        }
    }
```

Você pode permitir que o NUnit gerencie a execução de seus testes. Ou, alternativamente, você pode escrever um programa `main()` simples que instancia o objeto de teste e executa cada um dos três métodos, `SetupTest()`, `TheNewTest()` e `TeardownTest()` por sua vez.

### Python

Pyunit é a estrutura de teste a ser usada para Python.

A estrutura básica do teste é:

```python

   from selenium import selenium
   # This is the driver's import.  You'll use this class for instantiating a
   # browser and making it do what you need.

   import unittest, time, re
   # This are the basic imports added by Selenium-IDE by default.
   # You can remove the modules if they are not used in your script.

   class NewTest(unittest.TestCase):
   # We create our unittest test case

       def setUp(self):
           self.verificationErrors = []
           # This is an empty array where we will store any verification errors
           # we find in our tests

           self.selenium = selenium("localhost", 4444, "*firefox",
                   "http://www.google.com/")
           self.selenium.start()
           # We instantiate and start the browser

       def test_new(self):
           # This is the test code.  Here you should put the actions you need
           # the browser to do during your test.
            
           sel = self.selenium
           # We assign the browser to the variable "sel" (just to save us from 
           # typing "self.selenium" each time we want to call the browser).
            
           sel.open("/")
           sel.type("q", "selenium rc")
           sel.click("btnG")
           sel.wait_for_page_to_load("30000")
           self.failUnless(sel.is_text_present("Results * for selenium rc"))
           # These are the real test steps

       def tearDown(self):
           self.selenium.stop()
           # we close the browser (I'd recommend you to comment this line while
           # you are creating and debugging your tests)

           self.assertEqual([], self.verificationErrors)
           # And make the test fail if we found that any verification errors
           # were found
```

### Ruby

Versões antigas (pré 2.0) da Selenium-IDE geram código Ruby que requer o *gem* antigo do Selenium. Portanto, é aconselhável atualizar todos os scripts Ruby gerados pela IDE da seguinte forma:

1. Na linha 1, altere `require "selenium"` para `require "selenium/client"`

2. Na linha 11, altere `Selenium::SeleniumDriver.new` para `Selenium::Client::Driver.new`

Você provavelmente também deseja alterar o nome da classe para algo mais informativo do que “Untitled” e alterar o nome do método de teste para algo diferente de “test\_untitled.”

Aqui está um exemplo simples criado pela modificação do código Ruby gerado pela Selenium IDE, conforme descrito acima.

```ruby

   # load the Selenium-Client gem
   require "selenium/client"

   # Load Test::Unit, Ruby's default test framework.
   # If you prefer RSpec, see the examples in the Selenium-Client
   # documentation.
   require "test/unit"

   class Untitled < Test::Unit::TestCase

     # The setup method is called before each test.
     def setup

       # This array is used to capture errors and display them at the
       # end of the test run.
       @verification_errors = []

       # Create a new instance of the Selenium-Client driver.
       @selenium = Selenium::Client::Driver.new \
         :host => "localhost",
         :port => 4444,
         :browser => "*chrome",
         :url => "http://www.google.com/",
         :timeout_in_second => 60

       # Start the browser session
       @selenium.start

       # Print a message in the browser-side log and status bar
       # (optional).
       @selenium.set_context("test_untitled")

     end

     # The teardown method is called after each test.
     def teardown

       # Stop the browser session.
       @selenium.stop

       # Print the array of error messages, if any.
       assert_equal [], @verification_errors
     end

     # This is the main body of your test.
     def test_untitled
     
       # Open the root of the site we specified when we created the
       # new driver instance, above.
       @selenium.open "/"

       # Type 'selenium rc' into the field named 'q'
       @selenium.type "q", "selenium rc"

       # Click the button named "btnG"
       @selenium.click "btnG"

       # Wait for the search results page to load.
       # Note that we don't need to set a timeout here, because that
       # was specified when we created the new driver instance, above.
       @selenium.wait_for_page_to_load

       begin

          # Test whether the search results contain the expected text.
	  # Notice that the star (*) is a wildcard that matches any
	  # number of characters.
	  assert @selenium.is_text_present("Results * for selenium rc")
	  
       rescue Test::Unit::AssertionFailedError
       
          # If the assertion fails, push it onto the array of errors.
	  @verification_errors << $!

       end
     end
   end
```

### Perl, PHP

Os membros da equipe de documentação não usaram Selenium RC com Perl ou PHP. Se você estiver usando Selenium RC com qualquer um desses dois idiomas, entre em contato com a Equipe de Documentação (consulte o capítulo sobre Contribuições). Gostaríamos muito de incluir alguns exemplos seus e de suas experiências, para oferecer suporte a usuários Perl e PHP.

## Aprendendo a API

A API Selenium RC usa convenções de nomenclatura que, supondo que você entenda Selenese, será em grande parte autoexplicativo. Aqui, no entanto, explicamos os aspectos mais críticos e possivelmente menos óbvios.

### Iniciando o navegador

#### CSharp

```csharp
      selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.google.com/");
      selenium.Start();
```

#### Java

```java

      setUp("http://www.google.com/", "*firefox");
```

#### Perl

```perl
      my $sel = Test::WWW::Selenium->new( host => "localhost", 
                                          port => 4444, 
                                          browser => "*firefox", 
                                          browser_url => "http://www.google.com/" );
```

#### Php

```php
      $this->setBrowser("*firefox");
      $this->setBrowserUrl("http://www.google.com/");
```

#### Python

```python
      self.selenium = selenium("localhost", 4444, "*firefox",
                               "http://www.google.com/")
      self.selenium.start()
```

#### Ruby

```ruby
      @selenium = Selenium::ClientDriver.new("localhost", 4444, "*firefox", "http://www.google.com/", 10000);
      @selenium.start
```

```
    selenium.type("field-id", "string to type")
```

|                   |                              |               |
| ----------------- | ---------------------------- | ------------- |
| open              | /                            |               |
| type              | q                            | selenium rc   |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium rc   |               |
| type              | q                            | selenium ide  |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium ide  |               |
| type              | q                            | selenium grid |
| clickAndWait      | btnG                         |               |
| assertTextPresent | Results \* for selenium grid |               |

O código foi repetido para executar as mesmas etapas 3 vezes. Mas ter múltiplas cópias do mesmo código não é uma boa prática de programação porque é mais trabalhoso para manter. Usando uma linguagem de programação, podemos iterar sobre os resultados da pesquisa para uma solução mais flexível e sustentável.

#### In `C#`

```csharp
   // Collection of String values.
   String[] arr = {"ide", "rc", "grid"};    
        
   // Execute loop for each String in array 'arr'.
   foreach (String s in arr) {
       sel.open("/");
       sel.type("q", "selenium " +s);
       sel.click("btnG");
       sel.waitForPageToLoad("30000");
       assertTrue("Expected text: " +s+ " is missing on page."
       , sel.isTextPresent("Results * for selenium " + s));
    }
```

### Declarações de condição

Para ilustrar o uso de condições em testes, começaremos com um exemplo. Um problema comum encontrado durante a execução de testes Selenium ocorre quando o elemento esperado não está disponível na página. Por exemplo, ao executar a seguinte linha:

```
   selenium.type("q", "selenium " +s);
```

Se o elemento ‘q’ não estiver na página, então uma exceção é lançada:

```java
   com.thoughtworks.selenium.SeleniumException: ERROR: Element q not found
```

Isso pode fazer com que seu teste seja interrompido. Para alguns testes, é isso que você deseja. Mas frequentemente isso não é desejável, pois seu script de teste tem muitos outros testes subsequentes para realizar.

Uma abordagem melhor é primeiro validar se o elemento está realmente presente e então escolher alternativas quando não estiver. Vejamos isso usando Java.

```java
   // If element is available on page then perform type operation.
   if(selenium.isElementPresent("q")) {
       selenium.type("q", "Selenium rc");
   } else {
       System.out.printf("Element: " +q+ " is not available on page.")
   }
```

A vantagem desta abordagem é continuar com a execução do teste, mesmo se alguns elementos de IU não estão disponíveis na página.

### Executando JavaScript a partir do seu teste

JavaScript é muito útil para exercitar uma aplicação que não é diretamente suportada por Selenium. O método **getEval** da API Selenium pode ser usado para executar JavaScript a partir de Selenium RC.

Considere um aplicativo com caixas de seleção sem identificadores estáticos. Neste caso, pode-se avaliar o JavaScript do Selenium RC para obter ids de todas caixas de seleção e, em seguida, exercitá-las.

```java
   public static String[] getAllCheckboxIds () { 
		String script = "var inputId  = new Array();";// Create array in java script.
		script += "var cnt = 0;"; // Counter for check box ids.  
		script += "var inputFields  = new Array();"; // Create array in java script.
		script += "inputFields = window.document.getElementsByTagName('input');"; // Collect input elements.
		script += "for(var i=0; i<inputFields.length; i++) {"; // Loop through the collected elements.
		script += "if(inputFields[i].id !=null " +
		"&& inputFields[i].id !='undefined' " +
		"&& inputFields[i].getAttribute('type') == 'checkbox') {"; // If input field is of type check box and input id is not null.
		script += "inputId[cnt]=inputFields[i].id ;" + // Save check box id to inputId array.
		"cnt++;" + // increment the counter.
		"}" + // end of if.
		"}"; // end of for.
		script += "inputId.toString();" ;// Convert array in to string.			
		String[] checkboxIds = selenium.getEval(script).split(","); // Split the string.
		return checkboxIds;
    }
```

Para contar as imagens em uma página

```java
   selenium.getEval("window.document.images.length;");
```

Lembre-se de usar o objeto window no caso de expressões DOM já que por padrão a janela Selenium é referida, não a janela de teste.

## Opções do servidor

Quando o servidor é iniciado, as opções de linha de comando podem ser usadas para alterar o comportamento padrão do servidor.

Lembre-se de que o servidor é iniciado executando o seguinte.

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar
```

Para ver a lista de opções, execute o servidor com a opção `-h`.

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar -h
```

Você verá uma lista de todas as opções que pode usar com o servidor e uma breve descrição de cada. As descrições fornecidas nem sempre serão suficientes, então fornecemos explicações para algumas das opções mais importantes.

### Configuração do Proxy

Se o seu aplicação estiver atrás de um proxy HTTP que requer autenticação, você deve configurar http.proxyHost, http.proxyPort, http.proxyUser e http.proxyPassword usando o seguinte comando.

```bash
   $ java -jar selenium-server-standalone-<version-number>.jar -Dhttp.proxyHost=proxy.com -Dhttp.proxyPort=8080 -Dhttp.proxyUser=username -Dhttp.proxyPassword=password
```

### Modo multi-janela

Se você estiver usando Selenium 1.0, você provavelmente pode pular esta seção, uma vez que o modo multijanela é o comportamento padrão. No entanto, antes da versão 1.0, o Selenium executava por padrão o aplicativo em teste em um subquadro, conforme mostrado aqui.

Alguns aplicativos não funcionavam corretamente em um subquadro e precisavam ser carregados no quadro superior da janela. A opção de modo multi-janela permitida a aplicação testada ser executada em uma janela separada, em vez do quadro padrão onde poderia então ter o quadro superior necessário.

Para versões mais antigas do Selenium você deve especificar o modo multijanela explicitamente com a seguinte opção:

```bash
   -multiwindow 
```

A partir do Selenium RC 1.0, se você deseja executar seu teste dentro de um quadro único (ou seja, usando o padrão para versões anteriores do Selenium) você pode declarar isso ao servidor Selenium usando a opção

```bash
   -singlewindow 
```

### Especificando o perfil do Firefox

O Firefox não executará duas instâncias simultaneamente, a menos que você especifique um perfil separado para cada instância. Selenium RC 1.0 e posterior é executado em um perfil separado automaticamente, então se você estiver usando Selenium 1.0, você pode provavelmente pular esta seção. No entanto, se você estiver usando uma versão mais antiga do Selenium ou se você precisar usar um perfil específico para seus testes (como adicionar um certificado https ou ter alguns complementos instalados), você precisa especificar explicitamente o perfil.

Primeiro, para criar um perfil separado do Firefox, siga este procedimento. Abra o menu Iniciar do Windows, selecione “Executar”, digite e entre um dos seguintes:

```bash
   firefox.exe -profilemanager 
```

```bash
   firefox.exe -P 
```

Crie o novo perfil usando a caixa de diálogo. Então, quando você executar o Selenium Server, diga a ele para usar este novo perfil do Firefox com a opção de linha de comando do servidor *-firefoxProfileTemplate* e especifique o caminho para o perfil usando seu nome de arquivo e o caminho do diretório.

```bash
   -firefoxProfileTemplate "path to the profile" 
```

**Aviso**: certifique-se de colocar seu perfil em uma nova pasta separada da padrão!!! A ferramenta gerenciadora de perfil do Firefox irá deletar todos os arquivos em uma pasta se você excluir um perfil, independentemente de serem arquivos de perfil ou não.

Mais informações sobre os perfis do Firefox podem ser encontradas em [Mozilla’s Knowledge Base](http://support.mozilla.com/en/kb/Managing+profiles)

### Execute Selenese diretamente dentro do servidor usando -htmlSuite

Você pode executar arquivos Selenese html diretamente no servidor Selenium passando o arquivo html para a linha de comando do servidor. Por exemplo:

```bash
   java -jar selenium-server-standalone-<version-number>.jar -htmlSuite "*firefox" 
   "http://www.google.com" "c:\absolute\path\to\my\HTMLSuite.html" 
   "c:\absolute\path\to\my\results.html"
```

Isso iniciará automaticamente seu pacote HTML, executará todos os testes e salvará um bom relatório HTML com os resultados.

*Nota:* ao usar esta opção, o servidor irá iniciar os testes e aguardar um número especificado de segundos para o teste ser concluído; se o teste não completar dentro desse período de tempo, o comando sairá com um código de saída diferente de zero e nenhum arquivo de resultados será gerado.

Esta linha de comando é muito longa, então tome cuidado com o que você digita. Observe que isso requer que você passe uma suíte de arquivos HTML Selenese, não um único teste. Também esteja ciente de que a opção -htmlSuite é incompatível com `-interactive`. Você não pode executar os dois ao mesmo tempo.

### Logging do servidor Selenium

#### logs do lado do servidor

Ao iniciar o servidor Selenium, a opção **-log** pode ser usada para gravar informações valiosas de depuração relatadas pelo servidor Selenium em um arquivo de texto.

```bash
   java -jar selenium-server-standalone-<version-number>.jar -log selenium.log
```

Este arquivo de log é mais detalhado do que os logs do console padrão (inclui mensagens de registro de nível DEBUG ). O arquivo de log também inclui o nome do registrador e o número do thread que registrou a mensagem. Por exemplo:

```bash
   20:44:25 DEBUG [12] org.openqa.selenium.server.SeleniumDriverResourceHandler - 
   Browser 465828/:top frame1 posted START NEW
```

O formato da mensagem é

```bash
   TIMESTAMP(HH:mm:ss) LEVEL [THREAD] LOGGER - MESSAGE
```

Esta mensagens pode ter múltiplas linhas.

#### Logs do lado do navegador

O JavaScript no lado do navegador (Selenium Core) também registra mensagens importantes; em muitos casos, eles podem ser mais úteis para o usuário final do que os Logs normais do servidor. Para acessar os registros do lado do navegador, passe o argumento **-browserSideLog** para o servidor Selenium.

```bash
   java -jar selenium-server-standalone-<version-number>.jar -browserSideLog
```

**-browserSideLog** deve ser combinado com o argumento **-log**, para registrar browserSideLogs (bem como todas as outras mensagens de log de nível DEBUG) em um arquivo.

## Especificando o caminho para um navegador específico

Você pode especificar para o Selenium RC o caminho para um navegador. Isto é útil se você possui diferentes versões do mesmo navegador e você deseja usar uma em específico. Isto também pode ser usado para executar seus testes em um navegador que não é suportado diretamente pelo Selenium RC. Quando especificar o modo de execução, use o especificador \*custom seguido do caminho completo para o executável do navegador.

```bash
   *custom <path to browser> 
```

```bash
   cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\MyBrowser.exe&2=http://www.google.com
```

### Executando testes com diferentes configurações de navegador

Normalmente o Selenium RC configura automaticamente o navegador, mas se você iniciar o navegador usando o modo de execução “\*custom”, você pode forçar o Selenium RC a iniciar o navegador como está, sem usar uma configuração automática.

Por exemplo, você pode iniciar o Firefox com uma configuração personalizada como esta:

```bash
   cmd=getNewBrowserSession&1=*custom c:\Program Files\Mozilla Firefox\firefox.exe&2=http://www.google.com
```

Observe que ao iniciar o navegador desta forma, você deve manualmente configurar o navegador para usar o servidor Selenium como proxy. Normalmente, isso apenas significa abrir as preferências do navegador e especificar “localhost: 4444” como um proxy HTTP, mas as instruções para isso podem diferir radicalmente de navegador para navegador. Consulte a documentação do seu navegador para obter detalhes.

Esteja ciente de que os navegadores Mozilla podem variar em como eles iniciam e param. Pode ser necessário definir a variável de ambiente MOZ\_NO\_REMOTE para fazer com que os navegadores Mozilla se comportem de maneira mais previsível. Os usuários Unix devem evitar iniciar o navegador usando um script de shell; geralmente é melhor usar o executável binário (por exemplo, firefox-bin) diretamente.

## Resolução de problemas comuns

Ao começar a usar o Selenium RC, há alguns problemas potenciais que são comumente encontrados. Nós os apresentamos junto com suas soluções aqui.

### Incapaz de conectar ao servidor

Quando seu programa de teste não pode se conectar ao servidor Selenium, o Selenium lança uma exceção em seu programa de teste. Ele deve exibir esta mensagem ou outra semelhante:

```bash
    "Unable to connect to remote server (Inner Exception Message: 
	No connection could be made because the target machine actively 
	refused it )"
    
	(using .NET and XP Service Pack 2) 
```

Se você vir uma mensagem como esta, certifique-se de iniciar o servidor Selenium. E se então, há um problema com a conectividade entre a biblioteca cliente Selenium e o servidor Selenium.

Ao começar com Selenium RC, a maioria das pessoas começa executando seu programa de teste (com uma biblioteca de cliente Selenium) e o servidor Selenium na mesma máquina. Para fazer isso use “localhost” como parâmetro de conexão. Recomendamos começar dessa forma, pois reduz a influência de possíveis problemas de rede que você está começando. Supondo que seu sistema operacional tenha uma rede típica e configurações TCP/IP, você deve ter pouca dificuldade. Na verdade, muitas pessoas optam por executar os testes desta forma.

Se, no entanto, você deseja executar o Selenium Server em uma máquina remota, a conectividade deve ser boa, supondo que você tenha uma conexão TCP/IP válida entre as duas máquinas.

Se tiver dificuldade para se conectar, você pode usar ferramentas de rede comuns como *ping*, *telnet*, *ifconfig (Unix) / ipconfig* (Windows), etc para garantir que você tenha uma conexão de rede. Se não estiver familiarizado com eles, o administrador do sistema pode ajudá-lo.

### Incapaz de carregar o navegador

Ok, não é uma mensagem de erro amigável, desculpe, mas se o servidor Selenium não pode carregar o navegador você provavelmente verá este erro.

```bash
    (500) Internal Server Error
```

```bash
    Error:  java.lang.RuntimeException: Firefox refused shutdown while 
    preparing a profile 
```

Esta é a mensagem de erro completa do servidor:

```bash
    16:20:03.919 INFO - Preparing Firefox profile... 
    16:20:27.822 WARN - GET /selenium-server/driver/?cmd=getNewBrowserSession&1=*fir 
    efox&2=http%3a%2f%2fsage-webapp1.qa.idc.com HTTP/1.1 
    java.lang.RuntimeException: Firefox refused shutdown while preparing a profile 
            at org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLaunc 
    her.waitForFullProfileToBeCreated(FirefoxCustomProfileLauncher.java:277) 
    ... 
    Caused by: org.openqa.selenium.server.browserlaunchers.FirefoxCustomProfileLaunc 
    her$FileLockRemainedException: Lock file still present! C:\DOCUME~1\jsvec\LOCALS 
    ~1\Temp\customProfileDir203138\parent.lock 
```

Para resolver isso, consulte a seção Especificando um perfil separado do Firefox

### Problemas de versionamento

Certifique-se de que sua versão do Selenium é compatível com a versão do seu navegador. Por exemplo, Selenium RC 0.92 não suporta Firefox 3. Às vezes você pode ter sorte (eu tive). Mas não se esqueça de verificar quais versões do navegador são compatíveis com a versão do Selenium que você está usando. Quando em dúvida, use a versão mais recente do Selenium com a versão mais usada do seu navegador.

### Mensagem de erro: “(Unsupported major.minor version 49.0)” ao inicializar o servidor

Este erro diz que você não está usando uma versão correta do Java. O Selenium Server requer Java 1.5 ou superior.

Para verificar novamente sua versão java, execute na linha de comando:

```bash
   java -version
```

Você deve ver uma mensagem mostrando a versão do Java.

```bash
   java version "1.5.0_07"
   Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03)
   Java HotSpot(TM) Client VM (build 1.5.0_07-b03, mixed mode)
```

```bash
   cmd=getNewBrowserSession&1=*firefox /usr/local/firefox/firefox-bin&2=http://www.google.com
```

```bash
   /usr/lib/firefox-x.x.x/ 
```

Onde x.x.x é o número da versão que você possui atualmente. Então, para adicionar esse caminho no *path* do usuário. você terá que adicionar o seguinte ao seu arquivo .bashrc:

```bash
   export PATH="$PATH:/usr/lib/firefox-x.x.x/"
```

Se necessário, você pode especificar o caminho para o firefox-bin diretamente em seu teste, assim:

```bash
   "*firefox /usr/lib/firefox-x.x.x/firefox-bin"
```

### IE e atributos de estilo

Se você estiver executando seus testes no Internet Explorer e não conseguir localizar elementos usando seu atributo `style`. Por exemplo:

```bash
    //td[@style="background-color:yellow"]
```

Isso funcionaria perfeitamente no Firefox, Opera ou Safari, mas não com o IE. O IE interpreta as chaves em `@style` como maiúsculas. Então, mesmo que o o código-fonte está em letras minúsculas, você deve usar:

```bash
    //td[@style="BACKGROUND-COLOR:yellow"]
```

Isso é um problema se o seu teste se destina a funcionar em vários navegadores, mas você pode facilmente codificar seu teste para detectar a situação e tentar o localizador alternativo que só funciona no IE.

### Erro encontrado - “Cannot convert object to primitive value” no delsigamento do navegador \*googlechrome

Para evitar esse erro, você deve iniciar o navegador com uma opção que desativa as verificações da política de mesma origem:

```bash
   selenium.start("commandLineFlags=--disable-web-security");
```

### Erro encontrado no IE - “Couldn’t open app window; is the pop-up blocker enabled?”

Para evitar esse erro, você deve configurar o navegador: desative o bloqueador de pop-ups e desmarque a opção ‘Ativar modo protegido’ em Ferramentas » Opções » Segurança.

***

1. O proxy é uma terceira pessoa no meio que passa a bola entre as duas partes. Ele atua como um “servidor da web” que entrega a aplicação ao navegador. Ser um proxy dá ao Selenium Server a capacidade de “mentir” sobre a URL real da aplicação. [↩︎](#fnref:1)

2. O navegador é iniciado com um perfil de configuração que definiu localhost:4444 como o proxy HTTP, é por isso que qualquer solicitação HTTP que o navegador fizer passará pelo servidor Selenium e a resposta passará por ele e não pelo servidor real. [↩︎](#fnref:2)

# 2 - Selenium 2

Selenium 2 was a rewrite of Selenium 1 that was implemented with WebDriver code.

# 2.1 - Migrando do RC para WebDriver

```java
Selenium selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.yoursite.com");
selenium.start();
```

Isso deve ser substituído assim:

```java
WebDriver driver = new FirefoxDriver();
Selenium selenium = new WebDriverBackedSelenium(driver, "http://www.yoursite.com");
```

## Próximos passos

Depois que seus testes forem executados sem erros, a próxima etapa é migrar o código de teste real para usar as APIs WebDriver. Dependendo de quão bem você abstrair o seu código, pode ser um processo curto ou longo. Em ambos os casos, a abordagem é a mesma e pode ser resumida simplesmente: modifique o código para usar a nova API quando for editá-lo.

Se você precisar extrair a implementação WebDriver subjacente da instância Selenium, você pode simplesmente fazer um cast para WrapsDriver:

```java
WebDriver driver = ((WrapsDriver) selenium).getWrappedDriver();
```

Isso permite que você continue passando a instância Selenium como normal, mas desembrulhar a instância do WebDriver conforme necessário.

Em algum ponto, sua base de código usará principalmente as APIs mais recentes. Neste ponto, você pode inverter o relacionamento, usando WebDriver em tudo e instanciar uma instância do Selenium sob demanda:

```java
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);
```

## Problemas comuns

Felizmente, você não é a primeira pessoa a passar por essa migração, então, aqui estão alguns problemas comuns que outras pessoas viram e como resolvê-los.

### Clicar e digitar são mais completos

Um padrão comum em um teste de Selenium RC é ver algo como:

```java
selenium.type("name", "exciting tex");
selenium.keyDown("name", "t");
selenium.keyPress("name", "t");
selenium.keyUp("name", "t");
```

```java
Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(30));
WebElement element= wait.until(visibilityOfElementLocated(By.id("some_id")));
```

Onde “visibilityOfElementLocated” é implementado como:

```java
public ExpectedCondition<WebElement> visibilityOfElementLocated(final By locator) {
  return new ExpectedCondition<WebElement>() {
    public WebElement apply(WebDriver driver) {
      WebElement toReturn = driver.findElement(locator);
      if (toReturn.isDisplayed()) {
        return toReturn;
      }
      return null;
    }
  };
}
```

Isso pode parecer complexo, mas é quase todo um código padrão. O único interessante é que a “condição esperada” será avaliada repetidamente até que o método “apply” retorne algo que não seja “null” nem Boolean.FALSE.

Claro, adicionar todas essas chamadas de “wait” pode confundir seu código. E se esse é o caso, e suas necessidades são simples, considere usar as esperas implícitas:

```java
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
```

```java
String name = selenium.getEval(
    "selenium.browserbot.findElement('id=foo', browserbot.getCurrentWindow()).tagName");
```

se torna:

```java
WebElement element = driver.findElement(By.id("foo"));
String name = (String) ((JavascriptExecutor) driver).executeScript(
    "return arguments[0].tagName", element);
```

Observe como a variável “element” passada aparece como o primeiro item na array de “arguments” padrão do JS.

### A execução de Javascript não retorna nada

O JavascriptExecutor do WebDriver envolverá todo o JS e o avaliará como uma expressão anônima. Isso significa que você precisa usar a palavra-chave “return”:

```java
String title = selenium.getEval("browserbot.getCurrentWindow().document.title");
```

se torna:

```java
((JavascriptExecutor) driver).executeScript("return document.title;");
```

# 2.2 - Servidor do WebDriver remoto

O servidor sempre será executado na máquina com o navegador que você deseja testar. O servidor pode ser usado a partir da linha de comando ou por meio de configuração de código.

## Iniciando o servidor a partir da linha de comando

Depois de fazer o download do `selenium-server-standalone-{VERSION}.jar`, coloque-o no computador com o navegador que deseja testar. Então, a partir do diretório com o jar, execute o seguinte:

```shell
java -jar selenium-server-standalone-{VERSION}.jar
```

## Considerações para executar o servidor

O chamador deve encerrar cada sessão adequadamente, chamando ou `Selenium#stop()` ou `WebDriver#quit`.

O selenium-server mantém registros na memória para cada sessão em andamento, que são apagados quando `Selenium#stop()` ou `WebDriver#quit` é chamado. E se você se esquecer de encerrar essas sessões, seu servidor pode vazar memória. E se você mantém sessões de duração extremamente longa, você provavelmente precisará parar / sair de vez em quando (ou aumentar a memória com a opção -Xmx jvm).

## Timeouts (a partir da versão 2.21)

O servidor tem dois timeouts diferentes, que podem ser definidos da seguinte forma:

```shell
java -jar selenium-server-standalone-{VERSION}.jar -timeout=20 -browserTimeout=60
```

```java
import org.mortbay.jetty.Connector;
import org.mortbay.jetty.Server;
import org.mortbay.jetty.nio.SelectChannelConnector;
import org.mortbay.jetty.security.SslSocketConnector;
import org.mortbay.jetty.webapp.WebAppContext;

import javax.servlet.Servlet;
import java.io.File;

import org.openqa.selenium.remote.server.DriverServlet;

public class AppServer {
  private Server server = new Server();

  public AppServer() throws Exception {
    WebAppContext context = new WebAppContext();
    context.setContextPath("");
    context.setWar(new File("."));
    server.addHandler(context);

    context.addServlet(DriverServlet.class, "/wd/*");

    SelectChannelConnector connector = new SelectChannelConnector();
    connector.setPort(3001);
    server.addConnector(connector);

    server.start();
  }
}
```

# 3 - Selenium 3

Selenium 3 was the implementation of WebDriver without the Selenium RC Code. It has since been replaced with Selenium 4, which implements the W3C WebDriver specification.

# 3.1 - Grid 3

Selenium Grid 3 supported WebDriver without Selenium RC code. Grid 3 was completely rewritten for the new Grid 4.

[Grid 4](https://www.selenium.dev/pt-br/documentation/grid/)

*Selenium Grid* é um servidor proxy inteligente que permite que os testes Selenium encaminhem comandos para instâncias remotas do navegador da web. Seu objetivo é fornecer uma maneira fácil de executar testes em paralelo em várias máquinas.

Com Selenium Grid, um servidor atua como o hub que roteia comandos de teste formatados em JSON para um ou mais nós registrados. Os testes entram em contato com o hub para obter acesso a instâncias remotas do navegador. O hub tem uma lista de servidores registrados aos quais fornece acesso, e permite o controle dessas instâncias.

Selenium Grid nos permite executar testes em paralelo em várias máquinas, e gerenciar diferentes versões e configurações do navegador centralmente (em vez de em cada teste individual).

Selenium Grid não é uma bala de prata. Ele resolve um subconjunto de problemas comuns de delegação e distribuição, mas não irá, por exemplo, gerenciar sua infraestrutura, e pode não atender às suas necessidades específicas.

# 3.2 - Configurando a sua

```shell
java -jar selenium-server-standalone.jar -role hub
```

The Hub will listen to port 4444 by default. You can view the status of the hub by opening a browser window and navigating to <http://localhost:4444/grid/console>.

Para alterar a porta padrão, você pode adicionar a flag opcional `-port` com um número inteiro representando a porta a ser ouvida quando você executa o comando. Além disso, todas as outras opções que você vê no arquivo de configuração JSON (veja abaixo) são possíveis flags de linha de comando.

Você certamente pode sobreviver apenas com o comando simples mostrado acima, mas se você precisar de uma configuração mais avançada, você também pode especificar um arquivo de configuração de formato JSON, por conveniência, para configurar o hub ao iniciá-lo. Você pode fazer assim:

```shell
java -jar selenium-server-standalone.jar -role hub -hubConfig hubConfig.json -debug
```

Abaixo você verá um exemplo de um arquivo `hubConfig.json`. Entraremos em mais detalhes sobre como fornecer arquivos de configuração de nó no Passo 2.

```json
{
  "_comment" : "Configuration for Hub - hubConfig.json",
  "host": ip,
  "maxSession": 5,
  "port": 4444,
  "cleanupCycle": 5000,
  "timeout": 300000,
  "newSessionWaitTimeout": -1,
  "servlets": [],
  "prioritizer": null,
  "capabilityMatcher": "org.openqa.grid.internal.utils.DefaultCapabilityMatcher",
  "throwOnCapabilityNotPresent": true,
  "nodePolling": 180000,
  "platform": "WINDOWS"}
```

### Pasos 2: Inicialize os Nós

Independentemente de você querer executar uma Grid com a nova funcionalidade WebDriver, ou uma Grid com funcionalidade Selenium 1 RC, ou os dois ao mesmo tempo, você usa o mesmo arquivo `selenium-server-standalone.jar` para iniciar os nós:

```shell
java -jar selenium-server-standalone.jar -role node -hub http://localhost:4444
```

```shell
java -Dwebdriver.chrome.driver=chromedriver.exe -jar selenium-server-standalone.jar -role node -nodeConfig node1Config.json
```

E aqui está um exemplo do arquivo `nodeConfig.json`:

```json
{
  "capabilities": [
    {
      "browserName": "firefox",
      "acceptSslCerts": true,
      "javascriptEnabled": true,
      "takesScreenshot": false,
      "firefox_profile": "",
      "browser-version": "27",
      "platform": "WINDOWS",
      "maxInstances": 5,
      "firefox_binary": "",
      "cleanSession": true
    },
    {
      "browserName": "chrome",
      "maxInstances": 5,
      "platform": "WINDOWS",
      "webdriver.chrome.driver": "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe"
    },
    {
      "browserName": "internet explorer",
      "maxInstances": 1,
      "platform": "WINDOWS",
      "webdriver.ie.driver": "C:/Program Files (x86)/Internet Explorer/iexplore.exe"
    }
  ],
  "configuration": {
    "_comment" : "Configuration for Node",
    "cleanUpCycle": 2000,
    "timeout": 30000,
    "proxy": "org.openqa.grid.selenium.proxy.WebDriverRemoteProxy",
    "port": 5555,
    "host": ip,
    "register": true,
    "hubPort": 4444,
    "maxSession": 5
  }
}
```

```shell
java -jar selenium-server-standalone.jar -role hub -log log.txt
```

Use o seu editor de texto favorito para abrir o arquivo de log (log.txt no exemplo acima) para encontrar registros de “ERROR” se você tiver problemas.

### Usando o argumento `-debug`

Você também pode usar o argumento `-debug` para imprimir logs de depuração no console. Inicie o Selenium Grid Hub ou Node com o argumento `-debug`. Por favor, veja o exemplo abaixo:

```shell
java -jar selenium-server-standalone.jar -role hub -debug
```

# 3.3 - Componentes


# 4 - Selenium IDE Legado

```html
<tr>
    <td>Command</td>
    <td>target (locator)</td>
    <td>Value</td>
</tr>
```

|            |              |       |
| ---------- | ------------ | ----- |
| verifyText | //div//a\[2] | Login |

Os parâmetros nem sempre são necessários, depende do comando. Em alguns casos ambos são necessários, em outros um parâmetro é necessário, e ainda em outros, o comando pode não ter nenhum parâmetro. Aqui estão mais alguns exemplos:

|                   |             |                         |
| ----------------- | ----------- | ----------------------- |
| goBackAndWait     |             |                         |
| verifyTextPresent |             | Welcome to My Home Page |
| type              | id=phone    | (555) 666-7066          |
| type              | id=address1 | ${myVariableAddress}    |

```html
<table>
    <tr><td>open</td><td>/download/</td><td></td></tr>
    <tr><td>assertTitle</td><td></td><td>Downloads</td></tr>
    <tr><td>verifyText</td><td>//h2</td><td>Downloads</td></tr>
</table>
```

Renderizado como uma tabela em um navegador, seria assim:

|             |            |           |
| ----------- | ---------- | --------- |
| open        | /download/ |           |
| assertTitle |            | Downloads |
| verifyText  | //h2       | Downloads |

A sintaxe HTML Selenese pode ser usada para escrever e executar testes sem exigir conhecimento de uma linguagem de programação. Com um conhecimento básico de Selenese e Selenium-IDE você pode produzir e executar casos de teste rapidamente.

## Suítes de Teste

Uma suíte de testes é uma coleção de testes. Frequentemente, você executará todos os testes em uma suite de teste como um trabalho em lote contínuo.

Ao usar a Selenium-IDE, as suítes de testes também podem ser definidas usando um arquivo HTML simples. A sintaxe novamente é simples. Uma tabela HTML define uma lista de testes onde cada linha define o caminho do sistema de arquivos para cada teste. Um exemplo diz tudo.

```html
<html>
<head>
<title>Test Suite Function Tests - Priority 1</title>
</head>
<body>
<table>
  <tr><td><b>Suite Of Tests</b></td></tr>
  <tr><td><a href="./Login.html">Login</a></td></tr>
  <tr><td><a href="./SearchValues.html">Test Searching for Values</a></td></tr>
  <tr><td><a href="./SaveValues.html">Test Save</a></td></tr>
</table>
</body>
</html>
```

| Command     | Target     | Value        |
| ----------- | ---------- | ------------ |
| open        | /download/ |              |
| assertTitle |            | Downloads    |
| verifyText  | //h2       | Downloads    |
| assertTable | 1.2.1      | Selenium IDE |
| verifyTable | 1.2.2      | June 3, 2008 |
| verifyTable | 1.2.3      | 1.0 beta 2   |

O exemplo acima primeiro abre uma página e, em seguida, faz uma asserção para saber se a página correta é carregada comparando o título com o valor esperado. Só se passar, o seguinte comando será executado e verificará se o texto está presente na localização esperada. O caso de teste, então, faz uma asserção para saber se a primeira coluna na segunda linha da primeira tabela contém o valor esperado, e somente se este for aprovado as células restantes nessa linha serão “verificadas”.

### **verifyTextPresent**

O comando `verifyTextPresent` é usado para verificar se existe um texto específico em algum lugar na página. Leva um único argumento - o texto a ser verificado. Por exemplo:

| Command           | Target             | Value |
| ----------------- | ------------------ | ----- |
| verifyTextPresent | Marketing Analysis |       |

Isso faria com que o Selenium procurasse e verificasse que a string de texto “Marketing Analysis” aparece em algum lugar na página que está sendo testada. Use verifyTextPresent quando você está interessado apenas no próprio texto estar presente na página. Não use isso quando você também precisa testar onde o texto está na página.

### **verifyElementPresent**

Use este comando quando precisar testar a presença de um elemento de UI específico, em vez de seu conteúdo. Esta verificação não verifica o texto, apenas a tag HTML. Um uso comum é verificar a presença de uma imagem.

| Command              | Target      | Value |
| -------------------- | ----------- | ----- |
| verifyElementPresent | //div/p/img |       |

Este comando verifica se uma imagem, especificada pela existência de uma tag HTML `<img>`, está presente na página e aparece após uma tag `<div>` e uma tag `<p>`. O primeiro (e único) parâmetro é um localizador para informar o comando Selenese de como encontrar o elemento. Os localizadores são explicados na próxima seção.

`verifyElementPresent` pode ser usado para verificar a existência de qualquer tag HTML dentro da página. Você pode verificar a existência de links, parágrafos, divisões `<div>`, etc. Aqui estão mais alguns exemplos.

| Command              | Target                        | Value |
| -------------------- | ----------------------------- | ----- |
| verifyElementPresent | //div/p                       |       |
| verifyElementPresent | //div/a                       |       |
| verifyElementPresent | id=Login                      |       |
| verifyElementPresent | link=Go to Marketing Research |       |
| verifyElementPresent | //a\[2]                       |       |
| verifyElementPresent | //head/title                  |       |

Esses exemplos ilustram a variedade de maneiras pelas quais um elemento de UI pode ser testado. Novamente, os localizadores são explicados na próxima seção.

### **verifyText**

Use `verifyText` quando o texto e seu elemento de UI devem ser testados. verifyText deve usar um localizador. Se você escolher um localizador *XPath* ou *DOM*, você pode verificar se um texto específico aparece em um local específico na página em relação a outro componente na página.

| Command    | Target              | Value                                                               |
| ---------- | ------------------- | ------------------------------------------------------------------- |
| verifyText | //table/tr/td/div/p | This is my text and it occurs right after the div inside the table. |

## Localizando elementos

Para muitos comandos do Selenium, um alvo é necessário. Este alvo identifica um elemento no conteúdo do aplicativo da web, e consiste na estratégia de localização seguida pela localização no formato `locatorType = location`. O tipo de localizador pode ser omitido em muitos casos. Os vários tipos de localizadores são explicados abaixo com exemplos para cada um.

### Localizando pelo Identificador

Este é provavelmente o método mais comum de localização de elementos e é o padrão quando nenhum tipo de localizador reconhecido é usado. Com esta estratégia, o primeiro elemento com o valor do atributo id correspondente ao local será usado. E se nenhum elemento tem um atributo *id* correspondente, então o primeiro elemento com um atributo *name* correspondente ao local será usado.

Por exemplo, o código fonte da sua página pode ter atributos id e name do seguinte modo:

```html
  <html>
   <body>
    <form id="loginForm">
     <input name="username" type="text" />
     <input name="password" type="password" />
     <input name="continue" type="submit" value="Login" />
    </form>
   </body>
  <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
    </body>
   <html>
```

* `id=loginForm` (3)

### Localizando pelo *name*

O tipo Localizador de Nome irá localizar o primeiro elemento com um atributo *name* correspondente. Se vários elementos tiverem o mesmo valor para um atributo *name*, então você pode usar filtros para refinar ainda mais sua estratégia de localização. O tipo de filtro padrão é *value* (correspondendo ao atributo *value*).

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
  <html>
   <body>
    <p>Are you sure you want to do this?</p>
    <a href="continue.html">Continue</a> 
    <a href="cancel.html">Cancel</a>
  </body>
  <html>
```

* `link=Continue` (4)
* `link=Cancel` (5)

### Localizando pelo DOM

O Document Object Model representa um documento HTML e pode ser acessado usando JavaScript. Esta estratégia de localização usa um JavaScript que representa um elemento na página, que pode ser simplesmente a localização do elemento usando a notação hierárquica.

Uma vez que apenas os localizadores `dom` começam com “document”, não é necessário incluir o rótulo `dom=` ao especificar um localizador DOM.

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input class="required" name="username" type="text" />
      <input class="required passfield" name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | glob:\*Film\*Television\*             |       |

O título real da página acessada clicando no link era “De Anza Film And Television Department - Menu”. Usando um padrão em vez do texto exato, o `verifyTitle` vai passar enquanto as duas palavras “Film” e “Television” aparecerem (nessa ordem) em qualquer lugar no título da página. Por exemplo, se o proprietário da página encurtar o título apenas para “Film & Television Department”, o teste ainda seria aprovado. Usar um padrão para um link e um teste simples de que o link funcionou (como o `verifyTitle` acima faz) pode reduzir bastante a manutenção de tais casos de teste.

#### Padrão de Expressões Regulares

Os padrões de *expressão regular* são os mais poderosos dos três tipos de padrões que o Selenese suporta. Expressões regulares também são suportados pela maioria das linguagens de programação de alto nível, muitos editores de texto e uma série de ferramentas, incluindo utilitários **grep**, **sed** e **awk** da linha de comando Linux / Unix. Em Selenese, padrões de expressão regular permitem que um usuário execute muitas tarefas que iriam ser muito difíceis de outra forma. Por exemplo, suponha que seu teste precise garantir que uma determinada célula da tabela contivesse nada além de um número. `regexp:[0-9]+` é um padrão simples que corresponderá a um número decimal de qualquer comprimento.

Enquanto os padrões de Globbing do Selenese suportam apenas o **\*** e **\[ ]** (classe de caracteres), os padrões de expressão regular Selenese oferecem a mesma ampla gama de caracteres especiais que existem em JavaScript. Abaixo está um subconjunto desses caracteres especiais:

| PATTERN | MATCH                                                                     |
| ------- | ------------------------------------------------------------------------- |
| .       | qualquer caractere isolado                                                |
| \[ ]    | classe de caracteres: qualquer caractere definido dentros dos colchetes   |
| \*      | quantificação: 0 ou mais do caractere anterior (ou grupo)                 |
| +       | quantificação: 1 ou mais do caractere anterior (ou grupo)                 |
| ?       | quantificação: 0 ou 1 do caractere anterior (ou grupo)                    |
| {1,5}   | quantificação: 1 até 5 repetições do caractere anterior (ou grupo)        |
| \|      | alternação: o caractere/grupo na esquerda OU o caractere/grupo na direita |
| ( )     | agrupamento: normalmente usado com alternação e/ou quantificação          |

Os padrões de expressão regular em Selenese precisam ser prefixados com `regexp:` ou `regexpi:`. O primeiro é sensível a maiúsculas e minúsculas; o último não faz distinção entre maiúsculas e minúsculas.

Alguns exemplos ajudarão a esclarecer como os padrões de expressão regular podem ser usados com comandos Selenese. O primeiro usa o que é provavelmente o padrão de expressão regular mais comumente usado - **.\*** (“ponto estrela”). Esta sequência de dois caracteres pode ser traduzida como “0 ou mais ocorrências de qualquer caractere” ou, mais simplesmente, “qualquer coisa ou nada.” É o equivalente do padrão globbing de um caractere **\*** (um único asterisco).

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | regexp:.\*Film.\*Television.\*        |       |

O exemplo acima é funcionalmente equivalente ao exemplo anterior que usou padrões de globbing para este mesmo teste. As únicas diferenças são o prefixo (**regexp:** em vez de **glob:**) e o padrão “qualquer coisa ou nada” (**.\*** em vez de apenas **\***).

O exemplo mais complexo abaixo testa que a página de clima do Yahoo! para Anchorage, Alasca, contém informações sobre o horário do nascer do sol:

| Command           | Target                                            | Value |
| ----------------- | ------------------------------------------------- | ----- |
| open              | <http://weather.yahoo.com/forecast/USAK0012.html> |       |
| verifyTextPresent | regexp:Sunrise: \*\[0-9]{1,2}:\[0-9]{2} \[ap]m    |       |

Vamos examinar a expressão regular acima em partes:

|              |                                                         |
| ------------ | ------------------------------------------------------- |
| `Sunrise: *` | A string **Sunrise:** seguida por 0 ou mais espaços     |
| `[0-9]{1,2}` | 1 ou 2 dígitos (para a hora do dia)                     |
| `:`          | O caractere **:** (sem caracteres especiais envolvidos) |
| `[0-9]{2}`   | 2 dígitos (para os minutos) seguidos de um espaço       |
| `[ap]m`      | “a” ou “p” seguido por “m” (am ou pm)                   |

#### Padrão Exato

O tipo de padrão **exato** do Selenium é de utilidade marginal. Ele não usa nenhum caractere especial. Então, se você precisasse procurar um caractere de asterisco real (que é especial para globbing e padrões de expressão regular), o padrão **exato** seria uma maneira fazer isso. Por exemplo, se você quiser selecionar um item rotulado “Real\*” em uma lista suspensa, o código a seguir pode funcionar ou não. O asterisco no padrão `glob:Real*` irá corresponder a qualquer coisa ou a nada. Portanto, se houvesse uma opção de seleção anterior rotulada “Números reais”, ser a opção selecionada em vez da opção “Real\*”.

| Command | Target   | Value        |
| ------- | -------- | ------------ |
| select  | //select | glob:Real \* |

A fim de garantir que o item “Real\*” seja selecionado, o prefixo `exact:` pode ser usado para criar um padrão **exato** conforme mostrado abaixo:

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| select  | //select | exact:Real \* |

Mas o mesmo efeito pode ser alcançado escapando o asterisco em um padrão de expressão regular:

| Command | Target   | Value            |
| ------- | -------- | ---------------- |
| select  | //select | regexp:Real \\\* |

| Command | Target            | Value |
| ------- | ----------------- | ----- |
| store   | <paul@mysite.org> |       |

Posteriormente em seu script, você desejará usar o valor armazenado de sua variável. Para acessar o valor de uma variável, coloque a variável em colchetes ({}) e preceda-a com um cifrão como a seguir.

| Command    | Target  | Value         |
| ---------- | ------- | ------------- |
| verifyText | //div/p | \\${userName} |

Um uso comum de variáveis é armazenar a entrada para um campo input.

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| type    | id=login | \\${userName} |

| Command         | Target                                         | Value       |
| --------------- | ---------------------------------------------- | ----------- |
| store           | 10                                             | hits        |
| storeXpathCount | //blockquote                                   | blockquotes |
| storeEval       | storedVars\[‘hits’].storedVars\[‘blockquotes’] | paragraphs  |

Este próximo exemplo ilustra como um snippet de JavaScript pode incluir chamadas para métodos, neste caso, os métodos `toUpperCase` e `toLowerCase`do objeto JavaScript String.

| Command   | Target                            | Value |
| --------- | --------------------------------- | ----- |
| store     | Edith Wharton                     | name  |
| storeEval | storedVars\[’name’].toUpperCase() | uc    |
| storeEval | storedVars\[’name’].toUpperCase() | lc    |

#### Usando JavaScript com parâmetros não-script

JavaScript também pode ser usado para ajudar a gerar valores para parâmetros, mesmo quando o parâmetro não é especificado para ser do tipo **script**. No entanto, neste caso, uma sintaxe especial é necessária - o parâmetro *inteiro* deve ser prefixado por `javascript{` com um `}` final, que envolve o snippet JavaScript, como em `javascript{*yourCodeHere*}`. Abaixo está um exemplo em que o segundo parâmetro do comando `type`

* `value` - é gerado através do código JavaScript usando esta sintaxe especial:

| Command | Target            | Value                                                 |
| ------- | ----------------- | ----------------------------------------------------- |
| store   | league of nations | searchString                                          |
| type    | q                 | javascript{storedVars\[‘searchString’].toUpperCase()} |

## *echo* - O comando de print do Selenese

Selenese tem um comando simples que permite imprimir texto para a saída do seu teste. Isso é útil para fornecer notas de progresso informativas em seu teste que são exibidas no console durante a execução. Essas notas também podem ser usadas para fornecer contexto em seus relatórios de resultados de teste, o que pode ser útil para descobrir onde existe um defeito em uma página, caso seu teste encontre um problema. Finalmente, declarações echo podem ser usadas para imprimir o conteúdo de variáveis Selenium.

| Command | Target                    | Value |
| ------- | ------------------------- | ----- |
| echo    | Testing page footer now.  |       |
| echo    | Username is \\${userName} |       |

## Alertas, Popups e Múltiplas Janelas

Suponha que você esteja testando uma página semelhante a esta.

```html
  <!DOCTYPE HTML>
  <html>
  <head>
    <script type="text/javascript">
      function output(resultText){
        document.getElementById('output').childNodes[0].nodeValue=resultText;
      }

      function show_confirm(){
        var confirmation=confirm("Chose an option.");
        if (confirmation==true){
          output("Confirmed.");
        }
        else{
          output("Rejected!");
        }
      }
      
      function show_alert(){
        alert("I'm blocking!");
        output("Alert is gone.");
      }
      function show_prompt(){
        var response = prompt("What's the best web QA tool?","Selenium");
        output(response);
      }
      function open_window(windowName){
        window.open("newWindow.html",windowName);
      }
      </script>
  </head>
  <body>

    <input type="button" id="btnConfirm" onclick="show_confirm()" value="Show confirm box" />
    <input type="button" id="btnAlert" onclick="show_alert()" value="Show alert" />
    <input type="button" id="btnPrompt" onclick="show_prompt()" value="Show prompt" />
    <a href="newWindow.html" id="lnkNewWindow" target="_blank">New Window Link</a>
    <input type="button" id="btnNewNamelessWindow" onclick="open_window()" value="Open Nameless Window" />
    <input type="button" id="btnNewNamedWindow" onclick="open_window('Mike')" value="Open Named Window" />

    <br />
    <span id="output">
    </span>
  </body>
  </html>
```

O usuário deve responder às caixas de alerta / confirmação, bem como mover o foco para as novas janelas pop-up abertas. Felizmente, o Selenium pode cobrir pop-ups de JavaScript.

Mas antes de começarmos a abordar alertas / confirmações / solicitações em detalhes individuais, é útil compreender a semelhança entre eles. Alertas, caixas de confirmação e todos os prompts têm variações do seguinte

| Command                   | Description                                                              |
| ------------------------- | ------------------------------------------------------------------------ |
| assertFoo(pattern)        | gera erro se o padrão não corresponder ao texto do pop-up                |
| assertFooPresent          | gera erro se o pop-up estiver presente                                   |
| assertFooNotPresent       | gera um erro se algum pop-up não estiver presente                        |
| storeFoo(variable)        | armazena o texto do pop-up em uma variável                               |
| storeFooPresent(variable) | armazena o texto do pop-up em uma variável e retorna verdadeiro ou falso |

Ao executar no Selenium, pop-ups de JavaScript não aparecerão. Isto é porque as chamadas de função são realmente substituídas em tempo de execução pelo próprio JavaScript do Selenium. No entanto, só porque você não pode ver o pop-up, não significa que você não tem que lidar com isso. Para lidar com um pop-up, você deve chamar sua função `assertFoo(padrão)`. Se você falhar em fazer a asserção da presença de um pop-up, seu próximo comando será bloqueado e você obterá um erro semelhante ao seguinte `[error] Error: There was an unexpected Confirmation! [Chose an option.]`

### Alertas

Vamos começar com alertas porque eles são os pop-ups mais simples de lidar. Para começar, abra o exemplo de HTML acima em um navegador e clique no botão “Show alert”. Você vai observar que, depois de fechar o alerta, o texto “Alert is gone.” é exibido na página. Agora execute as mesmas etapas com a gravação da Selenium IDE e verifique que o texto é adicionado após fechar o alerta. Seu teste será parecido com este:

| Command           | Target         | Value |
| ----------------- | -------------- | ----- |
| open              | /              |       |
| click             | btnAlert       |       |
| assertAlert       | I’m blocking!  |       |
| verifyTextPresent | Alert is gone. |       |

Você pode estar pensando: “Isso é estranho, nunca tentei fazer uma asserção nesse alerta.” Mas isso é a Selenium-IDE manipulando e fechando o alerta para você. Se você remover essa etapa e repetir o teste você obterá o seguinte erro `[error] Error: There was an unexpected Alert! [I'm blocking!]`. Você deve incluir uma asserção do alerta para reconhecer sua presença.

Se você apenas deseja verificar que um alerta está presente, mas não sabe ou não se importa o texto que ele contém, você pode usar `assertAlertPresent`. Isso retornará verdadeiro ou falso, sendo que falso faz o teste parar.

### Confirmações

As confirmações se comportam da mesma forma que os alertas, com `assertConfirmation` e `assertConfirmationPresent` oferecendo as mesmas características de suas contrapartes de alerta. No entanto, por padrão, o Selenium selecionará OK quando uma confirmação for exibida. Tente gravar clicando no botão “Show confirm box” na página de amostra, mas clique no botão “Cancel” no pop-up e, em seguida, confirme o texto de saída. Seu teste pode ser semelhante a este:

| Command                        | Target            | Value |
| ------------------------------ | ----------------- | ----- |
| open                           | /                 |       |
| click                          | btnConfirm        |       |
| chooseCancelOnNextConfirmation |                   |       |
| assertConfirmation             | Choose an option. |       |
| verifyTextPresent              | Rejected          |       |

A função `chooseCancelOnNextConfirmation` diz ao Selenium que todas as seguintes confirmações devem retornar falso. Ela pode ser redefinido chamando chooseOkOnNextConfirmation.

Você vai notar que não pode repetir este teste, porque o Selenium reclama que há uma confirmação não tratada. Isso ocorre porque a ordem dos registros de eventos do Selenium-IDE faz com que o clique e chooseCancelOnNextConfirmation sejam colocados na ordem errada (faz sentido se você pensar sobre isso, o Selenium não pode saber que você está cancelando antes de abrir uma confirmação). Simplesmente troque esses dois comandos e seu teste funcionará bem.

### Prompts

Os prompts se comportam da mesma forma que os alertas, com `assertPrompt` e `assertPromptPresent` oferecendo as mesmas características que suas contrapartes de alerta. Por padrão, o Selenium irá esperar você inserir dados quando o prompt for exibido. Tente gravar clicando no botão “Show prompt” na página de amostra e digite “Selenium” no prompt. Seu teste pode ser semelhante a este:

| Command            | Target                       | Value |
| ------------------ | ---------------------------- | ----- |
| open               | /                            |       |
| answerOnNextPrompt | Selenium!                    |       |
| click              | id=btnPrompt                 |       |
| assertPrompt       | What’s the best web QA tool? |       |
| verifyTextPresent  | Selenium!                    |       |

```html
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Sample Selenium Test Suite</title>
    </head>
    <body>
        <table cellpadding="1" cellspacing="1" border="1">
            <thead>
                <tr><td>Test Cases for De Anza A-Z Directory Links</td></tr>
            </thead>
        <tbody>
            <tr><td><a href="./a.html">A Links</a></td></tr>
            <tr><td><a href="./b.html">B Links</a></td></tr>
            <tr><td><a href="./c.html">C Links</a></td></tr>
            <tr><td><a href="./d.html">D Links</a></td></tr>
        </tbody>
        </table>
    </body>
</html>
```

***

*error loading test case: no command found*

Você usou **File => Open** para tentar abrir um arquivo de suíte de testes. Use **File => Open Test Suite** em vez disso.

Uma solicitação de aprimoramento foi levantada para melhorar esta mensagem de erro. Veja a [issue 1010](http://code.google.com/p/selenium/issues/detail?id=1010).

***

Este tipo de **erro** pode indicar um problema de tempo, ou seja, o elemento especificado por um localizador em seu comando não foi totalmente carregado quando o comando foi executado. Tente colocar um **pause 5000** antes do comando para determinar se o problema está realmente relacionado ao tempo. Em caso afirmativo, investigue usando um comando **waitFor\*** ou **\*AndWait** apropriado antes do comando com falha.

***

Sempre que sua tentativa de usar a substituição de variável falha, como é o caso para o comando **open** acima, isso indica que você não criou realmente a variável cujo valor você está tentando acessar. Isto é às vezes devido a colocar a variável no campo **Valor** quando deve estar no campo **Destino** ou vice-versa. No exemplo acima, os dois parâmetros para o comando **store** foram erroneamente colocados na ordem inversa do que é necessário. Para qualquer comando Selenese, o primeiro parâmetro obrigatório deve ir no campo **Destino** e o segundo parâmetro obrigatório (se houver) deve ir no campo **Valor**.

***

*error loading test case: \[Exception… “Component returned failure code: 0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND) \[nsIFileInputStream.init]” nresult: “0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND)” location: “JS frame :: chrome://selenium-ide/content/file-utils.js :: anonymous :: line 48” data: no]*

Um dos casos de teste em seu conjunto de testes não pode ser encontrado. Certifique-se de que o caso de teste está realmente localizado onde o conjunto de testes indica que ele está localizado. Além disso, certifique-se de que seus arquivos de caso de teste tenham a extensão .html em seus nomes de arquivo e no arquivo de suíte de testes onde são referenciados.

Uma solicitação de aprimoramento foi levantada para melhorar esta mensagem de erro. Veja a [issue 1011](http://code.google.com/p/selenium/issues/detail?id=1011).

***

O conteúdo do seu arquivo de extensão não foi lido pela Selenium-IDE. Certifique-se de ter especificado o nome do caminho adequado para o arquivo de extensões via **Options => Options => General** no campo **Selenium Core extensions**. Além disso, a Selenium-IDE deve ser reiniciada após qualquer alteração em um arquivo de extensões *ou* no conteúdo do campo **Selenium Core extensions**.

# 4.1 - HTML runner

```shell
[user@localhost ~]$ cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

[user@localhost ~]$ rpm -qa | egrep -i "xvfb|java-1.8|firefox"
xorg-x11-server-Xvfb-1.19.3-11.el7.x86_64
firefox-52.4.0-1.el7.centos.x86_64
java-1.8.0-openjdk-1.8.0.151-1.b12.el7_4.x86_64
java-1.8.0-openjdk-headless-1.8.0.151-1.b12.el7_4.x86_64
```

Exemplo de suíte de testes:

```html
[user@localhost ~]$ cat testsuite.html
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
  <title>Test Suite</title>
</head>
<body>
<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium"><tbody>
<tr><td><b>Test Suite</b></td></tr>
<tr><td><a href="YOUR-TEST-SCENARIO.html">YOUR-TEST-SCENARIO</a></td></tr>
</tbody></table>
</body>
</html>
```

## Como rodar o selenium-html-runner headless

Agora, a parte mais importante, um exemplo de como executar o selenium-html-runner! Sua experiência pode variar dependendo das combinações de software - versões geckodriver / FF / html-runner.

```shell
xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
```

```shell
[user@localhost ~]$ xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "*firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
Multi-window mode is longer used as an option and will be ignored.
1510061109691   geckodriver     INFO    geckodriver 0.18.0
1510061109708   geckodriver     INFO    Listening on 127.0.0.1:2885
1510061110162   geckodriver::marionette INFO    Starting browser /usr/bin/firefox with args ["-marionette"]
1510061111084   Marionette      INFO    Listening on port 43229
1510061111187   Marionette      WARN    TLS certificate errors will be ignored for this session
Nov 07, 2017 1:25:12 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
2017-11-07 13:25:12.714:INFO::main: Logging initialized @3915ms to org.seleniumhq.jetty9.util.log.StdErrLog
2017-11-07 13:25:12.804:INFO:osjs.Server:main: jetty-9.4.z-SNAPSHOT
2017-11-07 13:25:12.822:INFO:osjsh.ContextHandler:main: Started o.s.j.s.h.ContextHandler@87a85e1{/tests,null,AVAILABLE}
2017-11-07 13:25:12.843:INFO:osjs.AbstractConnector:main: Started ServerConnector@52102734{HTTP/1.1,[http/1.1]}{0.0.0.0:31892}
2017-11-07 13:25:12.843:INFO:osjs.Server:main: Started @4045ms
Nov 07, 2017 1:25:13 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |open | /auth_mellon.php |  |
Nov 07, 2017 1:25:14 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |waitForPageToLoad | 3000 |  |
.
.
.etc

<td>result:</td>
<td>PASS</td>
```

----
url: https://www.selenium.dev/ja/_print/documentation/grid/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/grid/).

# Grid

複数のマシンで並行してテストを実行したいですか？ Grid が手助けします。

* 1: [Gridを始める](#pg-3c2b75d36f1614bda9b1f90fda16b57d)
* 2: [いつGridを使用すべきか](#pg-0918ac00dadcaec8ed42334dbf603f55)
* 3: [Selenium Grid のコンポーネント](#pg-456d2e951a458e6f18fe16c80ad70bc5)
* 4: [コンポーネントの構成](#pg-6355fd8c1e3f7ed9dd004a69385e35a6)
* * 4.1: [構成ヘルプ](#pg-12759b62a0129dd593b35c93c9ce349e)
  * 4.2: [Selenium GridのCLI オプション](#pg-4ed8bf1ae4585a0e8d21dbdfce81afb8)
  * 4.3: [Toml オプション](#pg-e617239c5efb3fbc97f69447f5ba5981)
  5: [Grid アーキテクチャ](#pg-9c11ba83187c12a3cd6b4a1789bae031)
* 6: [高度な機能](#pg-abac6f77089fbf05fa24eca43aebeddf)
  * 6.1: [可観測性](#pg-cff3310fa01f534cfe804c3e76ae9056)
  * 6.2: [GraphQLクエリのサポート](#pg-b11540ed82255545d0e8201c6e111a70)
  * 6.3: [Grid エンドポイント](#pg-d62408233c3d62bcee1fef32842d1ecd)
  * 6.4: [Customizing a Node](#pg-5b5dba3035d5fdea37ea443e04bc3675)
  * 6.5: [External datastore](#pg-e65991b592e30916d941bdbfabb53abe)

Selenium Grid を利用して、クライアントからリモートブラウザーインスタンスにコマンドを ルーティングし、リモートマシン上で WebDriver スクリプトを実行することができます。

Grid の目標は、

* 複数のマシンでの並行したテスト実行を、簡単な方法で提供する
* 異なるバージョンのブラウザでのテストを可能にする
* クロスプラットフォームテストを可能にする

興味がありますか？ Grid の仕組みと設定方法が知りたければ以下のセクションを読んでください。

# 1 - Gridを始める

Selenium Gridの導入方法

## クイックスタート

1. 事前条件

   * Java 11 もしくはそれ以上がインストールされていること

   * ブラウザーがインストールされていること

   * ブラウザードライバー

     * [Selenium Manager](https://www.selenium.dev/ja/documentation/selenium_manager/) will configure the drivers automatically if you add `--selenium-manager true`.
     * [`PATH` が通っているインストール済みのもの](https://www.selenium.dev/ja/documentation/webdriver/troubleshooting/errors/driver_location/#use-the-path-environment-variable)

```shell
java -jar selenium-server-<version>.jar standalone
```

```shell
java -jar selenium-server-<version>.jar hub
```

デフォルトでは、サーバーは<http://localhost:4444>にて `RemoteWebDriver` リクエストを待ち受けます。

#### ノード

**ノード**は起動時にシステムの[パス](https://www.selenium.dev/ja/documentation/webdriver/troubleshooting/errors/driver_location/#use-the-path-environment-variable) が通っている利用可能なドライバーを検出します。

次のコマンドは**ノード**が**ハブ**と同じマシン上で動作していることを前提としています。

```shell
java -jar selenium-server-<version>.jar node
```

##### 同一マシン上での複数ノード

ノード 1

```shell
java -jar selenium-server-<version>.jar node --port 5555
```

ノード 2

```shell
java -jar selenium-server-<version>.jar node --port 6666
```

##### 異なるマシンでノードとハブを動かす

**ハブ**と**ノード**は HTTP と[**イベントバス**](https://www.selenium.dev/ja/documentation/grid/components/#event-bus)を介して通信します (**イベントバス**は**ハブ**の一部として存在します)。 **ノード**は**イベントバス**を通じてメッセージを送信し、登録処理を開始します。 **ハブ**がメッセージを受け取り、**ノード**の存在を確かめるため HTTP を使って**ノード**にアクセスします。

**ハブ**がデフォルトのポートを使用していれば、 `--hub` フラグで**ノード**を登録することができます。

```shell
java -jar selenium-server-<version>.jar node --hub http://<hub-ip>:4444
```

**ハブ**がデフォルトのポートを使用していない場合、`--publish-events` と `--subscribe-events` のフラグが必要です。

例えば**ハブ**が `8886` `8887` `8888` ポートを利用している場合、

```shell
java -jar selenium-server-<version>.jar hub --publish-events tcp://<hub-ip>:8886 --subscribe-events tcp://<hub-ip>:8887 --port 8888
```

**ノード**はこれらのポートを登録する際に使用します。

```shell
java -jar selenium-server-<version>.jar node --publish-events tcp://<hub-ip>:8886 --subscribe-events tcp://<hub-ip>:8887
```

### 分散

分散 Grid を利用すると、各コンポーネントは別々に起動され異なるマシン上で動作します。

コンポーネント間で通信をするために、全てのポートを適切に公開することが重要です。

1. **イベントバス**は Grid コンポーネント間での内部通信を可能にします。

デフォルトポートは `4442`, `4443`, `5557` です。

```shell
java -jar selenium-server-<version>.jar event-bus --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --port 5557
```

2. **新規セッションキュー**は新規セッションリクエストをキューに積み、ディストリビューターがリクエストを取得できるようにします。

デフォルトポートは `5559` です。

```shell
java -jar selenium-server-<version>.jar sessionqueue --port 5559
```

3. **セッションマップ**はセッション ID とそのセッションが実行中の**ノード**のマップを持ちます。

デフォルトの**セッションマップ**のポートは `5556` です。 **セッションマップ**は**イベントバス**と通信します。

```shell
java -jar selenium-server-<version>.jar sessions --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --port 5556
```

4. **ディストリビューター**は**新規セッションキュー**に新規セッションリクエストを問い合わせ、 capabilities がマッチする**ノード**にアサインします。**ノード**は、**ハブ&ノード**構成の Grid における**ハブ**の登録と同じように、**ディストリビューター**に登録します。

デフォルトの**ディストリビューター**のポートは `5553` です。 **ディストリビューター**は**新規セッションキュー**、**セッションマップ**、**イベントバス**、**ノード**と通信します。

```shell
java -jar selenium-server-<version>.jar distributor --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --sessions http://<sessions-ip>:5556 --sessionqueue http://<new-session-queue-ip>:5559 --port 5553 --bind-bus false
```

5. **ルーター**は**新規セッションリクエスト**をキューに、既存セッションのリクエストをそのセッションが実行中の**ノード**に転送します。

デフォルトの**ルーター**のポートは `4444` です。 **ルーター**は**新規セッションキュー**、**セッションマップ**、**ディストリビューター**と通信します。

```shell
java -jar selenium-server-<version>.jar router --sessions http://<sessions-ip>:5556 --distributor http://<distributor-ip>:5553 --sessionqueue http://<new-session-queue-ip>:5559 --port 4444
```

6. ノード

デフォルトの**ノード**のポートは `5555` です。

```shell
java -jar selenium-server-<version>.jar node --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443
```

## テストメタデータ

テストにメタデータを追加して、[GraphQL](https://www.selenium.dev/ja/documentation/grid/advanced_features/graphql_support/) 経由で使用するか、Selenium Grid UI 経由でその一部( `se:name` など) を可視化します。

メタデータは capability に`se:`プリフィックスをつけることで追加できます。 Java での簡単な例を紹介します。

```java
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setCapability("browserVersion", "100");
chromeOptions.setCapability("platformName", "Windows");
// Showing a test name instead of the session id in the Grid UI
chromeOptions.setCapability("se:name", "My simple test");
// Other type of metadata can be seen in the Grid UI by clicking on the
// session info or via GraphQL
chromeOptions.setCapability("se:sampleMetadata", "Sample metadata value");
WebDriver driver = new RemoteWebDriver(new URL("http://gridUrl:4444"), chromeOptions);
driver.get("http://www.google.com");
driver.quit();
```

```bash
java -Dwebdriver.http.factory=jdk-http-client -jar selenium-server-<version>.jar --ext selenium-http-jdk-client-<version>.jar standalone
```

`selenium-http-jdk-client`をダウンロードする別の方法として[Coursier](https://get-coursier.io/docs/cli-installation)を使う方法があります。

```bash
java -Dwebdriver.http.factory=jdk-http-client -jar selenium-server-<version>.jar --ext $(coursier fetch -p org.seleniumhq.selenium:selenium-http-jdk-client:<version>) standalone
```

# 2 - いつGridを使用すべきか

```
   15      *       45s        /        1        =      11m 15s   // Grid なし
   15      *       45s        /        5        =      2m 15s    // 5 ノードの Grid
   15      *       45s        /        15       =      45s       // 15 ノードの Grid
  100      *       120s       /        15       =      13m 20s   // Grid なしの場合3時間以上かかります
```

テストスイートが実行されると Grid はテストで設定されたブラウザに対して実行するテストを割り当てます。

このような設定により、大規模な Selenium テストスイートであっても実行時間を大幅に短縮することができます。

Selenium Grid は Selenium プロジェクトの一部であり、 Selenium コアの開発コミッターと同じチームによってメンテナンスされています。 テストの実行速度の重要性を認識し、Grid は Selenium プロジェクトの初期段階から重要な役割を担っています。

# 3 - Selenium Grid のコンポーネント

# 4 - コンポーネントの構成

ここでは、各コンポーネントを、共通の設定とコンポーネント固有の設定で個別に設定する方法を確認できます。

# 4.1 - 構成ヘルプ

```shell
java -jar selenium-server-<version>.jar info config
```

### セキュリティ

安全な通信とノード登録のためのグリッドサーバーの設定の詳細を取得するには、以下を実行します。

```shell
java -jar selenium-server-<version>.jar info security
```

### セッションマップの設定

デフォルトでは、グリッドはローカルセッションマップを使用してセッション情報を保存します。 グリッドは、Redis や JDBC-SQL がサポートするデータベースなどの追加のストレージオプションをサポートしています。 別のセッションストレージをセットアップするには、次のコマンドを使用してセットアップ手順を取得します。

```shell
java -jar selenium-server-<version>.jar info sessionmap
```

### OpenTelemetry と Jaeger を使用したトレースの設定

デフォルトでは、トレースは有効になっています。 トレースをエクスポートして Jaeger 経由で視覚化するには、次のコマンドを使用して手順を実行します。

```shell
java -jar selenium-server-<version>.jar info tracing
```

## SeleniumGrid コマンドを一覧表示する

```shell
java -jar selenium-server-<version>.jar --config-help
```

使用可能なすべてのコマンドとそれぞれの説明が表示されます。

## コンポーネントヘルプコマンド

Selenium ロールの後に–help config オプションを渡して、コンポーネント固有の構成情報を取得します。

### スタンドアロン

```shell
java -jar selenium-server-<version>.jar standalone --help
```

### ハブ

```shell
java -jar selenium-server-<version>.jar hub --help
```

### セッション

```shell
java -jar selenium-server-<version>.jar sessions --help
```

### 新規セッションキュー

```shell
java -jar selenium-server-<version>.jar sessionqueue --help
```

### ディストリビューター

```shell
java -jar selenium-server-<version>.jar distributor --help
```

### ルーター

```shell
java -jar selenium-server-<version>.jar router --help
```

### ノード

```shell
java -jar selenium-server-<version>.jar node --help
```

# 4.2 - Selenium GridのCLI オプション

全てのGridコンポーネントのCLIオプション詳細

Grid の設定には、さまざまなセクションが用意されています。 各セクションには、コマンドライン引数で設定可能なオプションがあります。コマンドライン引数で設定できます。

コンポーネントとセクションの対応は以下の通りです。

オプションが変更、または追加されたが文書化されていない場合、 このドキュメントは古くなる可能性があることに注意してください。 もしそのような状況を見つけたら、[“構成ヘルプ”](https://www.selenium.dev/ja/documentation/grid/configuration/help/)を確認し、 ドキュメントを更新するプルリクエストを気軽に送ってください。

## セクション

|                               | スタンドアロン | ハブ | ノード | ディストリビューター | ルーター | セッション | 新規セッションキュー |
| ----------------------------- | ------- | -- | --- | ---------- | ---- | ----- | ---------- |
| [Distributor](#distributor)   | **      | ** |     | **         | **   |       |            |
| [Docker](#docker)             | **      |    | **  |            |      |       |            |
| [Events](#events)             |         | ** | **  | **         |      | **    | **         |
| [Logging](#logging)           | **      | ** | **  | **         | **   | **    | **         |
| [Network](#network)           | **      | ** |     |            | **   |       |            |
| [Node](#node)                 | **      |    | **  |            |      |       |            |
| [Router](#router)             | **      | ** |     |            | **   |       |            |
| [Relay](#relay)               | **      |    | **  |            |      |       |            |
| [Server](#server)             | **      | ** | **  | **         | **   | **    | **         |
| [SessionQueue](#sessionqueue) | **      | ** |     | **         | **   |       | **         |
| [Sessions](#sessions)         |         |    |     | **         | **   | **    |            |

### Distributor

| オプション                          | 型       | 値/例                                                                 | 概要                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| ------------------------------ | ------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--healthcheck-interval`       | int     | `120`                                                               | 全てのノードに対してヘルスチェックを実行する頻度（秒）を指定します。これにより、サーバーは全てのノードに対して正常に ping を送信できるようになります。                                                                                                                                                                                                                                                                                                                                                                      |
| `--distributor`                | uri     | `http://localhost:5553`                                             | ディストリビューターの URL。                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `--distributor-host`           | string  | `localhost`                                                         | ディストリビューターがリッスンするホスト名。                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `--distributor-implementation` | string  | `org.openqa.selenium.grid.distributor.local.LocalDistributor`       | デフォルトでないディストリビューター実装の完全なクラス名。                                                                                                                                                                                                                                                                                                                                                                                                                       |
| `--distributor-port`           | int     | `5553`                                                              | ディストリビューターがリッスンするポート番号。                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `--reject-unsupported-caps`    | boolean | `false`                                                             | Grid がサポートしていない capabilities をリクエストされた時、ディストリビューターがリクエストを即座に今日できるようにします。これはオンデマンドでノードを立ち上げをしない Grid の設定に適しています。                                                                                                                                                                                                                                                                                                                                     |
| `--slot-matcher`               | string  | `org.openqa.selenium.grid.data.DefaultSlotMatcher`                  | デフォルト以外で使用するスロットマッチャーの完全なクラス名。これはノードが特定のセッションをサポートできるかを判断するために使用されます。                                                                                                                                                                                                                                                                                                                                                                               |
| `--slot-selector`              | string  | `org.openqa.selenium.grid.distributor.selector.DefaultSlotSelector` | デフォルト以外のスロットセレクターの完全なクラス名。これは、ノードがマッチした後ノード内のスロットを選択するために使用されます。                                                                                                                                                                                                                                                                                                                                                                                    |
| `--newsession-threadpool-size` | int     | `24`                                                                | The Distributor uses a fixed-sized thread pool to create new sessions as it consumes new session requests from the queue. This allows configuring the size of the thread pool. The default value is no. of available processors \* 3. Note: If the no. of threads is way greater than the available processors it will not always increase the performance. A high number of threads causes more context switching which is an expensive operation. |
| `--purge-nodes-interval`       | int     | `30`                                                                | How often, in seconds, will the Distributor purge Nodes that have been down for a while. This is calculated based on the heartbeat received from a particular node.                                                                                                                                                                                                                                                                                 |

### Docker

| オプション                       | 型         | 値/例                                                               | 概要                                                                                                                                                                                                                                                                                          |
| --------------------------- | --------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--docker-assets-path`      | string    | `/opt/selenium/assets`                                            | アセットが保存される絶対パス。                                                                                                                                                                                                                                                                             |
| `--docker-`                 | string\[] | `selenium/standalone-firefox:latest '{"browserName": "firefox"}'` | イメージとステレオタイプの capabilities を対応付ける Docker 設定 (例 \`-D selenium/standalone-firefox:latest ‘{“browserName”: “firefox”}’)                                                                                                                                                                        |
| `--docker-devices`          | string\[] | `/dev/kvm:/dev/kvm`                                               | コンテナに対してデバイスを公開します。各デバイスマッピングは、ホストとコンテナの両方のデバイスへのパスを、コロンで区切って保つ必要があります。例: /device/path/in/host:/device/path/in/container                                                                                                                                                                    |
| `--docker-host`             | string    | `localhost`                                                       | Docker デーモンが動作しているホスト名。                                                                                                                                                                                                                                                                     |
| `--docker-port`             | int       | `2375`                                                            | Docker デーモンが動作しているポート名。                                                                                                                                                                                                                                                                     |
| `--docker-url`              | string    | `http://localhost:2375`                                           | Docker デーモンに接続するための URL。                                                                                                                                                                                                                                                                    |
| `--docker-video-image`      | string    | `selenium/video:latest`                                           | ビデオレコーディングが有効になっているときに利用される Docker イメージ。                                                                                                                                                                                                                                                    |
| `--docker-host-config-keys` | string\[] | `Dns DnsOptions DnsSearch ExtraHosts Binds`                       | Specify which docker host configuration keys should be passed to browser containers. Keys name can be found in the Docker API [documentation](https://docs.docker.com/engine/api/v1.41/#tag/Container/operation/ContainerCreate), or by running `docker inspect` the node-docker container. |

### Events

| オプション                     | 型       | 値/例                                                | 概要                                                                                                                                                |
| ------------------------- | ------- | -------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--bind-bus`              | boolean | `false`                                            | 接続をバインドするかコネクトするかを指定します。 true の場合、コンポーネントはイベントバスにバインドされます（イベントバスもコンポーネントによって起動されます、通常はディストリビューターとハブによって起動されます）。 false の場合、コンポーネントがイベントバスにコネクトします。 |
| `--events-implementation` | string  | `org.openqa.selenium.events.zeromq.ZeroMqEventBus` | デフォルトでないイベントバス実装の完全なクラス名。                                                                                                                         |
| `--publish-events`        | string  | `tcp://*:4442`                                     | イベントをイベントバスに配信するための接続文字列。                                                                                                                         |
| `--subscribe-events`      | string  | `tcp://*:4443`                                     | イベントをイベントバスから購読するための接続文字列。                                                                                                                        |

### Logging

| オプション                    | 型       | 値/例                                                                                                                                      | 概要                                                                                                                                       |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- |
| `--http-logs`            | boolean | `false`                                                                                                                                  | http ログを有効にします。http ログを記録するには、トレースを有効にする必要があります。                                                                                         |
| `--log-encoding`         | string  | `UTF-8`                                                                                                                                  | ログのエンコーディング。                                                                                                                             |
| `--log`                  | string  | Windows パスの例: `'\path\to\file\gridlog.log'` or `'C:\path\path\to\file\gridlog.log'` Linux/Unix/MacOS パスの例: `'/path/to/file/gridlog.log'` | ログを出力するファイル。OS のファイルパスと互換性があることを確認してください。                                                                                                |
| `--log-level`            | string  | `“INFO”`                                                                                                                                 | ログレベル。デフォルトは INFO です。 ログレベルはこちらを参照してください。 <https://docs.oracle.com/en/java/javase/11/docs/api/java.logging/java/util/logging/Level.html> |
| `--plain-logs`           | boolean | `true`                                                                                                                                   | プレーンなログを使用します。                                                                                                                           |
| `--structured-logs`      | boolean | `false`                                                                                                                                  | 構造化ログを使用します。                                                                                                                             |
| `--tracing`              | boolean | `true`                                                                                                                                   | トレースを有効にします。                                                                                                                             |
| `--log-timestamp-format` | string  | `HH:mm:ss.SSS`                                                                                                                           | ログのタイムスタンプ形式を設定できます。                                                                                                                     |

### Network

| オプション            | 型       | 値/例     | 概要                                                  |
| ---------------- | ------- | ------- | --------------------------------------------------- |
| `--relax-checks` | boolean | `false` | 受信リクエストのオリジンヘッダーとコンテンツタイプに対する、厳格な W3C 準拠の検証をを緩和します。 |

### Node

| オプション                            | 型         | 値/例                                                                                                                                                                                                                                                                        | 概要                                                                                                                                                                                                                                                                                                                                                                             |
| -------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--detect-drivers`               | boolean   | `true`                                                                                                                                                                                                                                                                     | 現在のシステム上で利用可能なドライバーを自動で検出してノードに追加します。                                                                                                                                                                                                                                                                                                                                          |
| `--driver-configuration`         | string\[] | `display-name="Firefox Nightly" max-sessions=2 webdriver-path="/usr/local/bin/geckodriver" stereotype="{\"browserName\": \"firefox\", \"browserVersion\": \"86\", \"moz:firefoxOptions\": {\"binary\":\"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"` | ノードがサポートするドライバーの一覧。可読性向上のため TOML ファイルで設定することを推奨します。                                                                                                                                                                                                                                                                                                                            |
| `--driver-factory`               | string\[] | `org.openqa.selenium.example.LynxDriverFactory '{"browserName": "lynx"}'`                                                                                                                                                                                                  | 完全修飾クラス名と、そのクラスが対応するブラウザの設定とのマッピング。                                                                                                                                                                                                                                                                                                                                            |
| `--driver-implementation`        | string\[] | `"firefox"`                                                                                                                                                                                                                                                                | チェックされるドライバー。指定された場合、自動設定はスキップされます。                                                                                                                                                                                                                                                                                                                                            |
| `--node-implementation`          | string    | `"org.openqa.selenium.grid.node.local.LocalNodeFactory"`                                                                                                                                                                                                                   | デフォルトでないノード実装の完全なクラス名。これはセッションのライフサイクルを管理するために使用されます。                                                                                                                                                                                                                                                                                                                          |
| `--grid-url`                     | string    | `https://grid.example.com`                                                                                                                                                                                                                                                 | Grid 全体のパブリックな URL (通常ハブかルーターのアドレスです)。                                                                                                                                                                                                                                                                                                                                         |
| `--heartbeat-period`             | int       | `60`                                                                                                                                                                                                                                                                       | ノードが生存していることを知らせるため、ノードがディストリビューターに送るハードビートを、どのくらいの頻度（秒）で送るか。                                                                                                                                                                                                                                                                                                                  |
| `--max-sessions`                 | int       | `8`                                                                                                                                                                                                                                                                        | 最大同時接続セッション数。デフォルトは利用可能なプロセッサーの数です。                                                                                                                                                                                                                                                                                                                                            |
| `--override-max-sessions`        | boolean   | `false`                                                                                                                                                                                                                                                                    | 利用可能なプロセッサーの数は、推奨される最大セッション数（プロセッサーごとに 1 つのブラウザセッション）です。このフラグを true に設定すると、推奨される最大値を上書きすることができます。セッションの安定性と信頼性が損なわれ、ホストがリソースを使い果たす可能性があります。                                                                                                                                                                                                                                    |
| `--register-cycle`               | int       | `10`                                                                                                                                                                                                                                                                       | ノードがディストリビューターに初回登録を試みる頻度(秒)。                                                                                                                                                                                                                                                                                                                                                  |
| `--register-period`              | int       | `120`                                                                                                                                                                                                                                                                      | ノードが初めてディストリビューターに初回登録を試みるのにかかる時間(秒)。この時間が経過すると、ノードは再登録を試みない。                                                                                                                                                                                                                                                                                                                  |
| `--session-timeout`              | int       | `300`                                                                                                                                                                                                                                                                      | X をセッションタイムアウト(秒)としたとき、 ノード は、過去 X 秒間に何の活動もなかったセッションを自動的に終了させます。 これにより他のテストが利用できるようスロットを解放します。                                                                                                                                                                                                                                                                                 |
| `--vnc-env-var`                  | string\[] | `SE_START_XVFB SE_START_VNC SE_START_NO_VNC`                                                                                                                                                                                                                               | VNC ストリームが利用可能かどうかを判断するために利用する環境変数。                                                                                                                                                                                                                                                                                                                                            |
| `--no-vnc-port`                  | int       | `7900`                                                                                                                                                                                                                                                                     | VNC が利用可能な場合、ローカルの noVNC ストリームを取得できるポートを設定します。                                                                                                                                                                                                                                                                                                                                 |
| `--drain-after-session-count`    | int       | `1`                                                                                                                                                                                                                                                                        | X 個のセッションが実行された後に、ノードをドレインしてシャットダウンします。 Kubernetes のような環境で有用です。 0 より大きい値を指定すると、この機能が有効になります。                                                                                                                                                                                                                                                                                   |
| `--hub`                          | string    | `http://localhost:4444`                                                                                                                                                                                                                                                    | ハブ・ノード構成におけるハブのアドレスを指定します。ホスト名か IP アドレスが指定できます。この場合、ハブは `http://hostname:4444` とみなされ、 `--grid-url` は同じものになります。 `--publish-events` は `tcp://hostname:4442` 、`--subscribe-events` は `tcp://hostname:4443` となります。 `hostname` にポート番号が含まれている場合は、それが `--grid-url` に使用されますが、イベントバスの URI は変更されません。これらのデフォルト値は、適切なフラグを設定することでオーバーライドすることができます。ホスト名にプロトコル(`https`のような)が含まれる場合もそれが利用されます。 |
| `--enable-cdp`                   | boolean   | `true`                                                                                                                                                                                                                                                                     | Grid 内で CDP プロキシーを有効にします。もしネットワークが web socket を許可していない場合、Grid 管理者は CDP を無効にできます。デフォルトは true です。                                                                                                                                                                                                                                                                                |
| `--enable-managed-downloads`     | boolean   | `false`                                                                                                                                                                                                                                                                    | This causes the Node to auto manage files downloaded for a given session on the Node.                                                                                                                                                                                                                                                                                          |
| `--selenium-manager`             | boolean   | `false`                                                                                                                                                                                                                                                                    | When drivers are not available on the current system, use Selenium Manager. False by default.                                                                                                                                                                                                                                                                                  |
| `--connection-limit-per-session` | int       | `10`                                                                                                                                                                                                                                                                       | Let X be the maximum number of websocket connections per session.This will ensure one session is not able to exhaust the connection limit of the host.                                                                                                                                                                                                                         |

### Relay

| オプション                        | 型         | 値/例                                                                                                               | 概要                                                                                                              |
| ---------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------- |
| `--service-url`              | string    | `http://localhost:4723`                                                                                           | Appium サーバーやクラウドサービスなど、WebDriver コマンドをサポートするサービスに接続するための URL です。                                                |
| `--service-host`             | string    | `localhost`                                                                                                       | WebDriver コマンドをサポートしてるサービスが稼働しているホスト名。                                                                          |
| `--service-port`             | int       | `4723`                                                                                                            | WebDriver コマンドをサポートしてるサービスが稼働しているポート番号。                                                                         |
| `--service-status-endpoint`  | string    | `/status`                                                                                                         | WebDriver サービスの状態を問い合わせるエンドポイント、オプショナルです。HTTP 200 レスポンスが期待されます。                                                 |
| `--service-protocol-version` | string    | `HTTP/1.1`                                                                                                        | Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status |
| `--service-configuration`    | string\[] | `max-sessions=2 stereotype='{"browserName": "safari", "platformName": "iOS", "appium:platformVersion": "14.5"}}'` | 呼び出しの中継先となるサービスの設定。可読性向上のため、TOML ファイルで設定することを推奨します。                                                             |

### Router

| オプション          | 型       | 値/例                        | 概要                                                                                            |
| -------------- | ------- | -------------------------- | --------------------------------------------------------------------------------------------- |
| `--password`   | string  | `myStrongPassword`         | クライアントがサーバーに接続する際に使用するパスワード。このパスワードとユーザー名の両方が設定されていないと使用できません。                                |
| `--username`   | string  | `admin`                    | クライアントがサーバーに接続する際に使用するユーザー名。このユーザー名とパスワードの両方が設定されていないと使用できません。                                |
| `--sub-path`   | string  | `my_company/selenium_grid` | A sub-path that should be considered for all user facing routes on the Hub/Router/Standalone. |
| `--disable-ui` | boolean | `true`                     | Disable the Grid UI.                                                                          |

### Server

| オプション                 | 型       | 値/例                  | 概要                                                                                                                                               |
| --------------------- | ------- | -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--allow-cors`        | boolean | `true`               | Selenium サーバーが任意のホストからのウェブブラウザ接続を許可するかどうか。                                                                                                       |
| `--host`              | string  | `localhost`          | サーバーの IP もしくはホスト名、通常自動的に決定されます。                                                                                                                  |
| `--bind-host`         | boolean | `true`               | サーバがホストアドレス/ホスト名にバインドするか、あるいは到達可能な URL を知らせるためだけに使用するかを指定します。複雑なネットワーク構成で、サーバが現在の IP やホスト名ではなく、 外部の IP やホスト名で自分自身を公開する場合に有用です (例: Docker コンテナ内)。 |
| `--https-certificate` | path    | `/path/to/cert.pem`  | HTTPS のためのサーバー証明書。詳細は “java -jar selenium-server.jar info security” を実行してください。                                                                   |
| `--https-private-key` | path    | `/path/to/key.pkcs8` | HTTPS のための秘密鍵。 詳細は “java -jar selenium-server.jar info security” を実行してください。                                                                      |
| `--max-threads`       | int     | `24`                 | リスナースレッドの最大数。デフォルトは、有効なプロセッサーの \* 3 です。                                                                                                          |
| `--port`              | int     | `4444`               | リッスンポート。このパラメータは異なるコンポーネントによって使用されるため、デフォルトはありません。例えば、ルータ/ハブ/スタンドアロンは 4444 を使用し、ノードは 5555 を使用します。                                                |

### SessionQueue

| オプション                       | 型      | 値/例                     | 概要                                                                                                                                                      |
| --------------------------- | ------ | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--sessionqueue`            | uri    | `http://localhost:1237` | 新規セッションキューサーバーのアドレス。                                                                                                                                    |
| `-sessionqueue-host`        | string | `localhost`             | 新規セッションキューがリッスンするホスト。                                                                                                                                   |
| `--sessionqueue-port`       | int    | `1234`                  | 新規セッションキューがリッスンするポート                                                                                                                                    |
| `--session-request-timeout` | int    | `300`                   | タイムアウト(秒)。 新規セッションリクエストはキューに追加され、設定された時間以上キューに残っているリクエストはタイムアウトします。                                                                                     |
| `--session-retry-interval`  | int    | `5`                     | リトライ間隔(秒)。すべてのスロットがビジーな場合、 新規セッションリクエストはこの時間の間隔をおいてからリトライされます。                                                                                          |
| `--maximum-response-delay`  | int    | `8`                     | How often, in seconds, will the the SessionQueue response in case there is no data, to reduce the http requests while polling for new session requests. |

### Sessions

| オプション             | 型      | 値/例                     | 概要                      |
| ----------------- | ------ | ----------------------- | ----------------------- |
| `--sessions`      | uri    | `http://localhost:1234` | セッションマップサーバーのアドレス。      |
| `--sessions-host` | string | `localhost`             | セッションマップサーバーがリッスンするホスト。 |
| `--sessions-port` | int    | `1234`                  | セッションマップサーバーがリッスンするポート。 |

## 設定例

上記のオプションはすべて、Grid コンポーネントを起動する際に使用することができます。 Grid の適切な設定を模索するのに利用してください。

[TOML ファイル](https://www.selenium.dev/ja/documentation/grid/configuration/toml_options/) を使用して Grid を設定することをおすすめします。 設定ファイルは読みやすく、コード管理できます。

必要に応じて TOML ファイルと CLI オプションを併用することができます。

### コマンドラインフラグ

コマンドラインフラグとしてオプションを渡すには、適切なコンポーネントを特定し以下のテンプレートのようにします。

```
java -jar selenium-server-<version>.jar <component> --<option> value
```

#### スタドアロン、最大セッションとメインポートを設定する

```
java -jar selenium-server-<version>.jar standalone --max-sessions 4 --port 4444
```

#### ハブ、新規セッションリクエストのタイムアウト、メインポートを設定し、トレースを無効にする

```
java -jar selenium-server-<version>.jar hub --session-request-timeout 500 --port 3333 --tracing false
```

#### ノード、最大 4 セッション、デバッグログ、ポート 7777, FireFox と Edge のみ

```
java -jar selenium-server-<version>.jar node --max-sessions 4 --log-level "fine" --port 7777 --driver-implementation "firefox" --driver-implementation "edge"
```

#### ディストリビューター、セッションマップ・新規セッションキューの URL を指定、バスを無効にする

```
java -jar selenium-server-<version>.jar distributor --sessions http://localhost:5556 --sessionqueue http://localhost:5559 --bind-bus false
```

#### 特定ノードにカスタム capabilities を設定する

**重要:** カスタム capabilities は全てのノードに設定される必要があります。 また全てのセッションリクエストに含まれなければいけません。

##### ハブの起動

```
java -jar selenium-server-<version>.jar hub
```

##### customcap に `true` をセットしてノード A を起動する

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":true}' --port 6161
```

##### customcap に `false` をセットしてノード B を起動する

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":false}' --port 6262
```

##### ノード A とマッチ

```java
ChromeOptions options = new ChromeOptions();
options.setCapability("gsg:customcap", true);
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

ノード B とマッチさせるにはカスタム capability を `false` に設定します。

#### Enabling Managed downloads by the Node

At times a test may need to access files that were downloaded by it on the Node. To retrieve such files, following can be done.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node with manage downloads enabled

```
java -jar selenium-server-<version>.jar node --enable-managed-downloads true
```

##### Set the capability at the test level

Tests that want to use this feature should set the capability `"se:downloadsEnabled"`to `true`

```java
options.setCapability("se:downloadsEnabled", true);
```

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

In the response the list of file names appear under the key `names`.

##### Dowloading a file:

* The endpoint to `POST` from is `/session/<sessionId>/se/files` with a payload of the form `{"name": "fileNameGoesHere}`
* The session needs to be active in order for the command to work.
* The raw response looks like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "Base64EncodedStringContentsOfDownloadedFileAsZipGoesHere"
  }
}
```

* The response blob contains two keys,

  * `filename` - The file name that was downloaded.
  * `contents` - Base64 encoded zipped contents of the file.

* The file contents are Base64 encoded and they need to be unzipped.

##### List files that can be downloaded

The below mentioned `curl` example can be used to list all the files that were downloaded by the current session in the Node, and which can be retrieved locally.

```bash
curl -X GET "http://localhost:4444/session/90c0149a-2e75-424d-857a-e78734943d4c/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

##### Retrieve a downloaded file

Assuming the downloaded file is named `Red-blue-green-channel.jpg`, and using `curl`, the file could be downloaded with the following command:

```bash
curl -H "Accept: application/json" \
-H "Content-Type: application/json; charset=utf-8" \
-X POST -d '{"name":"Red-blue-green-channel.jpg"}' \
"http://localhost:4444/session/18033434-fa4f-4d11-a7df-9e6d75920e19/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "UEsDBBQACAgIAJpagVYAAAAAAAAAAAAAAAAaAAAAUmVkLWJsAAAAAAAAAAAAUmVkLWJsdWUtZ3JlZW4tY2hhbm5lbC5qcGdQSwUGAAAAAAEAAQBIAAAAcNkAAAAA"
  }
}
```

##### Complete sample code in Java

Below is an example in Java that does the following:

* Sets the capability to indicate that the test requires automatic managing of downloaded files.
* Triggers a file download via a browser.
* Lists the files that are available for retrieval from the remote node (These are essentially files that were downloaded in the current session)
* Picks one file and downloads the file from the remote node to the local machine.

```java
import com.google.common.collect.ImmutableMap;

import org.openqa.selenium.By;
import org.openqa.selenium.io.Zip;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.io.File;
import java.net.URL;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import static org.openqa.selenium.remote.http.Contents.asJson;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.HttpMethod.GET;
import static org.openqa.selenium.remote.http.HttpMethod.POST;

public class DownloadsSample {

  public static void main(String[] args) throws Exception {
    // Assuming the Grid is running locally.
    URL gridUrl = new URL("http://localhost:4444");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("se:downloadsEnabled", true);
    RemoteWebDriver driver = new RemoteWebDriver(gridUrl, options);
    try {
      demoFileDownloads(driver, gridUrl);
    } finally {
      driver.quit();
    }
  }

	private static void demoFileDownloads(RemoteWebDriver driver, URL gridUrl) throws Exception {
		driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
		// Download the two available files on the page
		driver.findElement(By.id("file-1")).click();
		driver.findElement(By.id("file-2")).click();

		// The download happens in a remote Node, which makes it difficult to know when the file
		// has been completely downloaded. For demonstration purposes, this example uses a
		// 10-second sleep which should be enough time for a file to be downloaded.
		// We strongly recommend to avoid hardcoded sleeps, and ideally, to modify your
		// application under test, so it offers a way to know when the file has been completely
		// downloaded.
		TimeUnit.SECONDS.sleep(10);

		//This is the endpoint which will provide us with list of files to download and also to
		//let us download a specific file.
		String downloadsEndpoint = String.format("/session/%s/se/files", driver.getSessionId());

		String fileToDownload;

		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To list all files that are were downloaded on the remote node for the current session
			// we trigger GET request.
			HttpRequest request = new HttpRequest(GET, downloadsEndpoint);
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			@SuppressWarnings("unchecked")
			List<String> names = (List<String>) value.get("names");
			// Let's say there were "n" files downloaded for the current session, we would like
			// to retrieve ONLY the first file.
			fileToDownload = names.get(0);
		}

		// Now, let's download the file
		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To retrieve a specific file from one or more files that were downloaded by the current session
			// on a remote node, we use a POST request.
			HttpRequest request = new HttpRequest(POST, downloadsEndpoint);
			request.setContent(asJson(ImmutableMap.of("name", fileToDownload)));
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			// The returned map would contain 2 keys,
			// filename - This represents the name of the file (same as what was provided by the test)
			// contents - Base64 encoded String which contains the zipped file.
			String zippedContents = value.get("contents").toString();
			// The file contents would always be a zip file and has to be unzipped.
			File downloadDir = Zip.unzipToTempDir(zippedContents, "download", "");
			// Read the file contents
			File downloadedFile = Optional.ofNullable(downloadDir.listFiles()).orElse(new File[]{})[0];
			String fileContent = String.join("", Files.readAllLines(downloadedFile.toPath()));
			System.out.println("The file which was "
					+ "downloaded in the node is now available in the directory: "
					+ downloadDir.getAbsolutePath() + " and has the contents: " + fileContent);
		}
	}


}
```

# 4.3 - Toml オプション

```toml
[section1]
option1="value"

[section2]
option2=["value1","value2"]
option3=true
```

TOML ファイルで設定された Grid コンポーネントを起動するには以下のように起動できます:

```
java -jar selenium-server-<version>.jar <component> --config /path/to/file/<file-name>.toml
```

### スタンドアロン

ポート 4449 で動作し、新規セッションリクエストのタイムアウトが 500 秒のスタンドアロンサーバー。

```toml
[server]
port = 4449

[sessionqueue]
session-request-timeout = 500
```

### 特定のブラウザとセッションの上限

Firefox と Chrome のみがデフォルトで有効になっているスタンドアロンサーバー、またはノード

```toml
[node]
drivers = ["chrome", "firefox"]
max-sessions = 3
```

### ドライバーのカスタマイズと設定

Firefox Beta や Nightly のような、異なるブラウザのバージョンを持つことができるカスタマイズされた ドライバを用いた、スタンドアロン、またはノード。

```toml
[node]
detect-drivers = false
[[node.driver-configuration]]
max-sessions = 100
display-name = "Firefox Nightly"
stereotype = "{\"browserName\": \"firefox\", \"browserVersion\": \"93\", \"platformName\": \"MAC\", \"moz:firefoxOptions\": {\"binary\": \"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"
[[node.driver-configuration]]
display-name = "Chrome Beta"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"94\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta\"}}"
[[node.driver-configuration]]
display-name = "Chrome Dev"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"95\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev\"}}"
webdriver-executable = '/path/to/chromedriver/95/chromedriver'
```

### Docker を利用したスタンドアロン、またはノード

Docker コンテナでセッションを実行できるスタンドアロン、またはノードサーバー。 ドライバを検出を無効にし、最大 2 つの同時セッションを持ちます。 ステレオタイプは、Docker イメージにマッピングされる必要があり、 Docker デーモンが http/tcp で公開されている必要があります。 また、`devices`プロパティを用いて、ホスト上でアクセス可能なデバイスファイルを、コンテナで利用できるようにすることも可能です。 Docker デバイスをマッピングする詳しい方法は[docker](https://docs.docker.com/engine/reference/commandline/run/#add-host-device-to-container---device) を参照してください。

```toml
[node]
detect-drivers = false
max-sessions = 2

[docker]
configs = [
    "selenium/standalone-chrome:93.0", "{\"browserName\": \"chrome\", \"browserVersion\": \"91\"}",
    "selenium/standalone-firefox:92.0", "{\"browserName\": \"firefox\", \"browserVersion\": \"92\"}"
]
#Optionally define all device files that should be mapped to docker containers
#devices = [
#    "/dev/kvm:/dev/kvm"
#]
url = "http://localhost:2375"
video-image = "selenium/video:latest"
```

### WebDriver をサポートするサービスエンドポイントへのコマンド中継

WebDriver をサポートする外部サービスを Selenium Grid に接続すると便利です。 例えばクラウドプロバイダーや Appium サーバーなどです。 Grid はローカルに存在しないプラットフォームやバージョンなどを幅広くカバーできるようになります。

以下は Appium サーバーを Grid に接続する例です。

```toml
[node]
detect-drivers = false

[relay]
# Default Appium/Cloud server endpoint
url = "http://localhost:4723/wd/hub"
status-endpoint = "/status"
# Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status (e.g. HTTP/1.1, HTTP/2)
protocol-version = "HTTP/1.1"
# Stereotypes supported by the service. The initial number is "max-sessions", and will allocate
# that many test slots to that particular configuration
configs = [
  "5", "{\"browserName\": \"chrome\", \"platformName\": \"android\", \"appium:platformVersion\": \"11\"}"
]
```

### Basic 認証の有効化

ルーター、ハブ、スタンドアロンにユーザー名とパスワードを設定することで、 Basic 認証で Grid を保護することができます。 このユーザーとパスワードは、Grid UI を読み込む時や 新しいセッションを開始する時に必要になります。

```toml
[router]
username = "admin"
password = "myStrongPassword"
```

Java でユーザーとパスワードを使ってセッションを開始する方法の例です。

```java
ClientConfig clientConfig = ClientConfig.defaultConfig()
  .baseUrl(new URL("http://localhost:4444"))
  .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"));
HttpCommandExecutor executor = new HttpCommandExecutor(clientConfig);
RemoteWebDriver driver = new RemoteWebDriver(executor, new ChromeOptions());
```

In other languages, you can use the URL http\://admin:myStrongPassword\@localhost:4444

### 特定のノードにマッチするカスタム capabilities の設定

**重要**: カスタム capabilities は全てのノードで設定する必要があります。 また全てのセッションリクエストで常に含まれる必要があります。

```toml
[node]
detect-drivers = false

[[node.driver-configuration]]
display-name = "firefox"
stereotype = '{"browserName": "firefox", "platformName": "macOS", "browserVersion":"96", "networkname:applicationName":"node_1", "nodename:applicationName":"app_1" }'
max-sessions = 5
```

Java でノードにマッチさせる方法の例です。

```java
FirefoxOptions options = new FirefoxOptions();
options.setCapability("networkname:applicationName", "node_1");
options.setCapability("nodename:applicationName", "app_1");
options.setBrowserVersion("96");
options.setPlatformName("macOS");
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

### Enabling Managed downloads by the Node.

The Node can be instructed to manage downloads automatically. This will cause the Node to save all files that were downloaded for a particular session into a temp directory, which can later be retrieved from the node. To turn this capability on, use the below configuration:

```toml
[node]
enable-managed-downloads = true
```

Refer to the [CLI section](https://www.selenium.dev/ja/documentation/grid/configuration/cli_options/#enabling-managed-downloads-by-the-node) for a complete example.

# 5 - Grid アーキテクチャ

|            | イベントバス | ディストリビューター | ノード | ルーター | セッションマップ | 新規セッションキュー |
| ---------- | ------ | ---------- | --- | ---- | -------- | ---------- |
| イベントバス     | X      |            |     |      |          |            |
| ディストリビューター | ✅      | X          | ✅   |      |          | ✅          |
| ノード        | ✅      |            | X   |      |          |            |
| ルーター       |        |            | ✅   | X    | ✅        |            |
| セッションマップ   |        |            |     |      | X        |            |
| 新規セッションキュー | ✅      |            |     |      |          | X          |

| 名前                 | 型       | 概要                                                                                                                |
| ------------------ | ------- | ----------------------------------------------------------------------------------------------------------------- |
| availability       | string  | `up`, `draining`, `down` のいずれかの文字列です。重要なのは `draining` で、これはノードに新しいセッションを送らないことを示し、最後のセッションが終了するとノードは終了、または再起動します。 |
| externalUrl        | string  | Grid 内の他のコンポーネントが接続するための URI。                                                                                     |
| lastSessionCreated | integer | このノードで最後にセッションが作成された時間のエポックタイムスタンプです。ディストリビューターは、他の条件がすべて同じであれば、最も長くアイドルであったノードに新しいセッションを送信しようとします。               |
| maxSessionCount    | integer | セッション数は利用可能なスロット数をカウントすることで推測できますが、この値はノードが「満杯」とみなされるまでに、ノード上で同時に実行されるセッションの最大数を決定するために使用されます。                    |
| nodeId             | string  | ノード ID を識別する UUID です。                                                                                             |
| osInfo             | object  | `arch`, `name`, `version` フィールドを持つオブジェクトです。Grid UI と GraphQL クエリーで利用されます。                                         |
| slots              | array   | Slot オブジェクト(以下を参照)の配列。                                                                                            |
| version            | string  | ノードのバージョン(Selenium では、これは Selenium のバージョンと同じです)。                                                                  |

すべてのフィールドの値を設定することが推奨されます。

### Slot オブジェクト

Slot オブジェクトは 1 ノードでの 1 スロットを表します。 1 スロットにつき 1 セッションを実行することができます。 1 つのノードが同時に実行できる数よりも多くのスロットを持つことができます。 例えばあるノードが 10 セッションまで同時に実行でき、 それらのセッションは Chrome, Edge, Firefox のどの組み合わせでも良い時、 ノードは ‘max session count’ を 10 として、 10 の Chrome スロット、10 の Edge スロット、10 の Firefox スロットを持ちます。

| 名前          | 型      | 概要                                                                                                                                 |
| ----------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| id          | string | スロット ID。                                                                                                                           |
| lastStarted | string | スロットが最後にセッションを開始した時間。ISO-8601 フォーマット。                                                                                              |
| stereotype  | object | このスロットがマッチする最小限の[capabilities](https://w3c.github.io/webdriver/#dfn-merging-capabilities) のセット。 最小の例: `{"browserName": "firefox"}` |
| session     | object | Session オブジェクト(以下を参照)。                                                                                                             |

### Session オブジェクト

スロットで実行中のセッションを表します。

| 名前           | 型      | 概要                                                                                                                                               |
| ------------ | ------ | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| capabilities | object | セッションが持つ実際の capabilities。 The actual capabilities provided by the session. [新規セッション](https://w3c.github.io/webdriver/#new-session)コマンドの戻り値と同じです。 |
| startTime    | string | セッションが開始した時間。ISO-8601 フォーマット。                                                                                                                    |
| stereotype   | object | このスロットがマッチする最小限の[capabilities](https://w3c.github.io/webdriver/#dfn-merging-capabilities) のセット。 最小の例: `{"browserName": "firefox"}`               |
| uri          | string | ノードがセッションに接続するための URI。                                                                                                                           |

# 6 - 高度な機能

高度な機能のすべての詳細を取得し、それがどのように機能するか、および独自の設定方法を理解するには、次のセクションを参照してください。

# 6.1 - 可観測性

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar standalone --log-level FINE
```

2. Jaeger UI - OpenTelemetry は、コード内のトレースを計測するための API と SDK を提供します。一方、Jaeger はトレースのバックエンドで、トレースのテレメトリデータを収集し、データのクエリ、フィルタリング、ビジュアライズの機能を提供します。

Jaeger UI を用いたトレースの可視化の詳細な手順を確認するには、次のコマンドを実行してください:

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar info tracing
```

[非常に参考になる例と、Jaeger にトレースを送信するスクリプトです](https://github.com/manoj9788/tracing-selenium-grid)

## イベントログの活用

トレースを可視化しない場合でも、イベントロギングではトレースを有効にする必要があります。 **デフォルトでは、トレースは有効です。コンソールでログを見るために、追加のパラメータを渡す必要はありません。** スパン内のすべてのイベントは FINE レベルでログに記録されます。エラーイベントは、WARN レベルでログに記録されます。

全てのイベントは次のフィールドを持ちます:

| フィールド   | フィールド名          | 概要                                                                                                |
| ------- | --------------- | ------------------------------------------------------------------------------------------------- |
| イベント時刻  | eventId         | イベントのタイムスタンプ(エポックナノ秒)。                                                                            |
| トレース ID | tracedId        | 各トレースはトレース ID で一意に識別されます。                                                                         |
| スパン ID  | spanId          | トレース内の各スパンは、スパン ID により一意に識別されます。                                                                  |
| スパン種別   | spanKind        | スパン種別は、スパンの種類を示すスパンのプロパティです。スパンの処理の性質を識別するのに役立ちます。                                                |
| イベント名   | eventName       | ログメッセージにマッピングされます。                                                                                |
| イベント属性  | eventAttributes | イベントログの核となるもので、実行された操作に基づいて JSON フォーマットのキーと値のペアが用意されています。また、ロガークラスを表示するために、ハンドラークラスアトリビュートも含まれます。 |

サンプルログ

```
FINE [LoggingOptions$1.lambda$export$1] - {
  "traceId": "fc8aef1d44b3cc8bc09eb8e581c4a8eb",
  "spanId": "b7d3b9865d3ddd45",
  "spanKind": "INTERNAL",
  "eventTime": 1597819675128886121,
  "eventName": "Session request execution complete",
  "attributes": {
    "http.status_code": 200,
    "http.handler_class": "org.openqa.selenium.grid.router.HandleSession",
    "http.url": "\u002fsession\u002fdd35257f104bb43fdfb06242953f4c85",
    "http.method": "DELETE",
    "session.id": "dd35257f104bb43fdfb06242953f4c85"
  }
}
```

上記のフィールドに加えて、[OpenTelemetry の仕様](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/exceptions.md)に基づきエラーログは以下のフィールドで構成されます:

| フィールド    | フィールド名               | 概要                                           |
| -------- | -------------------- | -------------------------------------------- |
| 例外タイプ    | exception.type       | 例外クラス名。                                      |
| 例外メッセージ  | exception.message    | 例外の原因。                                       |
| スタックトレース | exception.stacktrace | 例外が発生した時点のコールスタックを表示します。 例外の発生源を把握するのに役立ちます。 |

サンプルエラーログ

```
WARN [LoggingOptions$1.lambda$export$1] - {
  "traceId": "7efa5ea57e02f89cdf8de586fe09f564",
  "spanId": "914df6bc9a1f6e2b",
  "spanKind": "INTERNAL",
  "eventTime": 1597820253450580272,
  "eventName": "exception",
  "attributes": {
    "exception.type": "org.openqa.selenium.ScriptTimeoutException",
    "exception.message": "Unable to execute request: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist ..." (full message will be printed),
    "exception.stacktrace": "org.openqa.selenium.ScriptTimeoutException: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist\nBuild info: version: '4.0.0-alpha-7', revision: 'Unknown'\nSystem info: host: 'XYZ-MacBook-Pro.local', ip: 'fe80:0:0:0:10d5:b63a:bdc6:1aff%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.7'\nDriver info: driver.version: unknown ...." (full stack will be printed),
    "http.handler_class": "org.openqa.selenium.grid.distributor.remote.RemoteDistributor",
    "http.url": "\u002fsession",
    "http.method": "POST"
  }
}
```

# 6.2 - GraphQLクエリのサポート

```shell
{
    session(id: "<session-id>") : {
        id,
        capabilities,
        startTime,
        uri,
        nodeId,
        nodeUri,
        sessionDurationMillis
        slot : {
            id,
            stereotype,
            lastStarted
        }
    }
    grid: {
        uri,
        totalSlots,
        nodeCount,
        maxSession,
        sessionCount,
        version,
        sessionQueueSize
    }
    sessionsInfo: {
        sessionQueueRequests,
        sessions: [
            {
                id,
                capabilities,
                startTime,
                uri,
                nodeId,
                nodeUri,
                sessionDurationMillis
                slot : {
                    id,
                    stereotype,
                    lastStarted
                }
            }
        ]
    }
    nodesInfo: {
        nodes : [
            {
                id,
                uri,
                status,
                maxSession,
                slotCount,
                sessions: [
                    {
                        id,
                        capabilities,
                        startTime,
                        uri,
                        nodeId,
                        nodeUri,
                        sessionDurationMillis
                        slot : {
                            id,
                            stereotype,
                            lastStarted
                        }
                    }
                ],
                sessionCount,
                stereotypes,
                version,
                osInfo: {
                    arch,
                    name,
                    version
                }
            }
        ]
    }
}
```

## GraphQLで照会する

GraphQLをクエリする最良の方法は、 `curl` リクエストを使用することです。 GraphQLを使用すると、必要なデータのみをフェッチできます。それ以上でもそれ以下でもありません。

GraphQLクエリの例のいくつかを以下に示します。 必要に応じて独自のクエリを作成できます。

### グリッド内の `maxSession`と` sessionCount`の数を照会する

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ grid { maxSession, sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

通常、ローカルマシンでは、 `<LINK_TO_GRAPHQL_ENDPOINT>` は `http://localhost:4444/graphql` になります。

### セッション、ノード、グリッドのすべての詳細を照会する

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { uri, maxSession, sessionCount }, nodesInfo { nodes { id, uri, status, sessions { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } }, slotCount, sessionCount }} }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### グリッドで現在のセッション数を取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### グリッドで最大セッション数を取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { maxSession } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### グリッド内のすべてのノードのすべてのセッションの詳細を取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, capabilities, startTime, uri, nodeId, nodeId, sessionDurationMillis } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### グリッド内の各ノードのすべてのセッションのスロット情報を取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, slot { id, stereotype, lastStarted } } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 特定のセッションのセッション情報を取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ session (id: \"<session-id>\") { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } } } "}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### グリッド内の各ノードのcapabilityを照会する

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { stereotypes } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### グリッド内の各ノードのステータスを照会する

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { status } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 各ノードとグリッドのURIを照会する

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { uri } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 新しいセッションキューで現在のリクエストを取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessionQueueRequests } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### 新しいセッションキューのサイズを取得するためのクエリ

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionQueueSize } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

# 6.3 - Grid エンドポイント

## Grid

### Grid ステータス

Grid ステータスは Grid の現在の状態を提供します。 登録されている全てのノードの詳細で構成されます。 各ノードのステータスには、ノードの稼働状況、セッション、およびスロットに関する情報が含まれます。

```shell
curl --request GET 'http://localhost:4444/status'
```

### セッションの削除

セッションを削除すると、WebDriver セッションが終了し、ドライバがアクティブなセッションマップから削除されます。 削除されたセッション ID を使用するリクエストや、ドライバのインスタンスを再利用しようとすると、エラーとなります。

```shell
curl --request DELETE 'http://localhost:4444/session/<session-id>'
```

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret> '
```

完全分散モードでは、ディストリビューター URL は ディストリビューターのアドレスになります。

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

Grid の設定時に登録用の secret を設定していない場合は次のようにします:

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET;'
```

### ノードのドレイン

ノードドレインコマンドはノードをグレースフルシャットダウンするために利用します。 ドレインは実行中のセッションがすべて完了した後にノードを停止します。 新規のセッションは受け付けません。

スタンドアロンモードでは、ディストリビューターの URL はスタンドアロンサーバーのアドレスとなります。

ハブ&ノードモードでは、ディストリビューターの URL は ハブのアドレスになります。

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret> '
```

完全分散モードでは、ディストリビューター URL は ディストリビューターのアドレスになります。

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

Grid の設定時に登録用の secret を設定していない場合は次のようにします:

```shell
curl --request POST 'http://<Router-URL>/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET;'
```

## ノード

この節でのエンドポイントは、ハブ&ノードモードとノードが独立して動作する完全分散型 Grid モードに適用されます。 ノードが 1 つの場合、デフォルトのノード URL は http\://localhost:5555 です。 複数のノードがある場合は、[Grid ステータス](/ja/documentation/grid/advanced_features/endpoints/#grid-%e3%82%b9%e3%83%86%e3%83%bc%e3%82%bf%e3%82%b9) を使ってすべてのノードの詳細とノードアドレスを取得してください。

### ステータス

ノードステータスは基本的にノードのヘルスチェックのためのものです。 ディストリビューターは定期的にノードの状態を ping で取得し、それに応じて Grid モデルを更新します。 ステータスには稼働状況、セッション、およびスロットに関する情報が含まれます。

```shell
curl --request GET 'http://localhost:5555/status'
```

### ドレイン

ディストリビューターは [ドレイン](/ja/documentation/grid/advanced_features/endpoints/#%e3%83%8e%e3%83%bc%e3%83%89%e3%81%ae%e3%83%89%e3%83%ac%e3%82%a4%e3%83%b3)コマンドを適切なノードに渡します。 ノードを直接ドレインするには以下の curl コマンドを使います。 どちらのエンドポイントも有効であり、同じ結果になります。 ドレインは、ノードを停止する前に進行中のセッションを終了させます。

```shell
curl --request POST 'http://localhost:5555/se/grid/node/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

Grid の設定時に登録用の secret を設定していない場合は次のようにします:

```shell
curl --request POST 'http://<node-URL>/se/grid/node/drain' --header 'X-REGISTRATION-SECRET;'
```

### セッションオーナーのチェック

あるセッションがノードに属しているかどうかをチェックするには、以下の curl コマンドを使います。

```shell
curl --request GET 'http://localhost:5555/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

Grid の設定時に登録用の secret を設定していない場合は次のようにします:

```shell
curl --request GET 'http://<node-URL>/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

もしセッションがノードに属していたら true を返し、そうでなければ false が返ります。

### セッションの削除

セッションを削除すると、WebDriver セッションが終了し、ドライバがアクティブなセッションマップから削除されます。 削除されたセッション ID を使用するリクエストや、ドライバのインスタンスを再利用しようとすると、エラーとなります。

```shell
curl --request DELETE 'http://localhost:5555/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

Grid の設定時に登録用の secret を設定していない場合は次のようにします:

```shell
curl --request DELETE 'http://<node-URL>/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

## 新規セッションキュー

### 新規セッションキューのクリア

新規セッションキューには、新規セッションリクエストが格納されます。 キューをクリアするには、以下に挙げる curl コマンドを使用します。 キューを消去すると、キューにあるすべてのリクエストを拒否します。 サーバーは各リクエストのそれぞれのクライアントにエラーレスポンスを返します。 クリアコマンドの結果は、削除されたリクエストの数です。

スタンドアロンモードでは、キューの URL はスタンドアロンサーバーのアドレスとなります。

ハブ&ノードモードでは、キューの URL は ハブのアドレスになります。

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

完全分散モードでは、キューの URL は 新規セッションキューのアドレスになります。

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

Grid の設定時に登録用の secret を設定していない場合は次のようにします:

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET;'
```

### 新規セッションリクエストの取得

新規セッションキューには、新規セッションリクエストが格納されます。 キューにある現在のリクエストを取得するには、以下に挙げる curl コマンドを使用します。 レスポンスはキュー内のリクエストの数とリクエストのペイロードを返します。

スタンドアロンモードでは、キューの URL はスタンドアロンサーバーのアドレスとなります。

ハブ&ノードモードでは、キューの URL は ハブのアドレスになります。

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

完全分散モードでは、キューの URL は 新規セッションキューのアドレスになります。

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

# 6.4 - Customizing a Node

```bash
java -jar custom_node-server.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

```bash
java -jar selenium-server-4.6.0.jar \
--ext custom_node-1.0-SNAPSHOT.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

Below is a sample that just prints some messages on to the console whenever there’s an activity of interest (session created, session deleted, a webdriver command executed etc.,) on the Node.

Sample customized node

```java
package org.seleniumhq.samples;

import java.net.URI;
import java.util.UUID;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.NoSuchSessionException;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.grid.config.Config;
import org.openqa.selenium.grid.data.CreateSessionRequest;
import org.openqa.selenium.grid.data.CreateSessionResponse;
import org.openqa.selenium.grid.data.NodeId;
import org.openqa.selenium.grid.data.NodeStatus;
import org.openqa.selenium.grid.data.Session;
import org.openqa.selenium.grid.log.LoggingOptions;
import org.openqa.selenium.grid.node.HealthCheck;
import org.openqa.selenium.grid.node.Node;
import org.openqa.selenium.grid.node.local.LocalNodeFactory;
import org.openqa.selenium.grid.security.Secret;
import org.openqa.selenium.grid.security.SecretOptions;
import org.openqa.selenium.grid.server.BaseServerOptions;
import org.openqa.selenium.internal.Either;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
import org.openqa.selenium.remote.tracing.Tracer;

public class DecoratedLoggingNode extends Node {

  private Node node;

  protected DecoratedLoggingNode(Tracer tracer, NodeId nodeId, URI uri, Secret registrationSecret, Duration sessionTimeout) {
    super(tracer, nodeId, uri, registrationSecret, sessionTimeout);
  }

  public static Node create(Config config) {
    LoggingOptions loggingOptions = new LoggingOptions(config);
    BaseServerOptions serverOptions = new BaseServerOptions(config);
    URI uri = serverOptions.getExternalUri();
    SecretOptions secretOptions = new SecretOptions(config);
    NodeOptions nodeOptions = new NodeOptions(config);
    Duration sessionTimeout = nodeOptions.getSessionTimeout();

    // Refer to the foot notes for additional context on this line.
    Node node = LocalNodeFactory.create(config);

    DecoratedLoggingNode wrapper = new DecoratedLoggingNode(loggingOptions.getTracer(),
        node.getId(),
        uri,
        secretOptions.getRegistrationSecret(),
        sessionTimeout);
    wrapper.node = node;
    return wrapper;
  }

  @Override
  public Either<WebDriverException, CreateSessionResponse> newSession(
      CreateSessionRequest sessionRequest) {
    System.out.println("Before newSession()");
    try {
      return this.node.newSession(sessionRequest);
    } finally {
      System.out.println("After newSession()");
    }
  }

  @Override
  public HttpResponse executeWebDriverCommand(HttpRequest req) {
    try {
      System.out.println("Before executeWebDriverCommand(): " + req.getUri());
      return node.executeWebDriverCommand(req);
    } finally {
      System.out.println("After executeWebDriverCommand()");
    }
  }

  @Override
  public Session getSession(SessionId id) throws NoSuchSessionException {
    try {
      System.out.println("Before getSession()");
      return node.getSession(id);
    } finally {
      System.out.println("After getSession()");
    }
  }

  @Override
  public HttpResponse uploadFile(HttpRequest req, SessionId id) {
    try {
      System.out.println("Before uploadFile()");
      return node.uploadFile(req, id);
    } finally {
      System.out.println("After uploadFile()");
    }
  }

  @Override
  public void stop(SessionId id) throws NoSuchSessionException {
    try {
      System.out.println("Before stop()");
      node.stop(id);
    } finally {
      System.out.println("After stop()");
    }
  }

  @Override
  public boolean isSessionOwner(SessionId id) {
    try {
      System.out.println("Before isSessionOwner()");
      return node.isSessionOwner(id);
    } finally {
      System.out.println("After isSessionOwner()");
    }
  }

  @Override
  public boolean isSupporting(Capabilities capabilities) {
    try {
      System.out.println("Before isSupporting");
      return node.isSupporting(capabilities);
    } finally {
      System.out.println("After isSupporting()");
    }
  }

  @Override
  public NodeStatus getStatus() {
    try {
      System.out.println("Before getStatus()");
      return node.getStatus();
    } finally {
      System.out.println("After getStatus()");
    }
  }

  @Override
  public HealthCheck getHealthCheck() {
    try {
      System.out.println("Before getHealthCheck()");
      return node.getHealthCheck();
    } finally {
      System.out.println("After getHealthCheck()");
    }
  }

  @Override
  public void drain() {
    try {
      System.out.println("Before drain()");
      node.drain();
    } finally {
      System.out.println("After drain()");
    }

  }

  @Override
  public boolean isReady() {
    try {
      System.out.println("Before isReady()");
      return node.isReady();
    } finally {
      System.out.println("After isReady()");
    }
  }
}
```

***Foot Notes:***

In the above example, the line `Node node = LocalNodeFactory.create(config);` explicitly creates a `LocalNode`.

There are basically 2 types of *user facing implementations* of `org.openqa.selenium.grid.node.Node` available.

These classes are good starting points to learn how to build a custom Node and also to learn the internals of a Node.

* `org.openqa.selenium.grid.node.local.LocalNode` - Used to represent a long running Node and is the default implementation that gets wired in when you start a `node`.

  * It can be created by calling `LocalNodeFactory.create(config);`, where:

    * `LocalNodeFactory` belongs to `org.openqa.selenium.grid.node.local`
    * `Config` belongs to `org.openqa.selenium.grid.config`

* `org.openqa.selenium.grid.node.k8s.OneShotNode` - This is a special reference implementation wherein the Node gracefully shuts itself down after servicing one test session. This class is currently not available as part of any pre-built maven artifact.

  * You can refer to the source code [here](https://github.com/SeleniumHQ/selenium/blob/trunk/java/src/org/openqa/selenium/grid/node/k8s/OneShotNode.java) to understand its internals.

  * To build it locally refer [here](https://github.com/SeleniumHQ/selenium/blob/trunk/deploys/k8s/README.md).

  * It can be created by calling `OneShotNode.create(config)`, where:

    * `OneShotNode` belongs to `org.openqa.selenium.grid.node.k8s`
    * `Config` belongs to `org.openqa.selenium.grid.config`

# 6.5 - External datastore

```sql
CREATE TABLE IF NOT EXISTS sessions_map(
    session_ids varchar(256),
    session_caps text,
    session_uri varchar(256),
    session_stereotype text,
    session_start varchar(256)
 );
```

* In the same directory as the `init.sql`, create a file named `docker-compose.yml` with its contents as below:

```yaml
version: '3.8'
services:
  db:
    image: postgres:9.6-bullseye
    restart: always
    environment:
      - POSTGRES_USER=seluser
      - POSTGRES_PASSWORD=seluser
      - POSTGRES_DB=selenium_sessions
    ports:
      - "5432:5432"
    volumes:
    - ./init.sql:/docker-entrypoint-initdb.d/init.sql
```

We can now start our database container by running:

```bash
docker-compose up -d
```

*Our database name is `selenium_sessions` with its username and password set to `seluser`*

If you are working with an already running PostGreSQL DB instance, then you just need to create a database named `selenium_sessions` and the table `sessions_map` using the above mentioned SQL statement.

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
implementation = "org.openqa.selenium.grid.sessionmap.jdbc.JdbcBackedSessionMap"
jdbc-url = "jdbc:postgresql://localhost:5432/selenium_sessions"
jdbc-user = "seluser"
jdbc-password = "seluser"
```

*Note:* If you plan to use an existing PostGreSQL DB instance, then replace `localhost:5432` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed Grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Sessions Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

```yaml
version: '3.8'
services:
  redis:
    image: redis:bullseye
    restart: always
    ports:
      - "6379:6379"
```

We can now start our Redis container by running:

```bash
docker-compose up -d
```

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
scheme = "redis"
implementation = "org.openqa.selenium.grid.sessionmap.redis.RedisBackedSessionMap"
hostname = "localhost"
port = 6379
```

*Note:* If you plan to use an existing Redis Cache instance, then replace `localhost` and `6379` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Session Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

* At this point the current directory should contain the following files:

  * `docker-compose.yml`
  * `sessions.toml`
  * `distributed.sh`

* You can now spawn the Grid by running `distributed.sh` shell script and quickly run a test. You will notice that the Grid now stores session information into the Redis instance. You can perhaps make use of a Redis GUI such as [TablePlus](https://tableplus.com/) to see them (Make sure that you have setup a debug point in your test, because the values will get deleted as soon as the test runs to completion).

In the line which spawns a `SessionMap` on a machine:

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

----
url: https://www.selenium.dev/documentation/legacy/selenium_3/grid_3/
----

# Grid 3

Selenium Grid 3 supported WebDriver without Selenium RC code. Grid 3 was completely rewritten for the new Grid 4.

You can read our documentation for more information about [Grid 4](https://www.selenium.dev/documentation/grid/)

*Selenium Grid* is a smart proxy server that allows Selenium tests to route commands to remote web browser instances. Its aim is to provide an easy way to run tests in parallel on multiple machines.

With Selenium Grid, one server acts as the hub that routes JSON formatted test commands to one or more registered Grid nodes. Tests contact the hub to obtain access to remote browser instances. The hub has a list of registered servers that it provides access to, and allows control of these instances.

Selenium Grid allows us to run tests in parallel on multiple machines, and to manage different browser versions and browser configurations centrally (instead of in each individual test).

Selenium Grid is not a silver bullet. It solves a subset of common delegation and distribution problems, but will for example not manage your infrastructure, and might not suit your specific needs.

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/browsers/safari/
----

# Safari 特定功能

这些是特定于Apple Safari浏览器的功能和特性.

与Chromium和Firefox驱动不同, safari驱动随操作系统安装. 要在 Safari 上启用自动化, 请从终端运行以下命令:

```shell
safaridriver --enable
```

## 选项

所有浏览器通用的Capabilities在[选项页](https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/options/).

Safari独有的Capabilities可以在Apple的页面[关于Safari的WebDriver](https://developer.apple.com/documentation/webkit/about_webdriver_for_safari#2957227) 上找到

使用基本定义的选项启动 Safari 会话如下所示:

*
*
*
*
*
*

```java
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#24-L25)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

```py
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L9-L10)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

```cs
            var options = new SafariOptions();
            driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/SafariTest.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/Browsers/SafariTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Safari;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("OSX")]
    public class SafariTest
    {
        private SafariDriver driver;

        [TestCleanup]
        public void QuitDriver()
        {
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new SafariOptions();
            driver = new SafariDriver(options);
        }
    }
}
```

```rb
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L8-L9)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

```js
    let driver = new Builder()
      .forBrowser(Browser.SAFARI)
      .setSafariOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/safariSpecificCap.spec.js#L8-L11)

##### /examples/javascript/test/browser/safariSpecificCap.spec.js

```js
const safari = require('selenium-webdriver/safari');
const {Browser, Builder} = require("selenium-webdriver");
const options = new safari.Options();
const process  =  require('node:process');

describe('Should be able to Test Command line arguments', function () {
  (process.platform === 'darwin' ? it : it.skip)('safari caps', async function () {
    let driver = new Builder()
      .forBrowser(Browser.SAFARI)
      .setSafariOptions(options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
val options = SafariOptions()
val driver = SafariDriver(options)
```

### 移动端

那些希望在iOS上自动化Safari的人可以参考 [Appium 项目](/zh-cn/).

## 服务

所有浏览器通用的服务设置在 [服务页面](https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/service/).

### 日志

与其他浏览器不同, Safari 浏览器不允许您选择日志的输出位置或更改级别. 一个可用选项是关闭或打开日志. 如果日志处于打开状态， 则可以在以下位置找到它们: `~/Library/Logs/com.apple.WebDriver/`.

```java
                .withLogging(true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

**注意**: Java也允许使用环境变量进行设置;\
属性键: `SafariDriverService.SAFARI_DRIVER_LOGGING`\
属性值: `"true"` 或 `"false"`

[Selenium v4.26](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.26.0)

```py
    service = webdriver.SafariService(enable_logging=True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L17)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L20)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## Safari Technology Preview

Apple 提供了其浏览器的开发版本 — [Safari Technology Preview](https://developer.apple.com/safari/technology-preview/)

在代码中使用此版本:

*
*
*
*
*
*

```java
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#L39-L40)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

```py
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L25-L30)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L38-L39)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

----
url: https://www.selenium.dev/documentation/webdriver/bidi/
----

```java
options.setCapability("webSocketUrl", true);
```

```python
options.enable_bidi = True
```

```csharp
UseWebSocketUrl = true,
```

```ruby
options.web_socket_url = true
```

```javascript
Options().enableBidi();
```

```kotlin
options.setCapability("webSocketUrl", true);
```

This enables the WebSocket connection for bidirectional communication, unlocking the full potential of the WebDriver BiDi protocol.

Note that Selenium is updating its entire implementation from WebDriver Classic to WebDriver BiDi (while maintaining backwards compatibility as much as possible), but this section of documentation focuses on the new functionality that bidirectional communication allows. The low-level BiDi domains will be accessible in the code to the end user, but the goal is to provide high-level APIs that are straightforward methods of real-world use cases. As such, the low-level components will not be documented, and this section will focus only on the user-friendly features that we encourage users to take advantage of.

If there is additional functionality you’d like to see, please raise a [feature request](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=\&template=feature.md).

***

##### [WebDriver BiDi Logging Features](/documentation/webdriver/bidi/logging/)

These features are related to logging. Because “logging” can refer to so many different things, these methods are made available via a “script” namespace.

##### [WebDriver BiDi Network Features](/documentation/webdriver/bidi/network/)

These features are related to networking, and are made available via a “network” namespace.

##### [WebDriver BiDi Script Features](/documentation/webdriver/bidi/script/)

These features are related to scripts, and are made available via a “script” namespace.

##### [Chrome DevTools Protocol](/documentation/webdriver/bidi/cdp/)

Examples of working with Chrome DevTools Protocol in Selenium. CDP support is temporary until WebDriver BiDi has been implemented.

##### [BiDirectional API (W3C compliant)](/documentation/webdriver/bidi/w3c/)

Examples of working with Chrome DevTools Protocol in Selenium. CDP support is temporary until WebDriver BiDi has been implemented.

Last modified September 26, 2024: [added python example for enabling BiDi (#1965) (cb40aec6caf)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/cb40aec6caf8fa666077e3e047f6c2d1a194df83)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/elements/information/
----

# 关于网络元素的信息

```java
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L27-L29)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L12-L15)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L18-L22)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    displayed_value = driver.find_element(name: 'email_input').displayed?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L12)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L16-L17)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//returns true if element is displayed else returns false
val flag = driver.findElement(By.name("email_input")).isDisplayed()
```

```java
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L32-L34)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L19)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L25-L27)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    enabled_value = driver.find_element(name: 'email_input').enabled?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L17)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L23-L24)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//returns true if element is enabled else returns false
val attr = driver.findElement(By.name("button_input")).isEnabled()
```

```java
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L37-L39)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L23)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
  from selenium.webdriver.common.by import By
  
  import pytest
  
  
  def test_informarion():
      # Initialize WebDriver
      driver = webdriver.Chrome()
      driver.implicitly_wait(0.5)
  
      driver.get("https://www.selenium.dev/selenium/web/inputs.html")
  
      # isDisplayed
      is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
      assert is_email_visible == True
  
      # isEnabled
      is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
      assert is_enabled_button == True
  
      # isSelected
      is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
      assert is_selected_check == True
  
      # TagName
      tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
      assert tag_name_inp == "input"
  
      # GetRect
      rect = driver.find_element(By.NAME, "range_input").rect
      assert rect["x"] == 10
  
      # CSS Value
      css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
          "font-size"
      )
      assert css_value == "13.3333px"
  
      # GetText
      text = driver.find_element(By.TAG_NAME, "h1").text
      assert text == "Testing Inputs"
  
      # FetchAttributes
      email_txt = driver.find_element(By.NAME, "email_input")
      value_info = email_txt.get_attribute("value")
      assert value_info == "admin@localhost"
  
```

```cs
            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L30-L32)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    selected_value = driver.find_element(name: 'email_input').selected?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L22)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L30-L31)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//returns true if element is checked else returns false
val attr =  driver.findElement(By.name("checkbox_input")).isSelected()
```

```java
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L42-L44)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L27)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L35-L37)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    tag_name = driver.find_element(name: 'email_input').tag_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L27)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L37-L38)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
//navigates to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//returns TagName of the element 
val attr =  driver.findElement(By.name("email_input")).getTagName()
```

```java
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L47-L50)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    rect = driver.find_element(By.NAME, "range_input").rect
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L31)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L40-L43)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    size = driver.find_element(name: 'email_input').size
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L32)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    let object = await driver.findElement(By.name('range_input')).getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L45)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

// Returns height, width, x and y coordinates referenced element
val res = driver.findElement(By.name("range_input")).rect

// Rectangle class provides getX,getY, getWidth, getHeight methods
println(res.getX())
```

```java
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L52-L54)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L35-L37)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L49-L50)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L38)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L76-L78)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to Url
driver.get("https://www.selenium.dev/selenium/web/colorPage.html")

// Retrieves the computed style property 'color' of linktext
val cssValue = driver.findElement(By.id("namedColor")).getCssValue("background-color")
```

```java
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L58-L60)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    text = driver.find_element(By.TAG_NAME, "h1").text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L41)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L53-L55)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    text = driver.find_element(xpath: '//h1').text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L43)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L84-L86)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to URL
driver.get("https://www.selenium.dev/selenium/web/linked_image.html")

// retrieves the text of the element
val text = driver.findElement(By.id("justanotherlink")).getText()
```

```java
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L64-L68)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L44-L46)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L58-L62)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L48)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L55-L59)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to URL
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//fetch the value property associated with the textbox
val attr = driver.findElement(By.name("email_input")).getAttribute("value")
```

最后修改 April 17, 2026: [Update code block references in documentation (#2613) (5d614fcd479)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/5d614fcd479d384003f8e4dd949f6a9f4cada711)

----
url: https://www.selenium.dev/documentation/webdriver/interactions/alerts/
----

# JavaScript alerts, prompts and confirmations

```java

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L36-L41)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L12-L18)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See an example alert")).Click();

//Wait for the alert to be displayed and store it in a variable
IAlert alert = wait.Until(ExpectedConditions.AlertIsPresent());

//Store the alert text in a variable
string text = alert.Text;

//Press the OK button
alert.Accept();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L15-L22)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L19-L21)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See an example alert")).click()

//Wait for the alert to be displayed and store it in a variable
val alert = wait.until(ExpectedConditions.alertIsPresent())

//Store the alert text in a variable
val text = alert.getText()

//Press the OK button
alert.accept()
  
```

```java
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L131-L138)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L26-L32)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See a sample confirm")).Click();

//Wait for the alert to be displayed
wait.Until(ExpectedConditions.AlertIsPresent());

//Store the alert in a variable
IAlert alert = driver.SwitchTo().Alert();

//Store the alert in a variable for reuse
string text = alert.Text;

//Press the Cancel button
alert.Dismiss();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L28-L35)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L30-L32)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See a sample confirm")).click()

//Wait for the alert to be displayed
wait.until(ExpectedConditions.alertIsPresent())

//Store the alert in a variable
val alert = driver.switchTo().alert()

//Store the alert in a variable for reuse
val text = alert.text

//Press the Cancel button
alert.dismiss()
  
```

```java
        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L79-L84)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L40-L47)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

//Click the link to activate the alert driver.FindElement(By.LinkText("See a sample prompt")).Click(); //Wait for the alert to be displayed and store it in a variable IAlert alert = wait.Until(ExpectedConditions.AlertIsPresent()); //Type your message alert.SendKeys("Selenium"); //Press the OK button alert.Accept();

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L41-L48)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L42-L45)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

//Click the link to activate the alert driver.findElement(By.linkText("See a sample prompt")).click() //Wait for the alert to be displayed and store it in a variable val alert = wait.until(ExpectedConditions.alertIsPresent()) //Type your message alert.sendKeys("Selenium") //Press the OK button alert.accept()

Last modified August 14, 2025: [Fixing path for code block (c7fcb0099f5)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/c7fcb0099f58ba4d4dd467a8c6667f6130749d82)

----
url: https://www.selenium.dev/zh-cn/documentation/legacy/selenium_3/grid_components/
----

# 服务网格的组件

----
url: https://www.selenium.dev/ja/_print/documentation/overview/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/overview/).

# 概要

Seleniumはあなたに適していますか？さまざまなプロジェクトのコンポーネントの概要を参照してください。

* 1: [コンポーネントを理解する](#pg-af0ab4bb41cb2aa49a31860949be4638)
* 2: [Selenium 詳細](#pg-4b41eaabcff09a9eb8cfbcae6abd814e)

# 1 - コンポーネントを理解する

# 2 - Selenium 詳細

----
url: https://www.selenium.dev/documentation/webdriver/support_features/
----

# Support features

Support classes provide optional higher level features.

The core libraries of Selenium try to be low level and non-opinionated. The Support classes in each language provide opinionated wrappers for common interactions that may be used to simplify some behaviors.

***

##### [Waiting with Expected Conditions](/documentation/webdriver/support_features/expected_conditions/)

These are classes used to describe what needs to be waited for.

##### [Command Listeners](/documentation/webdriver/support_features/listeners/)

##### [Working With Colors](/documentation/webdriver/support_features/colors/)

##### [Working with select list elements](/documentation/webdriver/support_features/select_lists/)

Select lists have special behaviors compared to other elements.

##### [ThreadGuard](/documentation/webdriver/support_features/thread_guard/)

----
url: https://www.selenium.dev/ja/documentation/webdriver/drivers/http_client/
----

# HTTPクライアントの設定

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import org.openqa.selenium.remote.http.ClientConfig;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import java.io.FileInputStream;
import java.net.URL;
import java.nio.file.Path;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.time.Duration;

import org.openqa.selenium.UsernameAndPassword;

import static java.net.http.HttpClient.Version.HTTP_1_1;

public class HttpClientTest extends BaseTest {
    URL gridUrl;

    @BeforeEach
    public void startGrid() {
        gridUrl = startStandaloneGridAdvanced();
    }

    @Test
    public void remoteWebDriverWithClientConfig() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createSSLContextWithCA(Path.of("src/test/resources/tls.crt").toAbsolutePath().toString()))
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
    }

    @Test
    public void remoteWebDriverIgnoreSSL() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createIgnoreSSLContext())
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
    }

    @Test
    public void remoteWebDriverWithEmbedAuthUrl() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createSSLContextWithCA(Path.of("src/test/resources/tls.crt").toAbsolutePath().toString()))
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(embedAuthToUrl(gridUrl, "admin", "myStrongPassword"))
                .config(clientConfig)
                .build();
    }

    private URL embedAuthToUrl(URL url, String username, String password) throws Exception {
        String userInfo = username + ":" + password;
        String urlWithAuth = url.getProtocol() + "://" + userInfo + "@" + url.getHost() + ":" + url.getPort() + url.getPath();
        return new URL(urlWithAuth);
    }

    public static SSLContext createSSLContextWithCA(String caCertPath) throws Exception {
        FileInputStream fis = new FileInputStream(caCertPath);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate caCert = (X509Certificate) cf.generateCertificate(fis);
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, null);
        keyStore.setCertificateEntry("caCert", caCert);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(keyStore);
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);
        return sslContext;
    }

    public static SSLContext createIgnoreSSLContext() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    }
                }
        };
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
        return sslContext;
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/HttpClientTest.java)

```py
import os
import pytest
import sys
from urllib3.util import Retry, Timeout
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType
from selenium.webdriver.remote.client_config import ClientConfig


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_with_client_config(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    retries = Retry(connect=2, read=2, redirect=2)
    timeout = Timeout(connect=300, read=3600)
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 init_args_for_pool_manager={
                                     "init_args_for_pool_manager": {"retries": retries, "timeout": timeout}},
                                 ca_certs=_get_resource_path("tls.crt"),
                                 username="admin", password="myStrongPassword")
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_ignore_certs(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 timeout=3600,
                                 ignore_certificates=True,
                                 username="admin", password="myStrongPassword")
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


def _get_resource_path(file_name: str):
    if os.path.abspath("").endswith("tests"):
        path = os.path.abspath(f"resources/{file_name}")
    else:
        path = os.path.abspath(f"tests/resources/{file_name}")
    return path

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_http_client.py)

[Add Example](/documentation/about/contributing/#creating-examples)

```rb

  it 'sets client configuration' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/http_client_spec.rb#L7-L8)

##### /examples/ruby/spec/drivers/http\_client\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'HTTP Client' do
  let(:url) { 'https://www.selenium.dev/selenium/web/' }

  it 'sets client configuration' do
    client = Selenium::WebDriver::Remote::Http::Default.new(open_timeout: 30, read_timeout: 30)
    expect(client.open_timeout).to eq 30
  end

  it 'uses the custom http client' do
    client = Selenium::WebDriver::Remote::Http::Default.new
    driver = Selenium::WebDriver.for :chrome, http_client: client
    driver.get(url)
    driver.quit
  end
end
```

----
url: https://www.selenium.dev/zh-cn/documentation/grid/
----

# Grid

要在多台计算机上并行运行测试吗? 那么, Grid正是为你准备的.

Selenium Grid 允许通过将客户端发送的命令路由到远程浏览器实例来在远程机器上执行 WebDriver 脚本。

Grid 的目标:

* 提供一种在多台机器上并行运行测试的简单方法
* 允许在不同的浏览器版本上进行测试
* 启用跨平台测试

感兴趣? 通过以下部分了解Grid的工作原理, 以及如何设置自己的.

***

##### [Selenium Grid快速起步](/zh-cn/documentation/grid/getting_started/)

一步一步地说明如何运行简单的Selenium Grid.

##### [什么时候应该使用Grid](/zh-cn/documentation/grid/applicability/)

Grid适合您吗?

##### [服务网格的组件](/zh-cn/documentation/grid/components/)

检查不同的Grid组件以了解如何使用它们.

##### [配置组件](/zh-cn/documentation/grid/configuration/)

在这里，您可以看到如何根据公共配置值和特定于组件的配置值分别配置每个网格组件.

##### [Grid架构](/zh-cn/documentation/grid/architecture/)

##### [高级功能](/zh-cn/documentation/grid/advanced_features/)

要获得高级功能的所有详细信息, 了解其工作原理, 以及如何设置自己的功能, 请浏览以下部分.

最后修改 February 6, 2024: [Grid as 4 in the index (f414b1ef8f2)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/f414b1ef8f2f4d0412a75fe8ca059786be95b0c0)

----
url: https://www.selenium.dev/ja/documentation/test_practices/encouraged/mock_external_services/
----

# モック外部サービス

外部サービスへの依存を排除すると、テストの速度と安定性が大幅に向上します。

----
url: https://www.selenium.dev/pt-br/_print/documentation/webdriver/actions_api/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/webdriver/actions_api/).

# Ações API

Uma interface de baixo nível para fornecer ações de entrada de dispositivo virtualizadas para o navegador da web..

* 1: [Ações de Teclado](#pg-1c9313f3574da39b3fc06f00f554e1df)
* 2: [Ações do Mouse](#pg-3826b702b93bc29599384a35cb0cc848)
* 3: [Ações de Caneta](#pg-b6ed3d48b71ca80ea0e3c360a8c28310)
* 4: [Ações de Roda de Rolagem](#pg-ade8d51f0a3ca3a88b1b692892d10ad4)

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/ActionsTest.java#L21-L28)

##### /examples/java/src/test/java/dev/selenium/actions\_api/ActionsTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;

public class ActionsTest extends BaseChromeTest {
    @Test
    public void pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        long start = System.currentTimeMillis();

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();

        long duration = System.currentTimeMillis() - start;
        Assertions.assertTrue(duration > 2000);
        Assertions.assertTrue(duration < 3000);
    }

    @Test
    public void releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        Actions actions = new Actions(driver);
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        ((RemoteWebDriver) driver).resetInputState();

        actions.sendKeys("a").perform();
        Assertions.assertEquals("A", String.valueOf(clickable.getAttribute("value").charAt(0)));
        Assertions.assertEquals("a", String.valueOf(clickable.getAttribute("value").charAt(1)));
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_actions.py#L13-L20)

##### /examples/python/tests/actions\_api/test\_actions.py

```py
from time import time

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.by import By


def test_pauses(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    start = time()

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()

    duration = time() - start
    assert duration > 2
    assert duration < 3


def test_releases_all(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .click_and_hold(clickable)\
        .key_down(Keys.SHIFT)\
        .key_down("a")\
        .perform()

    ActionBuilder(driver).clear_actions()

    ActionChains(driver).key_down('a').perform()

    assert clickable.get_attribute('value')[0] == "A"
    assert clickable.get_attribute('value')[1] == "a"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs#L18-L25)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class ActionsTest : BaseChromeTest
    {
        [TestMethod]
        public void Pause()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            DateTime start = DateTime.Now;

            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();

            TimeSpan duration = DateTime.Now - start;
            Assert.IsTrue(duration > TimeSpan.FromSeconds(2));
            Assert.IsTrue(duration < TimeSpan.FromSeconds(3));
        }

        [TestMethod]
        public void ReleaseAll()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            var actions = new Actions(driver);
            actions.ClickAndHold(clickable)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            ((WebDriver)driver).ResetInputState();

            actions.SendKeys("a").Perform();
            var value = clickable.GetAttribute("value");
            Assert.AreEqual("A", value[..1]);
            Assert.AreEqual("a", value.Substring(1, 1));
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/actions_spec.rb#L12-L19)

##### /examples/ruby/spec/actions\_api/actions\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Actions' do
  let(:driver) { start_session }

  it 'pauses' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
    start = Time.now

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform

    duration = Time.now - start
    expect(duration).to be > 2
    expect(duration).to be < 3
  end

  it 'releases all' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    action = driver.action
                   .click_and_hold(clickable)
                   .key_down(:shift)
                   .key_down('a')
    action.perform

    driver.action.release_actions

    action.key_down('a').perform
    expect(clickable.attribute('value')[0]).to eq 'A'
    expect(clickable.attribute('value')[-1]).to eq 'a'
  end
end
```

```js
    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/actionsTest.spec.js#L18-L25)

##### /examples/javascript/test/actionsApi/actionsTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Pause and Release All Actions', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('Pause', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const start = Date.now()

    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()

    const end = Date.now() - start
    assert.ok(end > 2000)
    assert.ok(end < 4000)
  })

  it('Clear', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const clickable = driver.findElement(By.id('clickable'))
    await driver.actions()
      .click(clickable)
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    await driver.actions().clear()
    await driver.actions().sendKeys('a').perform()

    const value = await clickable.getAttribute('value')
    assert.deepStrictEqual('A', value.substring(0, 1))
    assert.deepStrictEqual('a', value.substring(1, 2))
  })
})
```

```kt
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/ActionsTest.kt#L22-L29)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/ActionsTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration

class ActionsTest : BaseTest() {

    @Test
    fun pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val start = System.currentTimeMillis()

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 

        val duration = System.currentTimeMillis() - start
        Assertions.assertTrue(duration > 2000)
        Assertions.assertTrue(duration < 4000)
    }

    @Test
    fun releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        val actions = Actions(driver)
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        (driver as RemoteWebDriver).resetInputState()

        actions.sendKeys("a").perform()
        Assertions.assertEquals("A", clickable.getAttribute("value")!!.get(0).toString())
        Assertions.assertEquals("a", clickable.getAttribute("value")!!.get(1).toString())
    }
}
```

```java
        ((RemoteWebDriver) driver).resetInputState();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/ActionsTest.java#L46)

##### /examples/java/src/test/java/dev/selenium/actions\_api/ActionsTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;

public class ActionsTest extends BaseChromeTest {
    @Test
    public void pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        long start = System.currentTimeMillis();

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .moveToElement(clickable)
                .pause(Duration.ofSeconds(1))
                .clickAndHold()
                .pause(Duration.ofSeconds(1))
                .sendKeys("abc")
                .perform();

        long duration = System.currentTimeMillis() - start;
        Assertions.assertTrue(duration > 2000);
        Assertions.assertTrue(duration < 3000);
    }

    @Test
    public void releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        Actions actions = new Actions(driver);
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        ((RemoteWebDriver) driver).resetInputState();

        actions.sendKeys("a").perform();
        Assertions.assertEquals("A", String.valueOf(clickable.getAttribute("value").charAt(0)));
        Assertions.assertEquals("a", String.valueOf(clickable.getAttribute("value").charAt(1)));
    }
}
```

```py
    ActionBuilder(driver).clear_actions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_actions.py#L37)

##### /examples/python/tests/actions\_api/test\_actions.py

```py
from time import time

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.by import By


def test_pauses(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    start = time()

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .move_to_element(clickable)\
        .pause(1)\
        .click_and_hold()\
        .pause(1)\
        .send_keys("abc")\
        .perform()

    duration = time() - start
    assert duration > 2
    assert duration < 3


def test_releases_all(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver)\
        .click_and_hold(clickable)\
        .key_down(Keys.SHIFT)\
        .key_down("a")\
        .perform()

    ActionBuilder(driver).clear_actions()

    ActionChains(driver).key_down('a').perform()

    assert clickable.get_attribute('value')[0] == "A"
    assert clickable.get_attribute('value')[1] == "a"
```

```cs
            ((WebDriver)driver).ResetInputState();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs#L44)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/ActionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class ActionsTest : BaseChromeTest
    {
        [TestMethod]
        public void Pause()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            DateTime start = DateTime.Now;

            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .MoveToElement(clickable)
                .Pause(TimeSpan.FromSeconds(1))
                .ClickAndHold()
                .Pause(TimeSpan.FromSeconds(1))
                .SendKeys("abc")
                .Perform();

            TimeSpan duration = DateTime.Now - start;
            Assert.IsTrue(duration > TimeSpan.FromSeconds(2));
            Assert.IsTrue(duration < TimeSpan.FromSeconds(3));
        }

        [TestMethod]
        public void ReleaseAll()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            var actions = new Actions(driver);
            actions.ClickAndHold(clickable)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            ((WebDriver)driver).ResetInputState();

            actions.SendKeys("a").Perform();
            var value = clickable.GetAttribute("value");
            Assert.AreEqual("A", value[..1]);
            Assert.AreEqual("a", value.Substring(1, 1));
        }
    }
}
```

```rb
    driver.action.release_actions
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/actions_spec.rb#L36)

##### /examples/ruby/spec/actions\_api/actions\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Actions' do
  let(:driver) { start_session }

  it 'pauses' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
    start = Time.now

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .move_to(clickable)
          .pause(duration: 1)
          .click_and_hold
          .pause(duration: 1)
          .send_keys('abc')
          .perform

    duration = Time.now - start
    expect(duration).to be > 2
    expect(duration).to be < 3
  end

  it 'releases all' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    action = driver.action
                   .click_and_hold(clickable)
                   .key_down(:shift)
                   .key_down('a')
    action.perform

    driver.action.release_actions

    action.key_down('a').perform
    expect(clickable.attribute('value')[0]).to eq 'A'
    expect(clickable.attribute('value')[-1]).to eq 'a'
  end
end
```

```js
    await driver.actions().clear()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/actionsTest.spec.js#L42)

##### /examples/javascript/test/actionsApi/actionsTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Pause and Release All Actions', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('Pause', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const start = Date.now()

    const clickable = await driver.findElement(By.id('clickable'))
    await driver.actions()
      .move({ origin: clickable })
      .pause(1000)
      .press()
      .pause(1000)
      .sendKeys('abc')
      .perform()

    const end = Date.now() - start
    assert.ok(end > 2000)
    assert.ok(end < 4000)
  })

  it('Clear', async function() {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    const clickable = driver.findElement(By.id('clickable'))
    await driver.actions()
      .click(clickable)
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    await driver.actions().clear()
    await driver.actions().sendKeys('a').perform()

    const value = await clickable.getAttribute('value')
    assert.deepStrictEqual('A', value.substring(0, 1))
    assert.deepStrictEqual('a', value.substring(1, 2))
  })
})
```

```kt
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/ActionsTest.kt#L47)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/ActionsTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.Keys
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration

class ActionsTest : BaseTest() {

    @Test
    fun pause() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val start = System.currentTimeMillis()

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
            .moveToElement(clickable)
            .pause(Duration.ofSeconds(1))
            .clickAndHold()
            .pause(Duration.ofSeconds(1))
            .sendKeys("abc")
            .perform() 

        val duration = System.currentTimeMillis() - start
        Assertions.assertTrue(duration > 2000)
        Assertions.assertTrue(duration < 4000)
    }

    @Test
    fun releasesAll() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        val actions = Actions(driver)
        actions.clickAndHold(clickable)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        (driver as RemoteWebDriver).resetInputState()

        actions.sendKeys("a").perform()
        Assertions.assertEquals("A", clickable.getAttribute("value")!!.get(0).toString())
        Assertions.assertEquals("a", clickable.getAttribute("value")!!.get(1).toString())
    }
}
```

# 1 - Ações de Teclado

```java
        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L17-L20)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L10-L13)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L13-L16)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L17-L20)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L19-L22)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L30-L35)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L21-L26)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L30-L35)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L25-L30)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L32-L37)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L32-L37)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .sendKeys("abc")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L45-L47)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    ActionChains(driver)\
        .send_keys("abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L34-L36)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs

            new Actions(driver)
                .SendKeys("abc")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L45-L47)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .send_keys('abc')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L39-L41)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    await driver.actions()
      .sendKeys('abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L48-L50)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
                .sendKeys("abc")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L47-L49)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L59-L62)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L45-L48)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L58-L61)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L51-L54)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L59-L63)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L60-L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

```java
        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/KeysTest.java#L70-L84)

##### /examples/java/src/test/java/dev/selenium/actions\_api/KeysTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Keys;
import org.openqa.selenium.Platform;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;

public class KeysTest extends BaseChromeTest {
    @Test
    public void keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("A", textField.getAttribute("value"));
    }

    @Test
    public void keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("Ab", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        new Actions(driver)
                .sendKeys("abc")
                .perform();

        WebElement textField = driver.findElement(By.id("textInput"));
        Assertions.assertEquals("abc", textField.getAttribute("value"));
    }

    @Test
    public void sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");
        driver.findElement(By.tagName("body")).click();

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform();

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"));
    }

    @Test
    public void copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html");

        Keys cmdCtrl = Platform.getCurrent().is(Platform.MAC) ? Keys.COMMAND : Keys.CONTROL;

        WebElement textField = driver.findElement(By.id("textInput"));
        new Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform();

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"));
    }
}
```

```py
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_keys.py#L56-L67)

##### /examples/python/tests/actions\_api/test\_keys.py

```py
import sys

from selenium.webdriver import Keys, ActionChains
from selenium.webdriver.common.by import By


def test_key_down(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "ABC"


def test_key_up(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .key_down(Keys.SHIFT)\
        .send_keys("a")\
        .key_up(Keys.SHIFT)\
        .send_keys("b")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "Ab"


def test_send_keys_to_active_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')

    ActionChains(driver)\
        .send_keys("abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_send_keys_to_designated_element(driver):
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    driver.find_element(By.TAG_NAME, "body").click()

    text_input = driver.find_element(By.ID, "textInput")
    ActionChains(driver)\
        .send_keys_to_element(text_input, "abc")\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "abc"


def test_copy_and_paste(firefox_driver):
    driver = firefox_driver
    driver.get('https://selenium.dev/selenium/web/single_text_input.html')
    cmd_ctrl = Keys.COMMAND if sys.platform == 'darwin' else Keys.CONTROL

    ActionChains(driver)\
        .send_keys("Selenium!")\
        .send_keys(Keys.ARROW_LEFT)\
        .key_down(Keys.SHIFT)\
        .send_keys(Keys.ARROW_UP)\
        .key_up(Keys.SHIFT)\
        .key_down(cmd_ctrl)\
        .send_keys("xvv")\
        .key_up(cmd_ctrl)\
        .perform()

    assert driver.find_element(By.ID, "textInput").get_attribute('value') == "SeleniumSelenium!"
```

```cs

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs#L72-L82)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/KeysTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class KeysTest : BaseFirefoxTest
    {
        [TestMethod]
        public void KeyDown()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("A", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void KeyUp()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .KeyDown(Keys.Shift)
                .SendKeys("a")
                .KeyUp(Keys.Shift)
                .SendKeys("b")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("Ab", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToActiveElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            new Actions(driver)
                .SendKeys("abc")
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }
        
        [TestMethod]
        public void SendKeysToDesignatedElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";
            driver.FindElement(By.TagName("body")).Click();
            
            IWebElement textField = driver.FindElement(By.Id("textInput"));
            new Actions(driver)
                .SendKeys(textField, "abc")
                .Perform();

            Assert.AreEqual("abc", textField.GetAttribute("value"));
        }

        [TestMethod]
        public void CopyAndPaste()
        {
            driver.Url = "https://selenium.dev/selenium/web/single_text_input.html";

            var capabilities = ((WebDriver)driver).Capabilities;
            String platformName = (string)capabilities.GetCapability("platformName");

            String cmdCtrl = platformName.Contains("mac") ? Keys.Command : Keys.Control;

            new Actions(driver)
                .SendKeys("Selenium!")
                .SendKeys(Keys.ArrowLeft)
                .KeyDown(Keys.Shift)
                .SendKeys(Keys.ArrowUp)
                .KeyUp(Keys.Shift)
                .KeyDown(cmdCtrl)
                .SendKeys("xvv")
                .KeyUp(cmdCtrl)
                .Perform();

            IWebElement textField = driver.FindElement(By.Id("textInput"));
            Assert.AreEqual("SeleniumSelenium!", textField.GetAttribute("value"));
        }
    }
}
```

```rb
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/keys_spec.rb#L64-L74)

##### /examples/ruby/spec/actions\_api/keys\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Keys' do
  let(:driver) { start_session }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }

  it 'key down' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'A'
  end

  it 'key up' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .key_down(:shift)
          .send_keys('a')
          .key_up(:shift)
          .send_keys('b')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'Ab'
  end

  it 'sends keys to active element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    driver.action
          .send_keys('abc')
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'abc'
  end

  it 'sends keys to designated element' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    driver.find_element(tag_name: 'body').click
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    text_field = driver.find_element(id: 'textInput')
    driver.action
          .send_keys(text_field, 'Selenium!')
          .perform

    expect(text_field.attribute('value')).to eq 'Selenium!'
  end

  it 'copy and paste' do
    driver.get 'https://www.selenium.dev/selenium/web/single_text_input.html'
    wait.until { driver.find_element(id: 'textInput').attribute('autofocus') }

    cmd_ctrl = driver.capabilities.platform_name.include?('mac') ? :command : :control
    driver.action
          .send_keys('Selenium!')
          .send_keys(:arrow_left)
          .key_down(:shift)
          .send_keys(:arrow_up)
          .key_up(:shift)
          .key_down(cmd_ctrl)
          .send_keys('xvv')
          .key_up(cmd_ctrl)
          .perform

    expect(driver.find_element(id: 'textInput').attribute('value')).to eq 'SeleniumSelenium!'
  end
end
```

```js
    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/keysTest.spec.js#L73-L85)

##### /examples/javascript/test/actionsApi/keysTest.spec.js

```js
const { By, Key, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')
const { platform } = require('node:process')

describe('Keyboard Action - Keys test', function() {
  let driver

  before(async function() {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async () => await driver.quit())

  it('KeyDown', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .perform()

    const textField = driver.findElement(By.id('textInput'))
    assert.deepStrictEqual(await textField.getAttribute('value'), 'A')
  })

  it('KeyUp', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .keyDown(Key.SHIFT)
      .sendKeys('a')
      .keyUp(Key.SHIFT)
      .sendKeys('b')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'Ab')
  })

  it('sendKeys', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = driver.findElement(By.id('textInput'))
    await textField.click()

    await driver.actions()
      .sendKeys('abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Designated Element', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    await driver.findElement(By.css('body')).click()
    const textField = await driver.findElement(By.id('textInput'))

    await driver.actions()
      .sendKeys(textField, 'abc')
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'abc')
  })

  it('Copy and Paste', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/single_text_input.html')

    const textField = await driver.findElement(By.id('textInput'))

    const cmdCtrl = platform.includes('darwin') ? Key.COMMAND : Key.CONTROL

    await driver.actions()
      .click(textField)
      .sendKeys('Selenium!')
      .sendKeys(Key.ARROW_LEFT)
      .keyDown(Key.SHIFT)
      .sendKeys(Key.ARROW_UP)
      .keyUp(Key.SHIFT)
      .keyDown(cmdCtrl)
      .sendKeys('xvv')
      .keyUp(cmdCtrl)
      .perform()

    assert.deepStrictEqual(await textField.getAttribute('value'), 'SeleniumSelenium!')
  })
})
```

```kt

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/KeysTest.kt#L74-L86)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/KeysTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.HasCapabilities
import org.openqa.selenium.Keys
import org.openqa.selenium.Platform
import org.openqa.selenium.interactions.Actions

class KeysTest : BaseTest() {

    @Test
    fun keyDown() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("A", textField.getAttribute("value"))
    }

    @Test
    fun keyUp() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .keyDown(Keys.SHIFT)
                .sendKeys("a")
                .keyUp(Keys.SHIFT)
                .sendKeys("b")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("Ab", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToActiveElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        Actions(driver)
                .sendKeys("abc")
                .perform()

        val textField = driver.findElement(By.id("textInput"))
        Assertions.assertEquals("abc", textField.getAttribute("value"))
    }

    @Test
    fun sendKeysToDesignatedElement() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")
        driver.findElement(By.tagName("body")).click()

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .perform()

        Assertions.assertEquals("Selenium!", textField.getAttribute("value"))
    }

    @Test
    fun copyAndPaste() {
        driver.get("https://www.selenium.dev/selenium/web/single_text_input.html")

        val platformName = (driver as HasCapabilities).getCapabilities().getPlatformName()

        val cmdCtrl = if(platformName == Platform.MAC) Keys.COMMAND else Keys.CONTROL

        val textField = driver.findElement(By.id("textInput"))
        Actions(driver)
                .sendKeys(textField, "Selenium!")
                .sendKeys(Keys.ARROW_LEFT)
                .keyDown(Keys.SHIFT)
                .sendKeys(Keys.ARROW_UP)
                .keyUp(Keys.SHIFT)
                .keyDown(cmdCtrl)
                .sendKeys("xvv")
                .keyUp(cmdCtrl)
                .perform()

        Assertions.assertEquals("SeleniumSelenium!", textField.getAttribute("value"))
    }
}
```

# 2 - Ações do Mouse

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L22-L25)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L14-L17)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L11-L14)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    let clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.move({origin: clickable}).press().perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/clickAndHold.spec.js#L14-L16)

##### /examples/javascript/test/actionsApi/mouse/clickAndHold.spec.js

```js
const {By, Builder} = require('selenium-webdriver');

describe('Click and hold', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and mouseDown on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    let clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.move({origin: clickable}).press().perform();
  });
});
```

```kt
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L23-L26)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L34-L37)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L26-L29)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L30-L33)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L22-L25)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    let click = driver.findElement(By.id("click"));
    const actions = driver.actions({async: true});
    await actions.move({origin: click}).click().perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/clickAndRelease.spec.js#L14-L16)

##### /examples/javascript/test/actionsApi/mouse/clickAndRelease.spec.js

```js
const {By,Builder} = require('selenium-webdriver');

describe('Click and release', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    let click = driver.findElement(By.id("click"));
    const actions = driver.actions({async: true});
    await actions.move({origin: click}).click().perform();
  });
});
```

```kt
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L35-L38)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L46-L49)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L37-L40)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L43-L46)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L34-L37)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.contextClick(clickable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/rightClick.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/rightClick.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Right click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move and right click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.contextClick(clickable).perform();

    await driver.sleep(500);
    const clicked = await driver.findElement(By.id('click-status')).getText();
    assert.deepStrictEqual(clicked, `context-clicked`)
  });
});
```

```kt
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L47-L50)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L60-L66)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L51-L54)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L59-L63)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L47-L50)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js#L19-L20)

##### /examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js

```js
const {By, Button, Browser, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Should be able to perform BACK click and FORWARD click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Back click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)

    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)
  });

  it('Forward click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();
    await driver.navigate().back();

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)

    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L61-L67)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L78-L84)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L65-L68)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L77-L81)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L61-L64)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

[Selenium v4.5.0](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0.0)

```js
    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js#L32-L33)

##### /examples/javascript/test/actionsApi/mouse/backAndForwardClick.spec.js

```js
const {By, Button, Browser, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Should be able to perform BACK click and FORWARD click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Back click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)

    const actions = driver.actions({async: true});
    await actions.press(Button.BACK).release(Button.BACK).perform()

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)
  });

  it('Forward click', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    await driver.findElement(By.id("click")).click();
    await driver.navigate().back();

    assert.deepStrictEqual(await driver.getTitle(), `BasicMouseInterfaceTest`)

    const actions = driver.actions({async: true});
    await actions.press(Button.FORWARD).release(Button.FORWARD).perform()

    assert.deepStrictEqual(await driver.getTitle(), `We Arrive Here`)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L79-L85)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L93-L96)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L76-L79)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L91-L94)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L73-L76)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.doubleClick(clickable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/doubleClick.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/doubleClick.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Double click', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Double-click on an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const clickable = driver.findElement(By.id("clickable"));
    const actions = driver.actions({async: true});
    await actions.doubleClick(clickable).perform();

    await driver.sleep(500);
    const status = await driver.findElement(By.id('click-status')).getText();
    assert.deepStrictEqual(status, `double-clicked`)
  });
});
```

```kt
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L94-L97)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L105-L108)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L87-L90)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L104-L107)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L84-L87)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const hoverable = driver.findElement(By.id("hover"));
    const actions = driver.actions({async: true});
    await actions.move({origin: hoverable}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveToElement.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/moveToElement.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Move to element', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('Mouse move into an element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const hoverable = driver.findElement(By.id("hover"));
    const actions = driver.actions({async: true});
    await actions.move({origin: hoverable}).perform();

    const status = await driver.findElement(By.id('move-status')).getText();
    assert.deepStrictEqual(status, `hovered`)
  });
});
```

```kt
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L106-L109)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L118-L121)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L98-L101)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L132-L135)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L97-L100)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L15-L17)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L119-L122)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L131-L136)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L110-L112)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L146-L150)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      driver.action
            .move_to_location(8, 12)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L114-L116)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L27-L28)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L132-L137)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L153-L155)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L126-L128)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L167-L169)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
      driver.action
            .move_by(13, 15)
            .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L128-L130)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js#L40)

##### /examples/javascript/test/actionsApi/mouse/moveByOffset.spec.js

```js
const {By, Origin, Builder, until } = require('selenium-webdriver');
const assert = require('assert');

describe('Mouse move by offset', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('From element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const mouseTracker = driver.findElement(By.id("mouse-tracker"));
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0, origin: mouseTracker}).perform();

    await driver.wait(until.elementTextContains(await driver.findElement(By.id('relative-location')), ","), 2000);
    let result = await driver.findElement(By.id('relative-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 100 - 8) < 2), true)
  });

  it('From viewport origin', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 8, y: 0}).perform();

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual((Math.abs(parseInt(result[0]) - 8) < 2), true)
  });

  it('From current pointer location', async function () {
    await driver.get('https://selenium.dev/selenium/web/mouse_interaction.html');
    const actions = driver.actions({async: true});
    await actions.move({x: 6, y: 3}).perform()

    await actions.move({x: 13, y: 15, origin: Origin.POINTER}).perform()

    let result = await driver.findElement(By.id('absolute-location')).getText();
    result = result.split(', ');
    assert.deepStrictEqual(Math.abs(parseInt(result[0]) - 6 - 13) < 2, true)
    assert.deepStrictEqual(Math.abs(parseInt(result[1]) - 3 - 15) < 2, true)
  });
});
```

```kt
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L154-L156)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L166-L170)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L139-L143)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L181-L185)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L141-L145)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js#L27-L30)

##### /examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Drag and Drop', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('By Offset', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });

  it('Onto Element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });
});
```

```kt
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L167-L171)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

```java
        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/MouseTest.java#L179-L184)

##### /examples/java/src/test/java/dev/selenium/actions\_api/MouseTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Collections;

public class MouseTest extends BaseChromeTest {
    @Test
    public void clickAndHold() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .clickAndHold(clickable)
                .perform();

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("click"));
        new Actions(driver)
                .click(clickable)
                .perform();

        Assertions.assertTrue(driver.getCurrentUrl().contains("resultPage.html"));
    }

    @Test
    public void rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .contextClick(clickable)
                .perform();

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle());
    }

    @Test
    public void forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.findElement(By.id("click")).click();
        driver.navigate().back();
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        Assertions.assertEquals("We Arrive Here", driver.getTitle());
    }

    @Test
    public void doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement clickable = driver.findElement(By.id("clickable"));
        new Actions(driver)
                .doubleClick(clickable)
                .perform();

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText());
    }

    @Test
    public void hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement hoverable = driver.findElement(By.id("hover"));
        new Actions(driver)
                .moveToElement(hoverable)
                .perform();

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText());
    }

    @Test
    public void moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");
        driver.manage().window().fullscreen();

        WebElement tracker = driver.findElement(By.id("mouse-tracker"));
        new Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform();

        String[] result = driver.findElement(By.id("relative-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2);
    }

    @Test
    public void moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2);
    }

    @Test
    public void moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        PointerInput mouse = new PointerInput(PointerInput.Kind.MOUSE, "default mouse");

        Sequence actions = new Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11));
        ((RemoteWebDriver) driver).perform(Collections.singletonList(actions));

        new Actions(driver)
                .moveByOffset(13, 15)
                .perform();

        String[] result = driver.findElement(By.id("absolute-location")).getText().split(", ");
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2);
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2);
    }

    @Test
    public void dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        WebElement droppable = driver.findElement(By.id("droppable"));
        new Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }

    @Test
    public void dragsByOffset() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html");

        WebElement draggable = driver.findElement(By.id("draggable"));
        Rectangle start = draggable.getRect();
        Rectangle finish = driver.findElement(By.id("droppable")).getRect();
        new Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform();

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText());
    }
}
```

```py
    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_mouse.py#L151-L156)

##### /examples/python/tests/actions\_api/test\_mouse.py

```py
import pytest
from time import sleep
from selenium.webdriver import ActionChains
from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.mouse_button import MouseButton
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC


def test_click_and_hold(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .click_and_hold(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "focused"


def test_click_and_release(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "click")
    ActionChains(driver) \
        .click(clickable) \
        .perform()

    assert "resultPage.html" in driver.current_url


def test_right_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .context_click(clickable) \
        .perform()

    sleep(0.5)
    assert driver.find_element(By.ID, "click-status").text == "context-clicked"


def test_back_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    assert driver.title == "We Arrive Here"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.BACK)
    action.pointer_action.pointer_up(MouseButton.BACK)
    action.perform()

    assert driver.title == "BasicMouseInterfaceTest"


def test_forward_click_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    driver.find_element(By.ID, "click").click()
    driver.back()
    assert driver.title == "BasicMouseInterfaceTest"

    action = ActionBuilder(driver)
    action.pointer_action.pointer_down(MouseButton.FORWARD)
    action.pointer_action.pointer_up(MouseButton.FORWARD)
    action.perform()

    assert driver.title == "We Arrive Here"


def test_double_click(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    clickable = driver.find_element(By.ID, "clickable")
    ActionChains(driver) \
        .double_click(clickable) \
        .perform()

    assert driver.find_element(By.ID, "click-status").text == "double-clicked"


def test_hover(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    hoverable = driver.find_element(By.ID, "hover")
    ActionChains(driver) \
        .move_to_element(hoverable) \
        .perform()

    assert driver.find_element(By.ID, "move-status").text == "hovered"


def test_move_by_offset_from_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    mouse_tracker = driver.find_element(By.ID, "mouse-tracker")
    ActionChains(driver) \
        .move_to_element_with_offset(mouse_tracker, 8, 0) \
        .perform()

    coordinates = driver.find_element(By.ID, "relative-location").text.split(", ")
    assert abs(int(coordinates[0]) - 100 - 8) < 2


def test_move_by_offset_from_viewport_origin_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')
    WebDriverWait(driver, 10).until(EC.presence_of_element_located((By.ID, "absolute-location")))
    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(8, 0)
    action.perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 8) < 2


def test_move_by_offset_from_current_pointer_ab(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    action = ActionBuilder(driver)
    action.pointer_action.move_to_location(6, 3)
    action.perform()

    ActionChains(driver) \
        .move_by_offset(13, 15) \
        .perform()

    coordinates = driver.find_element(By.ID, "absolute-location").text.split(", ")

    assert abs(int(coordinates[0]) - 6 - 13) < 2
    assert abs(int(coordinates[1]) - 3 - 15) < 2


def test_drag_and_drop_onto_element(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    droppable = driver.find_element(By.ID, "droppable")
    ActionChains(driver) \
        .drag_and_drop(draggable, droppable) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"


def test_drag_and_drop_by_offset(driver):
    driver.get('https://selenium.dev/selenium/web/mouse_interaction.html')

    draggable = driver.find_element(By.ID, "draggable")
    start = draggable.location
    finish = driver.find_element(By.ID, "droppable").location
    ActionChains(driver) \
        .drag_and_drop_by_offset(draggable, finish['x'] - start['x'], finish['y'] - start['y']) \
        .perform()

    assert driver.find_element(By.ID, "drop-status").text == "dropped"
```

```cs
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs#L195-L200)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/MouseTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class MouseTest : BaseChromeTest
    {
        [TestMethod]
        public void ClickAndHold()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ClickAndHold(clickable)
                .Perform();
            
            Assert.AreEqual("focused", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void ClickAndRelease()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("click"));
            new Actions(driver)
                .Click(clickable)
                .Perform();
            
            Assert.IsTrue(driver.Url.Contains("resultPage.html"));
        }

        [TestMethod]
        public void RightClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .ContextClick(clickable)
                .Perform();
            
            Assert.AreEqual("context-clicked", driver.FindElement(By.Id("click-status")).Text);
        }
        
        [TestMethod]
        public void BackClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            Assert.AreEqual("We Arrive Here", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Back));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Back));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);
        }

        [TestMethod]
        public void ForwardClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            driver.FindElement(By.Id("click")).Click();
            driver.Navigate().Back();
            Assert.AreEqual("BasicMouseInterfaceTest", driver.Title);

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerDown(MouseButton.Forward));
            actionBuilder.AddAction(mouse.CreatePointerUp(MouseButton.Forward));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            Assert.AreEqual("We Arrive Here", driver.Title);
        }

        [TestMethod]
        public void DoubleClick()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement clickable = driver.FindElement(By.Id("clickable"));
            new Actions(driver)
                .DoubleClick(clickable)
                .Perform();
            
            Assert.AreEqual("double-clicked", driver.FindElement(By.Id("click-status")).Text);
        }

        [TestMethod]
        public void Hovers()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement hoverable = driver.FindElement(By.Id("hover"));
            new Actions(driver)
                .MoveToElement(hoverable)
                .Perform();
            
            Assert.AreEqual("hovered", driver.FindElement(By.Id("move-status")).Text);
        }

        [TestMethod]
        [Obsolete("Obsolete")]
        public void MoveByOffsetFromTopLeftOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCenterOfElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement tracker = driver.FindElement(By.Id("mouse-tracker"));
            new Actions(driver)
                .MoveToElement(tracker, 8, 0)
                .Perform();

            string[] result = driver.FindElement(By.Id("relative-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 100 - 8) < 2);
        }
        
        [TestMethod]
        public void MoveByOffsetFromViewport()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 0, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8) < 2);
        }

        [TestMethod]
        public void MoveByOffsetFromCurrentPointerLocation()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";

            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice mouse = new PointerInputDevice(PointerKind.Mouse, "default mouse");
            actionBuilder.AddAction(mouse.CreatePointerMove(CoordinateOrigin.Viewport,
                8, 12, TimeSpan.Zero));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            new Actions(driver)
                .MoveByOffset(13, 15)
                .Perform();

            string[] result = driver.FindElement(By.Id("absolute-location")).Text.Split(", ");
            Assert.IsTrue(Math.Abs(int.Parse(result[0]) - 8 - 13) < 2);
            Assert.IsTrue(Math.Abs(int.Parse(result[1]) - 12 - 15) < 2);
        }

        [TestMethod]
        public void DragToElement()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            IWebElement droppable = driver.FindElement(By.Id("droppable"));
            new Actions(driver)
                .DragAndDrop(draggable, droppable)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }

        [TestMethod]
        public void DragByOffset()
        {
            driver.Url = "https://selenium.dev/selenium/web/mouse_interaction.html";
            
            IWebElement draggable = driver.FindElement(By.Id("draggable"));
            Point start = draggable.Location;
            Point finish = driver.FindElement(By.Id("droppable")).Location;
            new Actions(driver)
                .DragAndDropToOffset(draggable, finish.X - start.X, finish.Y - start.Y)
                .Perform();
            
            Assert.AreEqual("dropped", driver.FindElement(By.Id("drop-status")).Text);
        }
    }
}
```

```rb
    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/mouse_spec.rb#L153-L158)

##### /examples/ruby/spec/actions\_api/mouse\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Mouse' do
  let(:driver) { start_session }

  it 'click and hold' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .click_and_hold(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'focused'
  end

  it 'click and release' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'click')
    driver.action
          .click(clickable)
          .perform

    expect(driver.current_url).to include 'resultPage.html'
  end

  describe 'alternate button clicks' do
    it 'right click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      clickable = driver.find_element(id: 'clickable')
      driver.action
            .context_click(clickable)
            .perform

      expect(driver.find_element(id: 'click-status').text).to eq 'context-clicked'
    end

    it 'back click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      expect(driver.title).to eq('We Arrive Here')

      driver.action
            .pointer_down(:back)
            .pointer_up(:back)
            .perform

      expect(driver.title).to eq('BasicMouseInterfaceTest')
    end

    it 'forward click' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.find_element(id: 'click').click
      driver.navigate.back
      expect(driver.title).to eq('BasicMouseInterfaceTest')

      driver.action
            .pointer_down(:forward)
            .pointer_up(:forward)
            .perform

      expect(driver.title).to eq('We Arrive Here')
    end
  end

  it 'double click' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    clickable = driver.find_element(id: 'clickable')
    driver.action
          .double_click(clickable)
          .perform

    expect(driver.find_element(id: 'click-status').text).to eq 'double-clicked'
  end

  it 'hovers' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    hoverable = driver.find_element(id: 'hover')
    driver.action
          .move_to(hoverable)
          .perform

    expect(driver.find_element(id: 'move-status').text).to eq 'hovered'
  end

  describe 'move by offset' do
    it 'offset from element' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'
      driver.action.scroll_to(driver.find_element(id: 'bottom')).perform

      mouse_tracker = driver.find_element(id: 'mouse-tracker')
      driver.action
            .move_to(mouse_tracker, 8, 11)
            .perform

      rect = mouse_tracker.rect
      center_x = rect.width / 2
      center_y = rect.height / 2
      x_coord, y_coord = driver.find_element(id: 'relative-location').text.split(',').map(&:to_i)

      expect(x_coord).to be_within(1).of(center_x + 8)
      expect(y_coord).to be_within(1).of(center_y + 11)
    end

    it 'offset from viewport', {platforn: :linux, reason: 'it only fails on the linux pipeline'} do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action
            .move_to_location(8, 12)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8)
      expect(y_coord).to be_within(1).of(12)
    end

    it 'offset from current pointer location' do
      driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

      driver.action.move_to_location(8, 11).perform

      driver.action
            .move_by(13, 15)
            .perform

      x_coord, y_coord = driver.find_element(id: 'absolute-location').text.split(',').map(&:to_i)
      expect(x_coord).to be_within(1).of(8 + 13)
      expect(y_coord).to be_within(1).of(11 + 15)
    end
  end

  it 'drags to another element' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    droppable = driver.find_element(id: 'droppable')
    driver.action
          .drag_and_drop(draggable, droppable)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end

  it 'drags by an offset' do
    driver.get 'https://www.selenium.dev/selenium/web/mouse_interaction.html'

    draggable = driver.find_element(id: 'draggable')
    start = draggable.rect
    finish = driver.find_element(id: 'droppable').rect
    driver.action
          .drag_and_drop_by(draggable, finish.x - start.x, finish.y - start.y)
          .perform

    expect(driver.find_element(id: 'drop-status').text).to include('dropped')
  end
end
```

```js
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js#L15-L19)

##### /examples/javascript/test/actionsApi/mouse/dragAndDrop.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require('assert');

describe('Drag and Drop', function () {
  let driver;

  before(async function () {
    driver = new Builder().forBrowser('chrome').build();
  });

  after(async () => await driver.quit());

  it('By Offset', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    let start = await draggable.getRect();
    let finish = await driver.findElement(By.id("droppable")).getRect();
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, {x: finish.x - start.x, y: finish.y - start.y}).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });

  it('Onto Element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/mouse_interaction.html');
    const draggable = driver.findElement(By.id("draggable"));
    const droppable = await driver.findElement(By.id("droppable"));
    const actions = driver.actions({async: true});
    await actions.dragAndDrop(draggable, droppable).perform();

    let result = await driver.findElement(By.id("drop-status")).getText();
    assert.deepStrictEqual('dropped', result)
  });
});
```

```kt
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/MouseTest.kt#L180-L185)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/MouseTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import java.time.Duration
import java.util.Collections

class MouseTest : BaseTest() {
        
    @Test
    fun clickAndHold() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .clickAndHold(clickable)
                .perform()

        Assertions.assertEquals("focused", driver.findElement(By.id("click-status")).getText())
    } 

    @Test
    fun clickAndRelease() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("click"))
        Actions(driver)
                .click(clickable)
                .perform()

        Assertions.assertTrue(driver.getCurrentUrl()!!.contains("resultPage.html"))
    }
  
    @Test
    fun rightClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .contextClick(clickable)
                .perform()

        Assertions.assertEquals("context-clicked", driver.findElement(By.id("click-status")).getText())
    }
      
    @Test
    fun backClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        Assertions.assertEquals(driver.getTitle(), "We Arrive Here")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.BACK.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.BACK.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("BasicMouseInterfaceTest", driver.getTitle())
    }
     
    @Test
    fun forwardClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.findElement(By.id("click")).click()
        driver.navigate().back()
        Assertions.assertEquals(driver.getTitle(), "BasicMouseInterfaceTest")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerDown(PointerInput.MouseButton.FORWARD.asArg()))
                .addAction(mouse.createPointerUp(PointerInput.MouseButton.FORWARD.asArg()))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Assertions.assertEquals("We Arrive Here", driver.getTitle())
    }
 
    @Test
    fun doubleClick() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val clickable = driver.findElement(By.id("clickable"))
        Actions(driver)
                .doubleClick(clickable)
                .perform()

        Assertions.assertEquals("double-clicked", driver.findElement(By.id("click-status")).getText())
    }

    @Test
    fun hovers() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val hoverable = driver.findElement(By.id("hover"))
        Actions(driver)
                .moveToElement(hoverable)
                .perform()

        Assertions.assertEquals("hovered", driver.findElement(By.id("move-status")).getText())
    }

    @Test
    fun moveByOffsetFromElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")
        driver.manage().window().fullscreen()

        val tracker = driver.findElement(By.id("mouse-tracker"))
        Actions(driver)
                .moveToElement(tracker, 8, 0)
                .perform()

        val result = driver.findElement(By.id("relative-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 100 - 8) < 2)
    }

    @Test
    fun moveByOffsetFromViewport() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 12))

        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ")
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 12) < 2)
    }

    @Test
    fun moveByOffsetFromCurrentPointer() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val mouse = PointerInput(PointerInput.Kind.MOUSE, "default mouse")

        val actions = Sequence(mouse, 0)
                .addAction(mouse.createPointerMove(Duration.ZERO, PointerInput.Origin.viewport(), 8, 11))
        (driver as RemoteWebDriver).perform(Collections.singletonList(actions))

        Actions(driver)
                .moveByOffset(13, 15)
                .perform()

        val result = driver.findElement(By.id("absolute-location")).getText().split(", ") 
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[0]) - 8 - 13) < 2)
        Assertions.assertTrue(Math.abs(Integer.parseInt(result[1]) - 11 - 15) < 2)
    }
    
    @Test
    fun dragsToElement() {
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val droppable = driver.findElement(By.id("droppable"))
        Actions(driver)
                .dragAndDrop(draggable, droppable)
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
        
    @Test
    fun dragsByOffset() { 
        driver.get("https://www.selenium.dev/selenium/web/mouse_interaction.html")

        val draggable = driver.findElement(By.id("draggable"))
        val start = draggable.getRect()
        val finish = driver.findElement(By.id("droppable")).getRect()
        Actions(driver)
                .dragAndDropBy(draggable, finish.getX() - start.getX(), finish.getY() - start.getY())
                .perform()

        Assertions.assertEquals("dropped", driver.findElement(By.id("drop-status")).getText())
    }
}
```

# 3 - Ações de Caneta

```java
        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/PenTest.java#L26-L33)

##### /examples/java/src/test/java/dev/selenium/actions\_api/PenTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PenTest extends BaseChromeTest {
    @Test
    public void usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();

        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    @Test
    public void setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();
        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("-72", moveBy.get("tiltX"));
        Assertions.assertEquals("9", moveBy.get("tiltY"));
        Assertions.assertEquals("86", moveBy.get("twist"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    private Map<String, String> getPropertyInfo(WebElement element) {
        String text = element.getText();
        text = text.substring(text.indexOf(' ') + 1);

        return Arrays.stream(text.split(", "))
                .map(s -> s.split(": "))
                .collect(Collectors.toMap(
                        a -> a[0],
                        a -> a[1]
                ));
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```py
    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_pen.py#L12-L20)

##### /examples/python/tests/actions\_api/test\_pen.py

```py
import math

from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.interaction import POINTER_PEN
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.by import By


def test_use_pen(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def test_set_pointer_event_properties(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert move_by["tiltX"] == "-72"
    assert move_by["tiltY"] == "9"
    assert move_by["twist"] == "86"
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def properties(element):
    kv = element.text.split(' ', 1)[1].split(', ')
    return {x[0]:x[1] for x in list(map(lambda item: item.split(': '), kv))}
```

```cs
            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs#L19-L28)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class PenTest : BaseChromeTest
    {
        [TestMethod]
        public void UsePen()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        [TestMethod]
        public void SetPointerEventProperties()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual((-72).ToString(), moveBy["tiltX"]);
            Assert.AreEqual((9).ToString(), moveBy["tiltY"]);
            Assert.AreEqual((86).ToString(), moveBy["twist"]);
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        private Dictionary<string, string> getProperties(IWebElement element)
        {
            var str = element.Text;
            str = str[(str.Split()[0].Length + 1)..];
            IEnumerable<string[]> keyValue = str.Split(", ").Select(part => part.Split(":"));
            return keyValue.ToDictionary(split => split[0].Trim(), split => split[1].Trim());
        }

        private bool VerifyEquivalent(decimal expected, string actual)
        {
            var absolute = Math.Abs(expected - decimal.Parse(actual));
            if (absolute <= 1)
            {
                return true;
            }

            throw new Exception("Expected: " + expected + "; but received: " + actual);
        }
    }
}
```

[Selenium v4.2](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.2.0)

```rb
    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/pen_spec.rb#L11-L17)

##### /examples/ruby/spec/actions\_api/pen\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Pen' do
  let(:driver) { start_session }

  it 'uses a pen' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  it 'sets pointer event attributes' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s,
                               'tiltX' => -72.to_s,
                               'tiltY' => 9.to_s,
                               'twist' => 86.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  def properties(element)
    element.text.sub(/.*?\s/, '').split(',').to_h { |item| item.lstrip.split(/\s*:\s*/) }
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/PenTest.kt#L23-L30)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/PenTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import kotlin.collections.Map
import java.time.Duration

class PenTest : BaseTest() {
  
    @Test
    fun usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
    }

    @Test
    fun setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY")) 
	    
        Assertions.assertEquals("-72", moveBy.get("tiltX"))
        Assertions.assertEquals("9", moveBy.get("tiltY"))
        Assertions.assertEquals("86", moveBy.get("twist"))
    }
    
    fun getPropertyInfo(element: WebElement): Map<String, String> {
        var text = element.getText()  
        text = text.substring(text.indexOf(" ")+1)
        return text.split(", ")
        .map { it.split(": ") }
        .map { it.first() to it.last() }
        .toMap() 
    }
}
```

```java
        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/PenTest.java#L67-L81)

##### /examples/java/src/test/java/dev/selenium/actions\_api/PenTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.PointerInput;
import org.openqa.selenium.interactions.Sequence;
import org.openqa.selenium.remote.RemoteWebDriver;

import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class PenTest extends BaseChromeTest {
    @Test
    public void usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        new Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform();

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();

        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    @Test
    public void setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html");

        WebElement pointerArea = driver.findElement(By.id("pointerArea"));
        PointerInput pen = new PointerInput(PointerInput.Kind.PEN, "default pen");
        PointerInput.PointerEventProperties eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86);
        PointerInput.Origin origin = PointerInput.Origin.fromElement(pointerArea);

        Sequence actionListPen = new Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0));

        ((RemoteWebDriver) driver).perform(Collections.singletonList(actionListPen));

        List<WebElement> moves = driver.findElements(By.className("pointermove"));
        Map<String, String> moveTo = getPropertyInfo(moves.get(0));
        Map<String, String> down = getPropertyInfo(driver.findElement(By.className("pointerdown")));
        Map<String, String> moveBy = getPropertyInfo(moves.get(1));
        Map<String, String> up = getPropertyInfo(driver.findElement(By.className("pointerup")));

        Rectangle rect = pointerArea.getRect();
        int centerX = (int) Math.floor(rect.width / 2 + rect.getX());
        int centerY = (int) Math.floor(rect.height / 2 + rect.getY());
        Assertions.assertEquals("-1", moveTo.get("button"));
        Assertions.assertEquals("pen", moveTo.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), moveTo.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), moveTo.get("pageY"));
        Assertions.assertEquals("0", down.get("button"));
        Assertions.assertEquals("pen", down.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX), down.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY), down.get("pageY"));
        Assertions.assertEquals("-1", moveBy.get("button"));
        Assertions.assertEquals("pen", moveBy.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), moveBy.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), moveBy.get("pageY"));
        Assertions.assertEquals("-72", moveBy.get("tiltX"));
        Assertions.assertEquals("9", moveBy.get("tiltY"));
        Assertions.assertEquals("86", moveBy.get("twist"));
        Assertions.assertEquals("0", up.get("button"));
        Assertions.assertEquals("pen", up.get("pointerType"));
        Assertions.assertEquals(String.valueOf(centerX + 2), up.get("pageX"));
        Assertions.assertEquals(String.valueOf(centerY + 2), up.get("pageY"));
    }

    private Map<String, String> getPropertyInfo(WebElement element) {
        String text = element.getText();
        text = text.substring(text.indexOf(' ') + 1);

        return Arrays.stream(text.split(", "))
                .map(s -> s.split(": "))
                .collect(Collectors.toMap(
                        a -> a[0],
                        a -> a[1]
                ));
    }
}
```

```py
    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_pen.py#L53-L61)

##### /examples/python/tests/actions\_api/test\_pen.py

```py
import math

from selenium.webdriver.common.actions.action_builder import ActionBuilder
from selenium.webdriver.common.actions.interaction import POINTER_PEN
from selenium.webdriver.common.actions.pointer_input import PointerInput
from selenium.webdriver.common.by import By


def test_use_pen(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2)\
        .pointer_up()
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def test_set_pointer_event_properties(driver):
    driver.get('https://www.selenium.dev/selenium/web/pointerActionsPage.html')

    pointer_area = driver.find_element(By.ID, "pointerArea")
    pen_input = PointerInput(POINTER_PEN, "default pen")
    action = ActionBuilder(driver, mouse=pen_input)
    action.pointer_action\
        .move_to(pointer_area)\
        .pointer_down()\
        .move_by(2, 2, tilt_x=-72, tilt_y=9, twist=86)\
        .pointer_up(0)
    action.perform()

    moves = driver.find_elements(By.CLASS_NAME, "pointermove")
    move_to = properties(moves[0])
    down = properties(driver.find_element(By.CLASS_NAME, "pointerdown"))
    move_by = properties(moves[1])
    up = properties(driver.find_element(By.CLASS_NAME, "pointerup"))

    rect = pointer_area.rect
    center_x = rect["x"] + rect["width"] / 2
    center_y = rect["y"] + rect["height"] / 2

    assert move_to["button"] == "-1"
    assert move_to["pointerType"] == "pen"
    assert move_to["pageX"] == str(math.floor(center_x))
    assert move_to["pageY"] == str(math.floor(center_y))
    assert down["button"] == "0"
    assert down["pointerType"] == "pen"
    assert down["pageX"] == str(math.floor(center_x))
    assert down["pageY"] == str(math.floor(center_y))
    assert move_by["button"] == "-1"
    assert move_by["pointerType"] == "pen"
    assert move_by["pageX"] == str(math.floor(center_x + 2))
    assert move_by["pageY"] == str(math.floor(center_y + 2))
    assert move_by["tiltX"] == "-72"
    assert move_by["tiltY"] == "9"
    assert move_by["twist"] == "86"
    assert up["button"] == "0"
    assert up["pointerType"] == "pen"
    assert up["pageX"] == str(math.floor(center_x + 2))
    assert up["pageY"] == str(math.floor(center_y + 2))


def properties(element):
    kv = element.text.split(' ', 1)[1].split(', ')
    return {x[0]:x[1] for x in list(map(lambda item: item.split(': '), kv))}
```

```cs
            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs#L64-L77)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/PenTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class PenTest : BaseChromeTest
    {
        [TestMethod]
        public void UsePen()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());

            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        [TestMethod]
        public void SetPointerEventProperties()
        {
            driver.Url = "https://selenium.dev/selenium/web/pointerActionsPage.html";

            IWebElement pointerArea = driver.FindElement(By.Id("pointerArea"));
            ActionBuilder actionBuilder = new ActionBuilder();
            PointerInputDevice pen = new PointerInputDevice(PointerKind.Pen, "default pen");
            PointerInputDevice.PointerEventProperties properties = new PointerInputDevice.PointerEventProperties() {
                TiltX = -72,
                TiltY = 9,
                Twist = 86,
            };            
            actionBuilder.AddAction(pen.CreatePointerMove(pointerArea, 0, 0, TimeSpan.FromMilliseconds(800)));
            actionBuilder.AddAction(pen.CreatePointerDown(MouseButton.Left));
            actionBuilder.AddAction(pen.CreatePointerMove(CoordinateOrigin.Pointer,
                2, 2, TimeSpan.Zero, properties));
            actionBuilder.AddAction(pen.CreatePointerUp(MouseButton.Left));
            ((IActionExecutor)driver).PerformActions(actionBuilder.ToActionSequenceList());
            
            var moves = driver.FindElements(By.ClassName("pointermove"));
            var moveTo = getProperties(moves.ElementAt(0));
            var down = getProperties(driver.FindElement(By.ClassName("pointerdown")));
            var moveBy = getProperties(moves.ElementAt(1));
            var up = getProperties(driver.FindElement(By.ClassName("pointerup")));

            Point location = pointerArea.Location;
            Size size = pointerArea.Size;
            decimal centerX = location.X + size.Width / 2;
            decimal centerY = location.Y + size.Height / 2;

            Assert.AreEqual("-1", moveTo["button"]);
            Assert.AreEqual("pen", moveTo["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, moveTo["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, moveTo["pageY"]));
            Assert.AreEqual("0", down["button"]);
            Assert.AreEqual("pen", down["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX, down["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY, down["pageY"]));
            Assert.AreEqual("-1", moveBy["button"]);
            Assert.AreEqual("pen", moveBy["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, moveBy["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, moveBy["pageY"]));
            Assert.AreEqual((-72).ToString(), moveBy["tiltX"]);
            Assert.AreEqual((9).ToString(), moveBy["tiltY"]);
            Assert.AreEqual((86).ToString(), moveBy["twist"]);
            Assert.AreEqual("0", up["button"]);
            Assert.AreEqual("pen", up["pointerType"]);
            Assert.IsTrue(VerifyEquivalent(centerX + 2, up["pageX"]));
            Assert.IsTrue(VerifyEquivalent(centerY + 2, up["pageY"]));
        }

        private Dictionary<string, string> getProperties(IWebElement element)
        {
            var str = element.Text;
            str = str[(str.Split()[0].Length + 1)..];
            IEnumerable<string[]> keyValue = str.Split(", ").Select(part => part.Split(":"));
            return keyValue.ToDictionary(split => split[0].Trim(), split => split[1].Trim());
        }

        private bool VerifyEquivalent(decimal expected, string actual)
        {
            var absolute = Math.Abs(expected - decimal.Parse(actual));
            if (absolute <= 1)
            {
                return true;
            }

            throw new Exception("Expected: " + expected + "; but received: " + actual);
        }
    }
}
```

```rb
    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/pen_spec.rb#L50-L56)

##### /examples/ruby/spec/actions\_api/pen\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Pen' do
  let(:driver) { start_session }

  it 'uses a pen' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  it 'sets pointer event attributes' do
    driver.get 'https://www.selenium.dev/selenium/web/pointerActionsPage.html'

    pointer_area = driver.find_element(id: 'pointerArea')
    driver.action(devices: :pen)
          .move_to(pointer_area)
          .pointer_down
          .move_by(2, 2, tilt_x: -72, tilt_y: 9, twist: 86)
          .pointer_up
          .perform

    moves = driver.find_elements(class: 'pointermove')
    move_to = properties(moves[0])
    down = properties(driver.find_element(class: 'pointerdown'))
    move_by = properties(moves[1])
    up = properties(driver.find_element(class: 'pointerup'))

    rect = pointer_area.rect
    center_x = rect.x + (rect.width / 2)
    center_y = rect.y + (rect.height / 2)

    expect(move_to).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => center_x.to_s,
                               'pageY' => center_y.floor.to_s)
    expect(down).to include('button' => '0',
                            'pointerType' => 'pen',
                            'pageX' => center_x.to_s,
                            'pageY' => center_y.floor.to_s)
    expect(move_by).to include('button' => '-1',
                               'pointerType' => 'pen',
                               'pageX' => (center_x + 2).to_s,
                               'pageY' => (center_y + 2).floor.to_s,
                               'tiltX' => -72.to_s,
                               'tiltY' => 9.to_s,
                               'twist' => 86.to_s)
    expect(up).to include('button' => '0',
                          'pointerType' => 'pen',
                          'pageX' => (center_x + 2).to_s,
                          'pageY' => (center_y + 2).floor.to_s)
  end

  def properties(element)
    element.text.sub(/.*?\s/, '').split(',').to_h { |item| item.lstrip.split(/\s*:\s*/) }
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

```kt
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/PenTest.kt#L64-L78)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/PenTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.PointerInput
import org.openqa.selenium.interactions.Sequence
import org.openqa.selenium.remote.RemoteWebDriver

import kotlin.collections.Map
import java.time.Duration

class PenTest : BaseTest() {
  
    @Test
    fun usePen() {
        driver.get("https://www.selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        Actions(driver)
                .setActivePointer(PointerInput.Kind.PEN, "default pen")
                .moveToElement(pointerArea)
                .clickAndHold()
                .moveByOffset(2, 2)
                .release()
                .perform()

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY"))
    }

    @Test
    fun setPointerEventProperties() {
        driver.get("https://selenium.dev/selenium/web/pointerActionsPage.html")
        
        val pointerArea = driver.findElement(By.id("pointerArea"))
        val pen = PointerInput(PointerInput.Kind.PEN, "default pen")
        val eventProperties = PointerInput.eventProperties()
                .setTiltX(-72)
                .setTiltY(9)
                .setTwist(86)
        val origin = PointerInput.Origin.fromElement(pointerArea)
        
        val actionListPen = Sequence(pen, 0)
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 0, 0))
                .addAction(pen.createPointerDown(0))
                .addAction(pen.createPointerMove(Duration.ZERO, origin, 2, 2, eventProperties))
                .addAction(pen.createPointerUp(0))

        (driver as RemoteWebDriver).perform(listOf(actionListPen))
                    

        val moves = driver.findElements(By.className("pointermove"))
        val moveTo = getPropertyInfo(moves.get(0))
        val down = getPropertyInfo(driver.findElement(By.className("pointerdown")))
        val moveBy = getPropertyInfo(moves.get(1))
        val up = getPropertyInfo(driver.findElement(By.className("pointerup")))
        
        val rect = pointerArea.getRect()

        val centerX = Math.floor(rect.width.toDouble() / 2 + rect.getX()).toInt()
        val centerY = Math.floor(rect.height.toDouble() / 2 + rect.getY()).toInt()
        Assertions.assertEquals("-1", moveTo.get("button"))
        Assertions.assertEquals("pen", moveTo.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), moveTo.get("pageX"))
        Assertions.assertEquals(centerY.toString(), moveTo.get("pageY"))
        Assertions.assertEquals("0", down.get("button"))
        Assertions.assertEquals("pen", down.get("pointerType"))
        Assertions.assertEquals(centerX.toString(), down.get("pageX"))
        Assertions.assertEquals(centerY.toString(), down.get("pageY"))
        Assertions.assertEquals("-1", moveBy.get("button"))
        Assertions.assertEquals("pen", moveBy.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), moveBy.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), moveBy.get("pageY"))
        Assertions.assertEquals("0", up.get("button"))
        Assertions.assertEquals("pen", up.get("pointerType"))
        Assertions.assertEquals((centerX + 2).toString(), up.get("pageX"))
        Assertions.assertEquals((centerY + 2).toString(), up.get("pageY")) 
	    
        Assertions.assertEquals("-72", moveBy.get("tiltX"))
        Assertions.assertEquals("9", moveBy.get("tiltY"))
        Assertions.assertEquals("86", moveBy.get("twist"))
    }
    
    fun getPropertyInfo(element: WebElement): Map<String, String> {
        var text = element.getText()  
        text = text.substring(text.indexOf(" ")+1)
        return text.split(", ")
        .map { it.split(": ") }
        .map { it.first() to it.last() }
        .toMap() 
    }
}
```

# 4 - Ações de Roda de Rolagem

```java
        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L17-L20)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L11-L14)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L11-L14)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L16-L19)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L18-L21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L29-L33)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L22-L26)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L31-L35)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L22-L26)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L26-L31)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L30-L34)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L42-L46)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L35-L39)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L46-L53)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L34-L38)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L40-L44)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L43-L47)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L57-L61)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L50-L54)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L66-L75)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L48-L52)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L57-L61)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L59-L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L73-L76)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L66-L70)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L89-L97)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L63-L66)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L75-L77)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L75-L78)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/elements/locators/
----

# 定位策略

在DOM中标识一个或多个特定元素的方法.

定位器是在页面上标识元素的一种方法。它是传送给 [查找元素](https://www.selenium.dev/zh-cn/documentation/webdriver/elements/finders/) 方法的参数。

查看 [鼓励测试练习](https://www.selenium.dev/zh-cn/documentation/test_practices/encouraged/) 寻找 [定位器](https://www.selenium.dev/zh-cn/documentation/test_practices/encouraged/locators/)的小技巧， 包含在查找方法中，不同时间，不同原因下，单独声明的定位器的使用方法。

### 元素选择策略

在 WebDriver 中有 8 种不同的内置元素定位策略：

| 定位器 Locator       | 描述                                                 |
| ----------------- | -------------------------------------------------- |
| class name        | 定位class属性与搜索值匹配的元素（不允许使用复合类名）                      |
| css selector      | 定位 CSS 选择器匹配的元素                                    |
| id                | 定位 id 属性与搜索值匹配的元素                                  |
| name              | 定位 name 属性与搜索值匹配的元素                                |
| link text         | 定位link text可视文本与搜索值完全匹配的锚元素                        |
| partial link text | 定位link text可视文本部分与搜索值部分匹配的锚点元素。如果匹配多个元素，则只选择第一个元素。 |
| tag name          | 定位标签名称与搜索值匹配的元素                                    |
| xpath             | 定位与 XPath 表达式匹配的元素                                 |

## Creating Locators

To work on a web element using Selenium, we need to first locate it on the web page. Selenium provides us above mentioned ways, using which we can locate element on the page. To understand and create locator we will use the following HTML snippet.

```html
<html>
<body>
<style>
.information {
  background-color: white;
  color: black;
  padding: 10px;
}
</style>
<h2>Contact Selenium</h2>

<form>
  <input type="radio" name="gender" value="m" />Male &nbsp;
  <input type="radio" name="gender" value="f" />Female <br>
  <br>
  <label for="fname">First name:</label><br>
  <input class="information" type="text" id="fname" name="fname" value="Jane"><br><br>
  <label for="lname">Last name:</label><br>
  <input class="information" type="text" id="lname" name="lname" value="Doe"><br><br>
  <label for="newsletter">Newsletter:</label>
  <input type="checkbox" name="newsletter" value="1" /><br><br>
  <input type="submit" value="Submit">
</form> 

<p>To know more about Selenium, visit the official page 
<a href ="www.selenium.dev">Selenium Official Page</a> 
</p>

</body>
</html>
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L31" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L7-L9)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.ClassName("information"));
  
```

```rb
    driver.find_element(class: 'information')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L7)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.className('information'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.className("information"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L38" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L17-L19)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.CssSelector("#fname"));
  
```

```rb
    driver.find_element(css: '#fname')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L11)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.css('#fname'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.css("#fname"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L45" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L27-L29)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.Id("lname"));
  
```

```rb
    driver.find_element(id: 'lname')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L15)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.id('lname'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.id("lname"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L52" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L37-L39)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.Name("newsletter"));
  
```

```rb
    driver.find_element(name: 'newsletter')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L19)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.name('newsletter'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.name("newsletter"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L59" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L47-L49)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.LinkText("Selenium Official Page"));
  
```

```rb
    driver.find_element(link_text: 'Selenium Official Page')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L23)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.linkText('Selenium Official Page'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.linkText("Selenium Official Page"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L66" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L57-L59)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.PartialLinkText("Official Page"));
  
```

```rb
    driver.find_element(partial_link_text: 'Official Page')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L27)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.partialLinkText('Official Page'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.partialLinkText("Official Page"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L73" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L67-L69)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.TagName("a"));
  
```

```rb
    driver.find_element(tag_name: 'a')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L31)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.tagName('a'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.tagName("a"))
  
```

```java
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   
   <div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span></span></span></code></pre></div>
   
   <style>
   div.code-toolbar > .toolbar {
       display: none !important;
   }
   </style>
   
   
   
   <div class="mt-4 pb-2">
       <div style="border: 1px solid #dee2e6; border-radius: 6px; overflow: hidden; display: flex;">
           <a onclick="showCodeModal('5ca67d91db8eccf20f520328d943e128')" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s; cursor: pointer; border-right: 1px solid #dee2e6;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               View Complete Code
           </a>
           <a href="https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorTest.java#L80" target="_blank" style="flex: 1; display: flex; align-items: center; justify-content: center; padding: 8px 12px; text-decoration: none; color: #007bff; background: #f8f9fa; font-weight: 500; transition: background-color 0.2s;" onmouseover="this.style.backgroundColor='#e9ecef'" onmouseout="this.style.backgroundColor='#f8f9fa'">
               <i class="fas fa-external-link-alt" style="margin-right: 8px;"></i>
               View on GitHub
           </a>
       </div>
   </div>
   
   <div id="codeModal_5ca67d91db8eccf20f520328d943e128" style="display: none; position: fixed; top: 0; left: 0; width: 100%; height: 100%; background: rgba(0,0,0,0.5); z-index: 1050;">
       <div style="position: absolute; top: 50%; left: 50%; transform: translate(-50%, -50%); background: white; border-radius: 8px; max-width: 90%; max-height: 90%; overflow: auto; box-shadow: 0 4px 20px rgba(0,0,0,0.3);">
           <div style="position: sticky; top: 0; z-index: 10; background: white; box-shadow: 0 2px 2px rgba(0,0,0,0.1); padding: 10px 15px; border-bottom: 1px solid #dee2e6; display: flex; justify-content: space-between; align-items: center; height: 50px;">
               <h5 style="margin: 0;">/examples/java/src/test/java/dev/selenium/elements/LocatorTest.java</h5>
               <div>
                   <button onclick="copyCode('5ca67d91db8eccf20f520328d943e128', event)" style="margin-right: 10px; padding: 5px 10px; border: 1px solid #007bff; background: #007bff; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Copy
                   </button>
                   <button onclick="closeCodeModal('5ca67d91db8eccf20f520328d943e128')" style="padding: 5px 10px; border: 1px solid #6c757d; background: #6c757d; color: white; border-radius: 4px; cursor: pointer; user-select: none; -webkit-user-select: none; -moz-user-select: none; -ms-user-select: none;">
                       Close
                   </button>
               </div>
           </div>
           <div style="padding: 20px;">
               <div id="codeContent_5ca67d91db8eccf20f520328d943e128"><div class="highlight"><pre tabindex="0" style="background-color:#f8f8f8;-moz-tab-size:4;-o-tab-size:4;tab-size:4;"><code class="language-java" data-lang="java"><span style="display:flex;"><span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.AfterEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Assertions</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.BeforeEach</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.junit.jupiter.api.Test</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.By</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.WebElement</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">import</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">org.openqa.selenium.chrome.ChromeDriver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">class</span> <span style="color:#000">LocatorTest</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">private</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">WebDriver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">;</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@BeforeEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">setUp</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Initialize the driver before each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">new</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">ChromeDriver</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">get</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/selenium/web/locators_tests/locators.html&#34;</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@AfterEach</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">tearDown</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#8f5902;font-style:italic">// Close the browser after each test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#204a87;font-weight:bold">if</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">driver</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">!=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">null</span><span style="color:#000;font-weight:bold">)</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">            </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">quit</span><span style="color:#000;font-weight:bold">();</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testClassName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">className</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;information&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testCssSelector</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">cssSelector</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;#fname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Jane&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testId</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">id</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;lname&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Doe&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;value&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">name</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;newsletter&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;input&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getTagName</span><span style="color:#000;font-weight:bold">());</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">linkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Selenium Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testPartialLinkText</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">partialLinkText</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;Official Page&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testTagName</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">tagName</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;a&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;https://www.selenium.dev/&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;href&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#5c35cc;font-weight:bold">@Test</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#204a87;font-weight:bold">public</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#204a87;font-weight:bold">void</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">testXpath</span><span style="color:#000;font-weight:bold">()</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000;font-weight:bold">{</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">WebElement</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#ce5c00;font-weight:bold">=</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">driver</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">findElement</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">By</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">xpath</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;//input[@value=&#39;f&#39;]&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertNotNull</span><span style="color:#000;font-weight:bold">(</span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">);</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">        </span><span style="color:#000">Assertions</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">assertEquals</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;radio&#34;</span><span style="color:#000;font-weight:bold">,</span><span style="color:#f8f8f8;text-decoration:underline"> </span><span style="color:#000">element</span><span style="color:#000;font-weight:bold">.</span><span style="color:#c4a000">getAttribute</span><span style="color:#000;font-weight:bold">(</span><span style="color:#4e9a06">&#34;type&#34;</span><span style="color:#000;font-weight:bold">));</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline">    </span><span style="color:#000;font-weight:bold">}</span><span style="color:#f8f8f8;text-decoration:underline">
   </span></span></span><span style="display:flex;"><span><span style="color:#f8f8f8;text-decoration:underline"></span><span style="color:#000;font-weight:bold">}</span></span></span></code></pre></div></div>
           </div>
       </div>
   </div>
   
   <script>
   document.addEventListener('DOMContentLoaded', function() {
       const toolbars = document.querySelectorAll('div.code-toolbar > .toolbar');
       toolbars.forEach(toolbar => toolbar.remove());
   });
   
   window.showCodeModal = window.showCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'block';
       document.body.style.overflow = 'hidden';
   };
   
   window.closeCodeModal = window.closeCodeModal || function(id) {
       document.getElementById('codeModal_' + id).style.display = 'none';
       document.body.style.overflow = '';
   };
   
   window.copyCode = window.copyCode || function(id, event) {
       const codeElement = document.getElementById('codeContent_' + id);
       const preElement = codeElement.querySelector('pre');
       const code = preElement ? preElement.textContent : codeElement.textContent;
   
       if (navigator.clipboard) {
           navigator.clipboard.writeText(code).then(() => {
               const btn = event.target;
               const originalText = btn.textContent;
               btn.textContent = 'Copied!';
               btn.style.background = '#28a745';
               btn.style.borderColor = '#28a745';
               setTimeout(() => {
                   btn.textContent = originalText;
                   btn.style.background = '#007bff';
                   btn.style.borderColor = '#007bff';
               }, 2000);
           });
       } else {
           const textArea = document.createElement('textarea');
           textArea.value = code;
           document.body.appendChild(textArea);
           textArea.select();
           document.execCommand('copy');
           document.body.removeChild(textArea);
   
           const btn = event.target;
           const originalText = btn.textContent;
           btn.textContent = 'Copied!';
           btn.style.background = '#28a745';
           btn.style.borderColor = '#28a745';
           setTimeout(() => {
               btn.textContent = originalText;
               btn.style.background = '#007bff';
               btn.style.borderColor = '#007bff';
           }, 2000);
       }
   };
   
   document.addEventListener('click', function(e) {
       if (e.target.id && e.target.id.startsWith('codeModal_')) {
           const id = e.target.id.replace('codeModal_', '');
           closeCodeModal(id);
       }
   });
   
   document.addEventListener('keydown', function(e) {
       if (e.key === 'Escape') {
           const openModals = document.querySelectorAll('[id^="codeModal_"]');
           openModals.forEach(modal => {
               if (modal.style.display === 'block') {
                   const id = modal.id.replace('codeModal_', '');
                   closeCodeModal(id);
               }
           });
       }
   });
   </script>
   
   
   

  
```

```py
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_locators.py#L77-L79)

##### /examples/python/tests/elements/test\_locators.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_class_name():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CLASS_NAME, "information")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_css_selector(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.CSS_SELECTOR, "#fname")

    assert element is not None
    assert element.get_attribute("value") == "Jane"

    driver.quit()

def test_id(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.ID, "lname")

    assert element is not None
    assert element.get_attribute("value") == "Doe"

    driver.quit()

def test_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.NAME, "newsletter")

    assert element is not None
    assert element.tag_name == "input"

    driver.quit()

def test_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.LINK_TEXT, "Selenium Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_partial_link_text(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.PARTIAL_LINK_TEXT, "Official Page")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_tag_name(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.TAG_NAME, "a")

    assert element is not None
    assert element.get_attribute("href") == "https://www.selenium.dev/"

    driver.quit()

def test_xpath(driver):
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/locators_tests/locators.html")
    element = driver.find_element(By.XPATH, "//input[@value='f']")

    assert element is not None
    assert element.get_attribute("type") == "radio"

    driver.quit()
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.Xpath("//input[@value='f']"));
  
```

```rb
    driver.find_element(xpath: "//input[@value='f']")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L35)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.xpath('//input[@value='f']'));
  
```

```kotlin
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.xpath('//input[@value='f']'))
  
```

```java
    import org.openqa.selenium.By;
    WebDriver driver = new ChromeDriver();
	driver.findElement(By.className("information"));
  
```

```python
    from selenium.webdriver.common.by import By
    driver = webdriver.Chrome()
	driver.find_element(By.CLASS_NAME, "information")
  
```

```csharp
    var driver = new ChromeDriver();
	driver.FindElement(By.ClassName("information"));
  
```

```rb
    driver.find_element(class: 'information')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L7)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
    let driver = await new Builder().forBrowser('chrome').build();
	const loc = await driver.findElement(By.className('information'));
  
```

```kotlin
    import org.openqa.selenium.By
    val driver = ChromeDriver()
	val loc: WebElement = driver.findElement(By.className("information"))
  
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java#L37-L38)

##### /examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java

```java
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java#L22-L23)

##### /examples/java/src/test/java/dev/selenium/elements/LocatorsTest.java

```java
```

```java
By emailLocator = RelativeLocator.with(By.tagName("input")).above(By.id("password"));
```

```python
email_locator = locate_with(By.TAG_NAME, "input").above({By.ID: "password"})
```

```csharp
var emailLocator = RelativeBy.WithLocator(By.TagName("input")).Above(By.Id("password"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L40)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let emailLocator = locateWith(By.tagName('input')).above(By.id('password'));
```

```kotlin
val emailLocator = RelativeLocator.with(By.tagName("input")).above(By.id("password"))
```

```java
By passwordLocator = RelativeLocator.with(By.tagName("input")).below(By.id("email"));
```

```python
password_locator = locate_with(By.TAG_NAME, "input").below({By.ID: "email"})
```

```csharp
var passwordLocator = RelativeBy.WithLocator(By.TagName("input")).Below(By.Id("email"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L44)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let passwordLocator = locateWith(By.tagName('input')).below(By.id('email'));
```

```kotlin
val passwordLocator = RelativeLocator.with(By.tagName("input")).below(By.id("email"))
```

```java
By cancelLocator = RelativeLocator.with(By.tagName("button")).toLeftOf(By.id("submit"));
```

```python
cancel_locator = locate_with(By.TAG_NAME, "button").to_left_of({By.ID: "submit"})
```

```csharp
var cancelLocator = RelativeBy.WithLocator(By.tagName("button")).LeftOf(By.Id("submit"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L48)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let cancelLocator = locateWith(By.tagName('button')).toLeftOf(By.id('submit'));
```

```kotlin
val cancelLocator = RelativeLocator.with(By.tagName("button")).toLeftOf(By.id("submit"))
```

```java
By submitLocator = RelativeLocator.with(By.tagName("button")).toRightOf(By.id("cancel"));
```

```python
submit_locator = locate_with(By.TAG_NAME, "button").to_right_of({By.ID: "cancel"})
```

```csharp
var submitLocator = RelativeBy.WithLocator(By.tagName("button")).RightOf(By.Id("cancel"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L52)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let submitLocator = locateWith(By.tagName('button')).toRightOf(By.id('cancel'));
```

```kotlin
val submitLocator = RelativeLocator.with(By.tagName("button")).toRightOf(By.id("cancel"))
```

```java
By emailLocator = RelativeLocator.with(By.tagName("input")).near(By.id("lbl-email"));
```

```python
email_locator = locate_with(By.TAG_NAME, "input").near({By.ID: "lbl-email"})
```

```csharp
var emailLocator = RelativeBy.WithLocator(By.tagName("input")).Near(By.Id("lbl-email"));
```

```rb
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L56)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let emailLocator = locateWith(By.tagName('input')).near(By.id('lbl-email'));
```

```kotlin
val emailLocator = RelativeLocator.with(By.tagName("input")).near(By.id("lbl-email"));
```

```java
By submitLocator = RelativeLocator.with(By.tagName("button")).below(By.id("email")).toRightOf(By.id("cancel"));
```

```python
submit_locator = locate_with(By.TAG_NAME, "button").below({By.ID: "email"}).to_right_of({By.ID: "cancel"})
```

```csharp
var submitLocator = RelativeBy.WithLocator(By.tagName("button")).Below(By.Id("email")).RightOf(By.Id("cancel"));
```

```rb
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/locators_spec.rb#L60)

##### /examples/ruby/spec/elements/locators\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Locators', skip: 'These are reference following the documentation example' do
  it 'finds element by class name' do
    driver.find_element(class: 'information')
  end

  it 'finds element by css selector' do
    driver.find_element(css: '#fname')
  end

  it 'finds element by id' do
    driver.find_element(id: 'lname')
  end

  it 'find element by name' do
    driver.find_element(name: 'newsletter')
  end

  it 'finds element by link text' do
    driver.find_element(link_text: 'Selenium Official Page')
  end

  it 'finds element by partial link text' do
    driver.find_element(partial_link_text: 'Official Page')
  end

  it 'finds element by tag name' do
    driver.find_element(tag_name: 'a')
  end

  it 'finds element by xpath' do
    driver.find_element(xpath: "//input[@value='f']")
  end

  context 'with relative locators' do
    it 'finds element above' do
      driver.find_element({relative: {tag_name: 'input', above: {id: 'password'}}})
    end

    it 'finds element below' do
      driver.find_element({relative: {tag_name: 'input', below: {id: 'email'}}})
    end

    it 'finds element to the left' do
      driver.find_element({relative: {tag_name: 'button', left: {id: 'submit'}}})
    end

    it 'finds element to the right' do
      driver.find_element({relative: {tag_name: 'button', right: {id: 'cancel'}}})
    end

    it 'finds near element' do
      driver.find_element({relative: {tag_name: 'input', near: {id: 'lbl-email'}}})
    end

    it 'chains relative locators' do
      driver.find_element({relative: {tag_name: 'button', below: {id: 'email'}, right: {id: 'cancel'}}})
    end
  end
end
```

```javascript
let submitLocator = locateWith(By.tagName('button')).below(By.id('email')).toRightOf(By.id('cancel'));
```

```kotlin
val submitLocator = RelativeLocator.with(By.tagName("button")).below(By.id("email")).toRightOf(By.id("cancel"))
```

最后修改 February 16, 2026: [added locator code file for java for locator strategies Section and added content in diff languages files (#2583) (77549cd7301)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/77549cd7301dea332c7559cb6a5365a82a357e50)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/bidi/w3c/script/
----

# Script

```java
        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));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L52-L75)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L32-L53)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L201-L210)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L202-L204)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L219-L229)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L222-L227)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L239-L242)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L237-L239)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L280-L283)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L279-L283)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L293-L299)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L292-L299)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            script.disownBrowsingContextScript(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L322-L322)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    await manager.disownBrowsingContextScript(id, boxId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L330-L330)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            script.disownRealmScript(realmId, List.of(boxId));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L375-L375)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    await manager.disownRealmScript(realmId, boxId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L372-L372)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L391-L392)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L383-L385)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L401-402)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L393-L395)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L411-412)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L403-L405)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L422-423)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```js
    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L416-L416)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L463-463)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L424-L426)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
                script.removePreloadScript(id);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptTest.java#L486-486)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.WindowType;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.browsingcontext.ReadinessState;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.script.ChannelValue;
import org.openqa.selenium.bidi.script.EvaluateResult;
import org.openqa.selenium.bidi.script.EvaluateResultExceptionValue;
import org.openqa.selenium.bidi.script.EvaluateResultSuccess;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.ObjectLocalValue;
import org.openqa.selenium.bidi.script.PrimitiveProtocolValue;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.bidi.script.RemoteReference;
import org.openqa.selenium.bidi.script.ResultOwnership;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void canCallFunction() {
        String id = driver.getWindowHandle();
        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));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(64L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithDeclaration() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id, "()=>{return 1+2;}", false, Optional.empty(), Optional.empty(), Optional.empty());
            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithArguments() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            List<LocalValue> arguments = new ArrayList<>();
            LocalValue value1 = PrimitiveProtocolValue.stringValue("ARGUMENT_STRING_VALUE");
            LocalValue value2 = PrimitiveProtocolValue.numberValue(42);
            arguments.add(value1);
            arguments.add(value2);

            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "(...args)=>{return args}",
                            false,
                            Optional.of(arguments),
                            Optional.empty(),
                            Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(2, ((List<Object>) successResult.getResult().getValue().get()).size());
        }
    }

    @Test
    void canCallFunctionWithAwaitPromise() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "async function() {{\n"
                                + "            await new Promise(r => setTimeout(() => r(), 0));\n"
                                + "            return \"SOME_DELAYED_RESULT\";\n"
                                + "          }}",
                        true,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("SOME_DELAYED_RESULT", (String) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithThisParameter() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        Map<Object, LocalValue> value = new HashMap<>();
        value.put("some_property", PrimitiveProtocolValue.numberValue(42));
        LocalValue thisParameter = LocalValue.objectValue(value);

        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "function(){return this.some_property}",
                        false,
                        Optional.empty(),
                        Optional.of(thisParameter),
                        Optional.empty());

        EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
        Assertions.assertEquals("number", successResult.getResult().getType());
        Assertions.assertEquals(42L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canCallFunctionWithOwnershipRoot() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "async function(){return {a:1}}",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
            }
        }

    @Test
    void canCallFunctionThatThrowsException() {
        String id = driver.getWindowHandle();
    try (Script script = new Script(id, driver)) {
        EvaluateResult result =
                script.callFunctionInBrowsingContext(
                        id,
                        "))) !!@@## some invalid JS script (((",
                        false,
                        Optional.empty(),
                        Optional.empty(),
                        Optional.empty());
        EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
        Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
        Assertions.assertEquals(
                "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canCallFunctionInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.callFunctionInBrowsingContext(
                            id,
                            "sandbox",
                            "() => window.foo",
                            true,
                            Optional.empty(),
                            Optional.empty(),
                            Optional.empty());

        Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canCallFunctionInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateScript() {
        String id = driver.getWindowHandle();

        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(id, "1 + 2", true, Optional.empty());

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
            Assertions.assertEquals(3L, (Long) successResult.getResult().getValue().get());
        }
    }

    @Test
    void canEvaluateScriptThatThrowsException() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "))) !!@@## some invalid JS script (((", false, Optional.empty());

            EvaluateResultExceptionValue exception = (EvaluateResultExceptionValue) result;
            Assertions.assertEquals("error", exception.getExceptionDetails().getException().getType());
            Assertions.assertEquals(
                    "SyntaxError: expected expression, got ')'", exception.getExceptionDetails().getText());
        }
    }

    @Test
    void canEvaluateScriptWithResulWithOwnership() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "Promise.resolve({a:1})", true, Optional.of(ResultOwnership.ROOT));

            EvaluateResultSuccess successResult = (EvaluateResultSuccess) result;
            Assertions.assertTrue(successResult.getResult().getHandle().isPresent());
        }
    }

    @Test
    void canEvaluateInASandBox() {
        String id = driver.getWindowHandle();
        try (Script script = new Script(id, driver)) {
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            id, "sandbox", "window.foo", true, Optional.empty());


            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canEvaluateInARealm() {
        String tab = driver.getWindowHandle();
        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());

            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canDisownHandle() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            script.disownBrowsingContextScript(
                            window, List.of(boxId));

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canDisownHandleInARealm() {
        String window = driver.getWindowHandle();
        try (Script script = new Script(window, driver)) {
            BrowsingContext context = new BrowsingContext(driver, window);

            context.navigate("https://www.selenium.dev/selenium/web/dynamic.html", ReadinessState.COMPLETE);

            driver.findElement(By.id("adder")).click();

            getLocatedElement(driver, By.id("box0"));

            List<RealmInfo> realms = script.getAllRealms();
            String realmId = realms.get(0).getRealmId();

            // Retrieve the handle for the element added to DOM
            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            window, "document.querySelector('.redbox');", false, Optional.of(ResultOwnership.ROOT));
            String boxId = ((EvaluateResultSuccess)result).getResult().getHandle().get();

            LocalValue value =
                    LocalValue.remoteReference(
                            RemoteReference.Type.HANDLE, boxId);

            EvaluateResult checkHandle = script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty());

            // The handle is present in memory, else it would result in exception
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, checkHandle.getResultType());

            // Useful to memory management in a dynamic webpage where DOM mutations happen often
            script.disownRealmScript(realmId, List.of(boxId));

            // Since the handle is now eligible for garbage collections, it is no longer available to be used.
            Assertions.assertThrows(WebDriverException.class, () -> script.callFunctionInBrowsingContext(
                    window,
                    "arg => arg.a",
                    false, Optional.of(List.of(value)),
                    Optional.empty(),
                    Optional.empty()));
        }
    }

    @Test
    void canGetAllRealms() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getAllRealms();
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmByType() {
        String firstWindow = driver.getWindowHandle();
        String secondWindow = driver.switchTo().newWindow(WindowType.WINDOW).getWindowHandle();
        try (Script script = new Script(firstWindow, driver)) {
            List<RealmInfo> realms = script.getRealmsByType(RealmType.WINDOW);
            Assertions.assertEquals(2, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContext() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> realms = script.getRealmsInBrowsingContext(tabId);
            Assertions.assertEquals(1, realms.size());
        }
    }

    @Test
    void canGetRealmInBrowsingContextByType() {
        String windowId = driver.getWindowHandle();
        String tabId = driver.switchTo().newWindow(WindowType.TAB).getWindowHandle();
        try (Script script = new Script(windowId, driver)) {
            List<RealmInfo> windowRealms =
                    script.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW);
            Assertions.assertEquals(1, windowRealms.size());
        }
    }

    @Test
    void canAddPreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

                Assertions.assertEquals("{preload_script_console_text}", logEntry.getText());
            }
        }
    }

    @Test
    void canAddPreloadScriptWithArguments() {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript(
                            "(channel) => channel('will_be_send', 'will_be_ignored')",
                            List.of(new ChannelValue("channel_name")));
            Assertions.assertNotNull(id);
        }
    }

    @Test
    void canAddPreloadScriptInASandbox() {
        try (Script script = new Script(driver)) {
            String id = script.addPreloadScript("() => { window.bar=2; }", "sandbox");
            Assertions.assertNotNull(id);
            driver.get("https://www.selenium.dev/selenium/blankPage");

            EvaluateResult result =
                    script.evaluateFunctionInBrowsingContext(
                            driver.getWindowHandle(), "sandbox", "window.bar", true, Optional.empty());
            Assertions.assertEquals(EvaluateResult.Type.SUCCESS, result.getResultType());
        }
    }

    @Test
    void canRemovePreloadScript() throws ExecutionException, InterruptedException, TimeoutException {
        try (Script script = new Script(driver)) {
            String id =
                    script.addPreloadScript("() => {{ console.log('{preload_script_console_text}') }}");

            Assertions.assertNotNull(id);

            try (LogInspector logInspector = new LogInspector(driver)) {
                CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
                logInspector.onConsoleEntry(future::complete);

                script.removePreloadScript(id);

                driver.get("https://www.selenium.dev/selenium/blankPage");

                Assertions.assertThrows(TimeoutException.class, () -> future.get(5, TimeUnit.SECONDS));
            }
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```js
    await manager.removePreloadScript(scriptId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_commands.spec.js#L471-L471)

##### /examples/javascript/test/bidirectional/script\_commands.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, until, Builder} = require("selenium-webdriver")
const ScriptManager = require('selenium-webdriver/bidi/scriptManager')
const {ResultOwnership} = require("selenium-webdriver/bidi/resultOwnership");
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue");
const {LocalValue, RemoteReferenceType, ReferenceValue} = require("selenium-webdriver/bidi/protocolValue");
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");
const BrowsingContext = require("selenium-webdriver/bidi/browsingContext");
const {WebDriverError} = require("selenium-webdriver/lib/error");
const {RealmType} = require("selenium-webdriver/bidi/realmInfo");
const LogInspector = require("selenium-webdriver/bidi/logInspector");



describe('Script commands', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can call function', async function () {
    const id = await driver.getWindowHandle()
    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)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 64)
  })

  it('can call function with declaration', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '()=>{return 1+2;}', false)
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can call function to get element', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded')
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '() => document.getElementById("consoleLog")',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.type, 'node')
    assert.notEqual(result.result.value, null)
    assert.notEqual(result.result.value.nodeType, null)
  })

  it('can call function with arguments', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let argumentValues = []
    let value1 = new ArgumentValue(LocalValue.createStringValue('ARGUMENT_STRING_VALUE'))
    let value2 = new ArgumentValue(LocalValue.createNumberValue(42))
    argumentValues.push(value1)
    argumentValues.push(value2)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      '(...args)=>{return args}',
      false,
      argumentValues,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value.length, 2)
  })

  it('can call function with await promise', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      true,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 'SOME_DELAYED_RESULT')
  })

  it('can call function with await promise false', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function() {{\n' +
      '            await new Promise(r => setTimeout(() => r(), 0));\n' +
      '            return "SOME_DELAYED_RESULT";\n' +
      '          }}',
      false,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.type, 'promise')
  })

  it('can call function with this parameter', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    let mapValue = {some_property: LocalValue.createNumberValue(42)}
    let thisParameter = new ArgumentValue(LocalValue.createObjectValue(mapValue)).asMap()

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'function(){return this.some_property}',
      false,
      null,
      thisParameter,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 42)
  })

  it('can call function with ownership root', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.ROOT,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function with ownership none', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(
      id,
      'async function(){return {a:1}}',
      true,
      null,
      null,
      ResultOwnership.NONE,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.realmId, null)
    assert.equal(result.result.handle, undefined)
    assert.notEqual(result.result.value, null)
  })

  it('can call function that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.callFunctionInBrowsingContext(id, '))) !!@@## some invalid JS script (((', false)
    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)

    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can call function in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.callFunctionInBrowsingContext(id, '() => { window.foo = 2; }', true, null, null, null, 'sandbox')

    const resultInSandbox = await manager.callFunctionInBrowsingContext(
      id,
      '() => window.foo',
      true,
      null,
      null,
      null,
      'sandbox',
    )

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
  })

  it('can call function in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(firstTab, driver)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    await manager.callFunctionInRealm(realmId, '() => { window.foo = 3; }', true)

    const result = await manager.callFunctionInRealm(realmId, '() => window.foo', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(id, '1 + 2', true)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can evaluate script that throws exception', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      '))) !!@@## some invalid JS script (((',
      false,
    )

    assert.equal(result.resultType, EvaluateResultType.EXCEPTION)
    assert.equal(result.exceptionDetails.exception.type, 'error')
    assert.equal(result.exceptionDetails.text, "SyntaxError: expected expression, got ')'")
    assert.equal(result.exceptionDetails.columnNumber, 39)
    assert.equal(result.exceptionDetails.stackTrace.callFrames.length, 0)
  })

  it('can evaluate script with result ownership', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const result = await manager.evaluateFunctionInBrowsingContext(
      id,
      'Promise.resolve({a:1})',
      true,
      ResultOwnership.ROOT,
    )

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(result.result.handle, null)
  })

  it('can evaluate in a sandbox', async function () {
    const id = await driver.getWindowHandle()
    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')

    assert.equal(resultInSandbox.resultType, EvaluateResultType.SUCCESS)
    assert.equal(resultInSandbox.result.value, 2)
  })

  it('can evaluate in a realm', async function () {
    const firstTab = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    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)

    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.equal(result.result.value, 3)
  })

  it('can disown handles', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    await manager.disownBrowsingContextScript(id, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can disown handles in realm', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const browsingContext = await BrowsingContext(driver, {browsingContextId: id})

    const info = await browsingContext.navigate(
      'https://www.selenium.dev/selenium/web/dynamic.html',
      'complete'
    )

    await driver.findElement(By.id('adder')).click()

    await driver.wait(until.elementLocated(By.id('box0')), 10000)

    const realms = await manager.getAllRealms()
    const realmId = realms[0].realmId

    const evaluateResult = await manager.evaluateFunctionInBrowsingContext(
      id,
      "document.querySelector('.redbox');",
      false,
      ResultOwnership.ROOT,
    )

    assert.equal(evaluateResult.resultType, EvaluateResultType.SUCCESS)
    let boxId = evaluateResult.result.handle

    let argumentValues = []
    let value1 = new ArgumentValue(new ReferenceValue(RemoteReferenceType.HANDLE, boxId))
    argumentValues.push(value1)
    let checkHandle = await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false, argumentValues)

    assert.equal(checkHandle.resultType, EvaluateResultType.SUCCESS)

    await manager.disownRealmScript(realmId, boxId)

    await manager.callFunctionInBrowsingContext(id, 'arg => arg.a', false).catch((error) => {
      assert(error instanceof WebDriverError)
    })
  })

  it('can get all realms', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getAllRealms()
    assert.equal(realms.length, 2)
  })

  it('can get realm by type', async function () {
    const firstWindow = await driver.getWindowHandle()
    await driver.switchTo().newWindow('window')
    const secondWindow = await driver.getWindowHandle()
    const manager = await ScriptManager(firstWindow, driver)

    const realms = await manager.getRealmsByType(RealmType.WINDOW)
    assert.equal(realms.length, 2)
  })

  it('can get realm in browsing context', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const tabId = await driver.getWindowHandle()
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContext(tabId)

    const tabRealm = realms[0]
    assert.equal(tabRealm.realmType, RealmType.WINDOW)
  })

  it('can get realm in browsing context by type', async function () {
    const windowId = await driver.getWindowHandle()
    await driver.switchTo().newWindow('tab')
    const manager = await ScriptManager(windowId, driver)

    const realms = await manager.getRealmsInBrowsingContextByType(windowId, RealmType.WINDOW)

    const windowRealm = realms[0]
    assert.equal(windowRealm.realmType, RealmType.WINDOW)
  })

  it('can add preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry.text, '{preload_script_console_text}')
  })

  it('can add preload script to sandbox', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    await manager.addPreloadScript('() => { window.bar = 2; }', undefined, 'sandbox')

    await driver.get('https://www.selenium.dev/selenium/blank')

    let result_in_sandbox = await manager.evaluateFunctionInBrowsingContext(
      id,
      'window.bar',
      true,
      null,
      'sandbox',
    )

    assert.equal(result_in_sandbox.result.type, 'number')
    assert.equal(result_in_sandbox.result.value, 2)
  })

  it('can remove preload script', async function () {
    const id = await driver.getWindowHandle()
    const manager = await ScriptManager(id, driver)

    const scriptId = await manager.addPreloadScript('() => {{ console.log(\'{preload_script_console_text}\') }}')

    let logEntry = null
    const inspector = await LogInspector(driver)
    await inspector.onConsoleEntry(function (log) {
      logEntry = log
    })

    await manager.removePreloadScript(scriptId)

    await driver.get('https://www.selenium.dev/selenium/blank')

    assert.equal(logEntry, null)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L37-L51)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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,
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L26-L43)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L58-L68)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.18](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.18.0)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L52-L65)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

```java
        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());
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ScriptEventsTest.java#L75-L85)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ScriptEventsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.bidi.module.Script;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.openqa.selenium.bidi.script.LocalValue;
import org.openqa.selenium.bidi.script.Message;
import org.openqa.selenium.bidi.script.RealmInfo;
import org.openqa.selenium.bidi.script.RealmType;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;

class ScriptEventsTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }
    
    @Test
    void canListenToChannelMessage()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @DisabledOnOs(value = OS.MAC, disabledReason = "Works locally, times out on CI")
    void canListenToRealmCreatedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }

    @Test
    @Disabled
    void canListenToRealmDestroyedEvent()
            throws ExecutionException, InterruptedException, TimeoutException {
        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());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.19](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.19.0)

```js
    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()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/script_events.spec.js#L73-L86)

##### /examples/javascript/test/bidirectional/script\_events.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {ScriptManager, BrowsingContext, Builder} = require("selenium-webdriver")
const {ArgumentValue} = require("selenium-webdriver/bidi/argumentValue")
const {RealmType} = require("selenium-webdriver/bidi/realmInfo")
const {LocalValue, ChannelValue} = require("selenium-webdriver/bidi/protocolValue")
const {EvaluateResultType} = require("selenium-webdriver/bidi/evaluateResult");



describe('Script events', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can listen to channel message', async function () {
    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,
    )
    assert.equal(result.resultType, EvaluateResultType.SUCCESS)
    assert.notEqual(message, null)
    assert.equal(message.channel, 'channel_name')
    assert.equal(message.data.type, 'string')
    assert.equal(message.data.value, 'foo')
  })

  it('can listen to realm created message', async function () {
    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')

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })

  xit('can listen to realm destroyed message', async function () {
    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()

    assert.notEqual(realmInfo, null)
    assert.notEqual(realmInfo.realmId, null)
    assert.equal(realmInfo.realmType, RealmType.WINDOW)
  })
})
```

[Add Example](/documentation/about/contributing/#creating-examples)

----
url: https://www.selenium.dev/zh-cn/documentation/legacy/selenium_2/upgrading/
----

# 从RC迁移到WebDriver

```java
Selenium selenium = new DefaultSelenium("localhost", 4444, "*firefox", "http://www.yoursite.com");
selenium.start();
```

应该这样替换:

```java
WebDriver driver = new FirefoxDriver();
Selenium selenium = new WebDriverBackedSelenium(driver, "http://www.yoursite.com");
```

## 下一步

一旦测试成功执行, 下一步就是迁移实际的测试代码以使用WebDriver API. 根据代码的抽象程度, 这可能是一个短暂的过程, 也可能是一个漫长的过程. 在这两种情况下, 方法都是相同的, 可以简单地总结一下：修改代码以在使用新API时进行编辑.

如果您需要从Selenium实例中提取基础WebDriver实现, 则只需将其强制转换为WrapsDriver:

```java
WebDriver driver = ((WrapsDriver) selenium).getWrappedDriver();
```

这使您可以继续正常传递Selenium实例, 但可以根据需要解包WebDriver实例.

有时, 您的代码库将主要使用较新的API. 此时, 您可以翻转关系, 使用WebDriver并按需实例化Selenium实例:

```java
Selenium selenium = new WebDriverBackedSelenium(driver, baseUrl);
```

## 常见问题

幸运的是, 您不是第一个进行此迁移的人, 因此这里有其他人已经看到的一些常见问题以及如何解决它们.

### 单击和键入更加完整

Selenium RC测试中的常见模式如下所示:

```java
selenium.type("name", "exciting tex");
selenium.keyDown("name", "t");
selenium.keyPress("name", "t");
selenium.keyUp("name", "t");
```

```java
Wait<WebDriver> wait = new WebDriverWait(driver, Duration.ofSeconds(30));
WebElement element= wait.until(visibilityOfElementLocated(By.id("some_id")));
```

其中"visibilityOfElementLocated"实现为:

```java
public ExpectedCondition<WebElement> visibilityOfElementLocated(final By locator) {
  return new ExpectedCondition<WebElement>() {
    public WebElement apply(WebDriver driver) {
      WebElement toReturn = driver.findElement(locator);
      if (toReturn.isDisplayed()) {
        return toReturn;
      }
      return null;
    }
  };
}
```

这看起来很复杂, 但这几乎是所有样板代码. 唯一有趣的一点是, 将反复评估"ExpectedCondition", 直到"apply"方法返回的结果既不是"null" 也不是Boolean.FALSE.

当然, 添加所有这些"等待"调用可能会使您的代码混乱. 如果是这样, 并且您的需求很简单, 请考虑使用隐式等待:

```java
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
```

```java
String name = selenium.getEval(
    "selenium.browserbot.findElement('id=foo', browserbot.getCurrentWindow()).tagName");
```

变成:

```java
WebElement element = driver.findElement(By.id("foo"));
String name = (String) ((JavascriptExecutor) driver).executeScript(
    "return arguments[0].tagName", element);
```

请注意, 传入的"element"变量如何显示为JS标准"arguments"数组中的第一项.

### 执行JavaScript不会返回任何内容

WebDriver的JavascriptExecutor将包装所有JS并将其评估为匿名表达式. 这意味着您需要使用"return"关键字:

```java
String title = selenium.getEval("browserbot.getCurrentWindow().document.title");
```

变成:

```java
((JavascriptExecutor) driver).executeScript("return document.title;");
```

----
url: https://www.selenium.dev/ja/documentation/webdriver/interactions/alerts/
----

# JavaScript アラート、プロンプトおよび確認

```java

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L36-L41)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L12-L18)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See an example alert")).Click();

//Wait for the alert to be displayed and store it in a variable
IAlert alert = wait.Until(ExpectedConditions.AlertIsPresent());

//Store the alert text in a variable
string text = alert.Text;

//Press the OK button
alert.Accept();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L15-L22)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L19-L21)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See an example alert")).click()

//Wait for the alert to be displayed and store it in a variable
val alert = wait.until(ExpectedConditions.alertIsPresent())

//Store the alert text in a variable
val text = alert.getText()

//Press the OK button
alert.accept()
  
```

```java
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L131-L138)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L26-L32)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See a sample confirm")).Click();

//Wait for the alert to be displayed
wait.Until(ExpectedConditions.AlertIsPresent());

//Store the alert in a variable
IAlert alert = driver.SwitchTo().Alert();

//Store the alert in a variable for reuse
string text = alert.Text;

//Press the Cancel button
alert.Dismiss();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L28-L35)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L30-L32)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See a sample confirm")).click()

//Wait for the alert to be displayed
wait.until(ExpectedConditions.alertIsPresent())

//Store the alert in a variable
val alert = driver.switchTo().alert()

//Store the alert in a variable for reuse
val text = alert.text

//Press the Cancel button
alert.dismiss()
  
```

```java
        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L79-L84)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L40-L47)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See a sample prompt")).Click();

//Wait for the alert to be displayed and store it in a variable
IAlert alert = wait.Until(ExpectedConditions.AlertIsPresent());

//Type your message
alert.SendKeys("Selenium");

//Press the OK button
alert.Accept();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L41-L48)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L42-L45)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See a sample prompt")).click()

//Wait for the alert to be displayed and store it in a variable
val alert = wait.until(ExpectedConditions.alertIsPresent())

//Type your message
alert.sendKeys("Selenium")

//Press the OK button
alert.accept()
  
```

最終更新 August 14, 2025: [Fixing path for code block (c7fcb0099f5)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/c7fcb0099f58ba4d4dd467a8c6667f6130749d82)

----
url: https://www.selenium.dev/ja/_print/documentation/webdriver/browsers/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/webdriver/browsers/).

# 対応ブラウザ

* 1: [Chrome固有の機能](#pg-aca938f5b5b240481e1161b5fd46a7ad)
* 2: [Edge固有の機能](#pg-8c748782863b194b39c04858a32ed168)
* 3: [Firefox特有の機能](#pg-6321659892ca24de2c4bce043831e793)
* 4: [IE特有の機能](#pg-659c5a89550ff75d0449c9df9786ae68)
* 5: [Safari特有の機能](#pg-7d4d9b9fd8c3987b8738d9549ca1c4f7)

各ブラウザにはカスタム機能とユニークな特徴があります。

# 1 - Chrome固有の機能

```java
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L36-L37)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L9-L10)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L30-L31)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L51-L55)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_argument("--start-maximized")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L18)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L39)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.args << '--start-maximized'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L17)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L9-L12)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L53)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.binary_location = chrome_bin
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L29)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L49)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.add_argument('--disable-dev-shm-usage')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L27)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L41-L44)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
  @DisabledOnOs(OS.WINDOWS)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L64)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_extension(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L40)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L73-L84)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L36)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L62-L66)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```py
    options.add_experimental_option("detach", True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L51)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

**注意**: これはすでに.NETのデフォルトの動作です。

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L45)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L29-L32)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L78)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L62)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L82)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L53)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L19-L22)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L100-L101)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Javaでは、システムプロパティによってファイル出力を設定することもできます：\
プロパティキー: `ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY`\
プロパティ値: ログファイルへのパスを表す文字列

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L71)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L86)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service = Selenium::WebDriver::Service.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L67)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L114-L115)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Javaでは、システムプロパティによってコンソール出力を設定することもできます。\
プロパティキー: `ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY`\
プロパティ値: `DriverService.LOG_STDOUT` または `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L82)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

`$stdout` と `$stderr` はどちらも有効な値です。

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service = Selenium::WebDriver::Service.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L76)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L129-L130)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Javaでは、システムプロパティによってログレベルを設定することもできます：\
プロパティキー: `ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY`\
プロパティ値: `ChromiumDriverLogLevel` 列挙型の文字列表現

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L93)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L87)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L147-L148)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Javaでは、これらの機能をシステムプロパティによって切り替えることもできます：\
プロパティキー: `ChromeDriverService.CHROME_DRIVER_APPEND_LOG_PROPERTY` および`ChromeDriverService.CHROME_DRIVER_READABLE_TIMESTAMP`\
プロパティ値: `"true"` または `"false"`

```py
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L104)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service = Selenium::WebDriver::Service.chrome(args: args)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L97-L98)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L166-L167)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Javaでは、システムプロパティによってビルドチェックを無効にすることもできます：\
プロパティキー: `ChromeDriverService.CHROME_DRIVER_DISABLE_BUILD_CHECK`\
プロパティ値: `"true"` または `"false"`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L115)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            service.DisableBuildCheck = true;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L155)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L108)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L230-L235)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L170-L174)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L119-L124)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L204-L210)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L129-L135)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
    it 'gets and sets network conditions' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L129)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L247)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    logs = driver.get_log("browser")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L186)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver = Selenium::WebDriver.for :chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L141)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    options.setBrowserVersion("stable");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L189)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    driver.set_permissions('camera', 'denied')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L149)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L149-L150)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### デベロッパー ツール

Chromeデベロッパーツールの使用に関する詳細については、\[Chromeデベロッパー ツール] セクションを参照してください。

# 2 - Edge固有の機能

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L38-L38)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options = get_default_edge_options()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L9-L10)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        {
            var options = new EdgeOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L30-L31)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let options = new edge.Options();
    driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/openEdgeTest.spec.js#L11-L15)

##### /examples/javascript/test/getting\_started/openEdgeTest.spec.js

```js
const {Browser, Builder} = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');


describe('Open Edge', function () {
  let driver;



  before(async function () {
    let options = new edge.Options();
    driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options)
      .build();
  });

  after(async () => await driver.quit());

  it('Basic Edge test', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
  public void arguments() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L46)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L18)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L39)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.args << '--start-maximized'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L17)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.addArguments('--headless=new'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L12)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```java
  public void setBrowserLocation() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L55)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L29)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L49)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.binary = edge_location
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L25)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L66)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L40)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L61)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.add_extension(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L34)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L55)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L51)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

**注意**: これはすでに.NETのデフォルトの動作です。

```rb
      options.detach = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L45)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.detachDriver(true))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L32)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```java
  public void excludeSwitches() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L79)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L62)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L76)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.exclude_switches << 'disable-popup-blocking'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L53)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L22)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```java
  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L101)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Javaでもシステムプロパティを使用してファイル出力を設定できます:\
プロパティキー: `EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY`\
プロパティ値: ログファイルのパスを表す文字列

```py
def test_log_to_file(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L71)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L86)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L67)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    File logLocation = getTempFile("logsToConsole", ".log");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L114)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注**: Javaでは、システムプロパティを使用してコンソール出力を設定することもできます。\
プロパティキー: `EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY`\
プロパティ値:`DriverService.LOG_STDOUT` または `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
def test_log_to_stdout(capfd):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L82)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

`$stdout` と `$stderr`はどちらも有効な値です。

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L76)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L127-L128)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Javaでは、システムプロパティを使用してログレベルを設定することもできます：\
プロパティキー: `EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY`\
プロパティ値:`ChromiumDriverLogLevel` 列挙型の文字列表現

```py
def test_log_level(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L93)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '--log-level=DEBUG'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L87)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L143-L144)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Javaでは、これらの機能をSystem Propertyによって切り替えることもできます：\
プロパティキー:`EdgeDriverService.EDGE_DRIVER_APPEND_LOG_PROPERTY` および `EdgeDriverService.EDGE_DRIVER_READABLE_TIMESTAMP`\
プロパティ値: `"true"` または `"false"`

```py
def test_log_features(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L104)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << '--append-log'
      service.args << '--readable-timestamp'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L97-L98)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L161-L162)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注**: Javaでは、システムプロパティを使用してビルドチェックを無効にすることもできます：\
プロパティキー:`EdgeDriverService.EDGE_DRIVER_DISABLE_BUILD_CHECK`\
プロパティ値: `"true"` または `"false"`

```py
def test_build_checks(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L115)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L155)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << '--disable-build-check'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L108)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L225-L230)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L170-L174)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L119-L123)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L198-L204)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L129-L135)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L129)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    consoleLogButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L242)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L186)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      sleep 1
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L141)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    EdgeDriver driver = new EdgeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L184)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L149)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L149-L150)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### DevTools

EdgeでDevToolsを使用する際の詳細については、\[Chrome DevTools]セクションを参照してください。

# 3 - Firefox特有の機能

```java
    driver = new FirefoxDriver(options);
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L36-L37)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L10-L11)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
        public void BasicOptions()
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L34-L35)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/openFirefoxTest.spec.js#L10-L13)

##### /examples/javascript/test/getting\_started/openFirefoxTest.spec.js

```js
const {Browser, Builder} = require('selenium-webdriver');
const firefox = require('selenium-webdriver/firefox');


describe('Open Firefox', function () {
  let driver;

  before(async function () {
    let options = new firefox.Options();
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options)
      .build();
  });

  after(async () => await driver.quit());

  it('Basic Firefox test', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options.add_argument("-headless")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L19)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            var options = new FirefoxOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L43)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options.args << '-headless'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L17)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
      .setFirefoxOptions(options.addArguments('--headless'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L12)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L54)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options.binary_location = firefox_bin
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L28)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            var options = new FirefoxOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L53)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options.binary = firefox_location
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L25)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
    driver = new FirefoxDriver(options);
  }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L211-L216)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L160-L168)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```csharp
var options = new FirefoxOptions();
var profile = new FirefoxProfile();
options.Profile = profile;
var driver = new RemoteWebDriver(options);
  
```

```rb
      profile = Selenium::WebDriver::Firefox::Profile.new
        profile['browser.download.dir'] = '/tmp/webdriver-downloads'
        options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L139-L141)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true
  
  require 'spec_helper'
  
  RSpec.describe 'Firefox' do
    describe 'Options' do
      let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }
  
      it 'basic options' do
        options = Selenium::WebDriver::Options.firefox
        @driver = Selenium::WebDriver.for :firefox, options: options
      end
  
      it 'add arguments' do
        options = Selenium::WebDriver::Options.firefox
  
        options.args << '-headless'
  
        @driver = Selenium::WebDriver.for :firefox, options: options
      end
  
      it 'sets location of binary' do
        options = Selenium::WebDriver::Options.firefox
  
        options.binary = firefox_location
  
        @driver = Selenium::WebDriver.for :firefox, options: options
      end
    end
  
    describe 'Service' do
      let(:file_name) { Tempfile.new('geckodriver').path }
      let(:root_directory) { Dir.mktmpdir }
  
      after do
        FileUtils.rm_f(file_name)
        FileUtils.rm_rf(root_directory)
      end
  
      it 'logs to file' do
        service = Selenium::WebDriver::Service.firefox
  
        service.log = file_name
  
        @driver = Selenium::WebDriver.for :firefox, service: service
        expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
      end
  
      it 'logs to console' do
        service = Selenium::WebDriver::Service.firefox
  
        service.log = $stdout
  
        expect {
          @driver = Selenium::WebDriver.for :firefox, service: service
        }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
      end
  
      it 'sets log level' do
        service = Selenium::WebDriver::Service.firefox
        service.log = file_name
  
        service.args += %w[--log debug]
  
        @driver = Selenium::WebDriver.for :firefox, service: service
        expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
      end
  
      it 'stops truncating log lines' do
        service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])
  
        service.args << '--log-no-truncate'
  
        @driver = Selenium::WebDriver.for :firefox, service: service
        expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
      end
  
      it 'sets default profile location' do
        service = Selenium::WebDriver::Service.firefox
  
        service.args += ['--profile-root', root_directory]
  
        @driver = Selenium::WebDriver.for :firefox, service: service
        profile_location = Dir.new(@driver.capabilities['moz:profile'])
        expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
      end
    end
  
    describe 'Features' do
      let(:driver) { start_firefox }
  
      it 'installs addon' do
        extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
  
        driver.install_addon(extension_file_path)
  
        driver.get 'https://www.selenium.dev/selenium/web/blank.html'
        injected = driver.find_element(id: 'webextensions-selenium-example')
        expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
      end
  
      it 'uninstalls addon' do
        extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
        extension_id = driver.install_addon(extension_file_path)
  
        driver.uninstall_addon(extension_id)
  
        driver.get 'https://www.selenium.dev/selenium/web/blank.html'
        expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
      end
  
      it 'installs unsigned addon' do
        extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)
  
        driver.install_addon(extension_dir_path, true)
  
        driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
        injected = driver.find_element(id: 'webextensions-selenium-example')
        expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
      end
  
      it 'takes full page screenshot' do
        driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
        Dir.mktmpdir('screenshot_test') do |dir|
          screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))
  
          expect(screenshot).to be_a File
        end
      end
  
      it 'sets the context' do
        driver.context = 'content'
        expect(driver.context).to eq 'content'
      end
    end
  
    describe 'Profile' do
      it 'creates a new profile' do
        profile = Selenium::WebDriver::Firefox::Profile.new
        profile['browser.download.dir'] = '/tmp/webdriver-downloads'
        options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
        expect(options.profile).to eq(profile)
      end
    end
  
    def driver_finder
      options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
      service = Selenium::WebDriver::Service.firefox
      finder = Selenium::WebDriver::DriverFinder.new(options, service)
      ENV['GECKODRIVER_BIN'] = finder.driver_path
      ENV['FIREFOX_BIN'] = finder.browser_path
    end
  end
  
```

```javascript
const { Builder } = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');

const options = new firefox.Options();
let profile = '/path to custom profile';
options.setProfile(profile);
const driver = new Builder()
    .forBrowser('firefox')
    .setFirefoxOptions(options)
    .build();
  
```

```kotlin
val options = FirefoxOptions()
options.profile = FirefoxProfile()
driver = RemoteWebDriver(options)
  
```

```java
        new GeckoDriverService.Builder().withLogFile(logLocation).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L62-L63)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**注**: Java では、システムプロパティによってファイル出力を設定することもできます。\
プロパティキー:`GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY`\
プロパティ値: ログファイルへのパスを表す文字列

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L36)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L43)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withLogOutput(System.out).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L76-L77)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**注意**: Javaは、システムプロパティを使用してコンソール出力を設定することもできます;\
プロパティキー: `GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY`\
プロパティ値: `DriverService.LOG_STDOUT` または `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L48)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L52)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L90-L91)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**注意**: Javaは、システムプロパティによってログレベルの設定も可能です:\
プロパティキー: `GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY`\
プロパティ値:`FirefoxDriverLogLevel`列挙型の文字列表現

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L59)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args += %w[--log debug]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L63)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L106-L107)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**注意**: Javaでは、システムプロパティによってログレベルを設定することもできます。\
プロパティキー: `GeckoDriverService.GECKO_DRIVER_LOG_NO_TRUNCATE`\
プロパティ値: `"true"` または `"false"`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L70)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '--log-no-truncate'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L72)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L118-L119)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**注意**: Javaでは、システムプロパティを使用してログレベルを設定することもできます：\
プロパティキー: `GeckoDriverService.GECKO_DRIVER_PROFILE_ROOT`\
プロパティ値: プロファイルルートディレクトリへのパスを表す文字列

```py
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L81)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args += ['--profile-root', root_directory]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L81)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L133)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.install_addon(addon_path_xpi)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L94)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L137)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      driver.install_addon(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L95)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    let id = await driver.installAddon(xpiPath);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L25)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L148)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.uninstall_addon(id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L106)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```cs
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L152)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      driver.uninstall_addon(extension_id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L106)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    await driver.uninstallAddon(id);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L26)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L160)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.install_addon(addon_path_dir, temporary=True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L115)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```cs
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L165)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```rb
      driver.install_addon(extension_dir_path, true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L115)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    let id = await driver.installAddon(xpiPath, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L41)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L181)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.save_full_page_screenshot("full_page_screenshot.png")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L139)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L125)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
    // Verify the context is back to "content"
    Assertions.assertEquals(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L197-L198)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L151-L152)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      driver.context = 'content'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L132)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

**Note**: As of Firefox 138, geckodriver needs to be started with the argument `--allow-system-access` to switch the context to `CHROME`.

# 4 - IE特有の機能

```java
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#38-L41)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

```py
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L11-L14)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L35-L38)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

```rb
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L17-L20)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#46-L47)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

```py
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L21-L22)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L44-L45)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L24-L25)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
let driver = await new Builder()
.forBrowser('internet explorer')
.setIEOptions(options)
.build();
```

```kotlin
<p><a href=/documentation/about/contributing/#moving-examples>
<span class="selenium-badge-code" data-bs-toggle="tooltip" data-bs-placement="right"
      title="One or more of these examples need to be implemented in the examples directory; click for details in the contribution guide">Move Code</span></a></p>


val options = InternetExplorerOptions()
val driver = InternetExplorerDriver(options)
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.waitForUploadDialogUpTo(Duration.ofSeconds(2));
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L28-L29)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.FileUploadDialogTimeout = TimeSpan.FromMilliseconds(2000);
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.file_upload_dialog_timeout = 2000
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L29)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().fileUploadDialogTimeout(2000);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.waitForUploadDialogUpTo(Duration.ofSeconds(2))
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.destructivelyEnsureCleanSession();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ensure_clean_session = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L38-L39)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.EnsureCleanSession = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ensure_clean_session = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L35)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().ensureCleanSession(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.destructivelyEnsureCleanSession()
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.ignoreZoomSettings();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L48-L49)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.IgnoreZoomLevel = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ignore_zoom_level = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L41)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().ignoreZoomSetting(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.ignoreZoomSettings()
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.introduceFlakinessByIgnoringSecurityDomains();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L58-L59)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.IntroduceInstabilityByIgnoringProtectedModeSettings = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ignore_protected_mode_settings = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L47)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().introduceFlakinessByIgnoringProtectedModeSettings(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.introduceFlakinessByIgnoringSecurityDomains()
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.setCapability("silent", true);
WebDriver driver = new InternetExplorerDriver(options);
  
```

```py
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L68-L69)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
InternetExplorerOptions options = new InternetExplorerOptions();
options.AddAdditionalInternetExplorerOption("silent", true);
IWebDriver driver = new InternetExplorerDriver(options);
  
```

```rb
      @options.silent = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L53)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const {Builder,By, Capabilities} = require('selenium-webdriver');
let caps = Capabilities.ie();
caps.set('silent', true);

(async function example() {
    let driver = await new Builder()
        .forBrowser('internet explorer')
        .withCapabilities(caps)
        .build();
    try {
        await driver.get('http://www.google.com/ncr');
    }
    finally {
        await driver.quit();
    }
})();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.setCapability("silent", true)
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  
```

```java
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;

public class ieTest {
    public static void main(String[] args) {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.useCreateProcessApiToLaunchIe();
        options.addCommandSwitches("-k");
        InternetExplorerDriver driver = new InternetExplorerDriver(options);
        try {
            driver.get("https://google.com/ncr");
            Capabilities caps = driver.getCapabilities();
            System.out.println(caps);
        } finally {
            driver.quit();
        }
    }
}
  
```

```py
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L76-L79)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;

namespace ieTest {
 class Program {
  static void Main(string[] args) {
   InternetExplorerOptions options = new InternetExplorerOptions();
   options.ForceCreateProcessApi = true;
   options.BrowserCommandLineArguments = "-k";
   IWebDriver driver = new InternetExplorerDriver(options);
   driver.Url = "https://google.com/ncr";
  }
 }
}
  
```

```rb
      @options.add_argument('-k')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L58)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options();
options.addBrowserCommandSwitches('-k');
options.addBrowserCommandSwitches('-private');
options.forceCreateProcessApi(true);

driver = await env.builder()
          .setIeOptions(options)
          .build();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.useCreateProcessApiToLaunchIe()
    options.addCommandSwitches("-k")
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps);
    } finally {
        driver.quit()
    }
}
  
```

```java
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;

public class ieTest {
    public static void main(String[] args) {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.useCreateProcessApiToLaunchIe();
        InternetExplorerDriver driver = new InternetExplorerDriver(options);
        try {
            driver.get("https://google.com/ncr");
            Capabilities caps = driver.getCapabilities();
            System.out.println(caps);
        } finally {
            driver.quit();
        }
    }
}
  
```

```py
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L87-L90)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;

namespace ieTest {
 class Program {
  static void Main(string[] args) {
   InternetExplorerOptions options = new InternetExplorerOptions();
   options.ForceCreateProcessApi = true;
   IWebDriver driver = new InternetExplorerDriver(options);
   driver.Url = "https://google.com/ncr";
  }
 }
}
  
```

```rb
      @options.force_create_process_api = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L63)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options();
options.forceCreateProcessApi(true);

driver = await env.builder()
          .setIeOptions(options)
          .build();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.useCreateProcessApiToLaunchIe()
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}

  
```

```java
                .withLogFile(getLogLocation())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L53)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY`\
Property value: String representing path to log file

```py
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L97-L99)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L82)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
                .withLogOutput(System.out)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L67)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L109-L111)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L91)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L82)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGLEVEL_PROPERTY`\
Property value: String representation of `InternetExplorerDriverLogLevel.DEBUG.toString()` enum

```py
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L121-L123)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            if (_tempPath == null || !File.Exists(_tempPath))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L85)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '-log-level=WARN'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L102)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
                .withExtractPath(getTempDirectory())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L94)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

\*\*Note\*\*: Java also allows setting log level by System Property:\ Property key: \`InternetExplorerDriverService.IE\_DRIVER\_EXTRACT\_PATH\_PROPERTY\`\ Property value: String representing path to supporting files directory

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L133-L135)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L98)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << "–extract-path=#{root_directory}"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L112)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

# 5 - Safari特有の機能

これらは、Apple Safariブラウザに特有の機能と機能です。

Unlike Chromium and Firefox drivers, the safaridriver is installed with the Operating System. To enable automation on Safari, run the following command from the terminal:

```shell
safaridriver --enable
```

```java
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#24-L25)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

```py
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L9-L10)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

```cs
            var options = new SafariOptions();
            driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/SafariTest.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/Browsers/SafariTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Safari;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("OSX")]
    public class SafariTest
    {
        private SafariDriver driver;

        [TestCleanup]
        public void QuitDriver()
        {
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new SafariOptions();
            driver = new SafariDriver(options);
        }
    }
}
```

```rb
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L8-L9)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

```js
    let driver = new Builder()
      .forBrowser(Browser.SAFARI)
      .setSafariOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/safariSpecificCap.spec.js#L8-L11)

##### /examples/javascript/test/browser/safariSpecificCap.spec.js

```js
const safari = require('selenium-webdriver/safari');
const {Browser, Builder} = require("selenium-webdriver");
const options = new safari.Options();
const process  =  require('node:process');

describe('Should be able to Test Command line arguments', function () {
  (process.platform === 'darwin' ? it : it.skip)('safari caps', async function () {
    let driver = new Builder()
      .forBrowser(Browser.SAFARI)
      .setSafariOptions(options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
val options = SafariOptions()
val driver = SafariDriver(options)
```

```java
                .withLogging(true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `SafariDriverService.SAFARI_DRIVER_LOGGING`\
Property value: `"true"` or `"false"`

[Selenium v4.26](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.26.0)

```py
    service = webdriver.SafariService(enable_logging=True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L17)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L20)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

```java
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#L39-L40)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

```py
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L25-L30)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L38-L39)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

----
url: https://www.selenium.dev/_print/documentation/grid/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/grid/).

# Grid

Want to run tests in parallel across multiple machines? Then, Grid is for you.

* 1: [Getting started with Selenium Grid](#pg-b65420f0b17cd83a52cb3a727d5dd688)
* 2: [When to Use Grid](#pg-0b04eda1b3eb8ca7f1a0da30d5475930)
* 3: [Selenium Grid Components](#pg-01cd7005c9fe890b652a752e84202045)
* 4: [Configuration of Components](#pg-aedd7c21b1dab64fd01a997c34bd16fe)
* * 4.1: [Configuration help](#pg-b0833a230d156d49a170ccaf66b15c1e)
  * 4.2: [CLI options in the Selenium Grid](#pg-06c8cbccc2ebce678b8300b1dbf16cfa)
  * 4.3: [TOML configuration options](#pg-84bc4f2f9f496018f9d4d76137abb5a3)
  5: [Grid architecture](#pg-ddd942d3d6b672c0dd5dcde8e4533a63)
* 6: [Advanced features of Selenium](#pg-1465ecf2a8678709289c8f006dc23784)
  * 6.1: [Observability in Selenium Grid](#pg-31c8fbb2badbe02b79aa5e8066e4dbb4)
  * 6.2: [GraphQL query support](#pg-76186a5d24597c9acf1bcb112d5b8cb6)
  * 6.3: [Grid endpoints](#pg-69471da8f601bc6b170f1ec47d69f853)
  * 6.4: [Customizing a Node](#pg-abdf1d3e182274141e4d8a3e7686dcf8)
  * 6.5: [External datastore](#pg-fe0209b2f377f5b9f5e592aade250b62)

Selenium Grid allows the execution of WebDriver scripts on remote machines by routing commands sent by the client to remote browser instances.

Grid aims to:

* Provide an easy way to run tests in parallel on multiple machines
* Allow testing on different browser versions
* Enable cross platform testing

Interested? Go through the following sections to understand how Grid works, and how to set up your own.

# 1 - Getting started with Selenium Grid

Instructions for a simple Selenium Grid

## Quick start

1. Prerequisites

   * Java 11 or higher installed

   * Browser(s) installed

   * Browser driver(s)

     * [Selenium Manager](https://www.selenium.dev/documentation/selenium_manager/) will configure the drivers automatically if you add `--selenium-manager true`.
     * [Installed and on the `PATH`](https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location/#use-the-path-environment-variable)

```shell
java -jar selenium-server-<version>.jar standalone
```

```shell
java -jar selenium-server-<version>.jar hub
```

By default, the server will listen for `RemoteWebDriver` requests on <http://localhost:4444>.

#### Node

During startup time, the **Node** will detect the available drivers that it can use from the System [`PATH`](https://www.selenium.dev/documentation/webdriver/troubleshooting/errors/driver_location/#use-the-path-environment-variable).

The command below assumes the **Node** is running on the same machine where the **Hub** is running.

```shell
java -jar selenium-server-<version>.jar node
```

##### More than one Node on the same machine

**Node** 1

```shell
java -jar selenium-server-<version>.jar node --port 5555
```

**Node** 2

```shell
java -jar selenium-server-<version>.jar node --port 6666
```

##### Node and Hub on different machines

**Hub** and **Nodes** talk to each other via HTTP and the [**Event Bus**](https://www.selenium.dev/documentation/grid/components/#event-bus) (the **Event Bus** lives inside the **Hub**). A **Node** sends a message to the **Hub** via the **Event Bus** to start the registration process. When the **Hub** receives the message, reaches out to the **Node** via HTTP to confirm its existence.

To successfully register a **Node** to a **Hub**, it is important to expose the **Event Bus** ports (4442 and 4443 by default) on the **Hub** machine. This also applies for the **Node** port. With that, both **Hub** and **Node** will be able to communicate.

If the **Hub** is using the default ports, the `--hub` flag can be used to register the **Node**

```shell
java -jar selenium-server-<version>.jar node --hub http://<hub-ip>:4444
```

When the **Hub** is not using the default ports, the `--publish-events` and `--subscribe-events` flags are needed.

For example, if the **Hub** uses ports `8886`, `8887`, and `8888`

```shell
java -jar selenium-server-<version>.jar hub --publish-events tcp://<hub-ip>:8886 --subscribe-events tcp://<hub-ip>:8887 --port 8888
```

The **Node** needs to use those ports to register successfully

```shell
java -jar selenium-server-<version>.jar node --publish-events tcp://<hub-ip>:8886 --subscribe-events tcp://<hub-ip>:8887
```

### Distributed

When using a Distributed Grid, each component is started separately, and ideally on different machines.

It is important to expose all ports properly in order to allow fluent communication between all components.

1. **Event Bus**: enables internal communication between different Grid components.

Default ports are: `4442`, `4443`, and `5557`.

```shell
java -jar selenium-server-<version>.jar event-bus --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --port 5557
```

2. **New Session Queue**: adds new session requests to a queue, which will be queried by the Distributor

Default port is `5559`.

```shell
java -jar selenium-server-<version>.jar sessionqueue --port 5559
```

3. **Session Map**: maps session IDs to the **Node** where the session is running

Default **Session Map** port is `5556`. **Session Map** interacts with the **Event Bus**.

```shell
java -jar selenium-server-<version>.jar sessions --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --port 5556
```

4. **Distributor**: queries the **New Session Queue** for new session requests, and assigns them to a **Node** when the capabilities match. **Nodes** register to the **Distributor** the way they register to the **Hub** in a **Hub/Node** Grid.

Default **Distributor** port is `5553`. **Distributor** interacts with **New Session Queue**, **Session Map**, **Event Bus**, and the **Node(s)**.

```shell
java -jar selenium-server-<version>.jar distributor --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --sessions http://<sessions-ip>:5556 --sessionqueue http://<new-session-queue-ip>:5559 --port 5553 --bind-bus false
```

5. **Router**: redirects new session requests to the queue, and redirects running sessions requests to the **Node** running that session.

Default **Router** port is `4444`. **Router** interacts with **New Session Queue**, **Session Map**, and **Distributor**.

```shell
java -jar selenium-server-<version>.jar router --sessions http://<sessions-ip>:5556 --distributor http://<distributor-ip>:5553 --sessionqueue http://<new-session-queue-ip>:5559 --port 4444
```

6. **Node(s)**

Default **Node** port is `5555`.

```shell
java -jar selenium-server-<version>.jar node --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443
```

## Metadata in tests

Add metadata to your tests and consume it via [GraphQL](https://www.selenium.dev/documentation/grid/advanced_features/graphql_support/) or visualize parts of it (like `se:name`) through the Selenium Grid UI.

Metadata can be added by prefixing a capability with `se:`. Here is a quick example in Java showing that.

```java
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setCapability("browserVersion", "100");
chromeOptions.setCapability("platformName", "Windows");
// Showing a test name instead of the session id in the Grid UI
chromeOptions.setCapability("se:name", "My simple test"); 
// Other type of metadata can be seen in the Grid UI by clicking on the 
// session info or via GraphQL
chromeOptions.setCapability("se:sampleMetadata", "Sample metadata value"); 
WebDriver driver = new RemoteWebDriver(new URL("http://gridUrl:4444"), chromeOptions);
driver.get("http://www.google.com");
driver.quit();
```

```bash
java -Dwebdriver.http.factory=jdk-http-client -jar selenium-server-<version>.jar --ext selenium-http-jdk-client-<version>.jar standalone
```

An alternative to downloading the `selenium-http-jdk-client` jar file is to use [Coursier](https://get-coursier.io/docs/cli-installation).

```bash
java -Dwebdriver.http.factory=jdk-http-client -jar selenium-server-<version>.jar --ext $(coursier fetch -p org.seleniumhq.selenium:selenium-http-jdk-client:<version>) standalone
```

# 2 - When to Use Grid

```
   15      *       45s        /        1        =      11m 15s   // Without Grid
   15      *       45s        /        5        =      2m 15s    // Grid with 5 Nodes
   15      *       45s        /        15       =      45s       // Grid with 15 Nodes
  100      *       120s       /        15       =      13m 20s   // Would take over 3 hours without Grid
```

As the test suite is executing, the Grid allocates the tests to run against these browsers as configured in the tests.

A configuration such as this can greatly speed up the execution time of even the largest Selenium test suites.

Selenium Grid is a completely native part of the Selenium project, and is maintained in parallel by the same team of committers who work in the core Selenium development. Recognizing the importance of test execution speed, Grid has been a critical part of the Selenium project since the earliest days.

# 3 - Selenium Grid Components

# 4 - Configuration of Components

Here you can see how each Grid component can be configured individually based on common configuration values and component-specific configuration values.

# 4.1 - Configuration help

```shell
java -jar selenium-server-<version>.jar info config
```

### Security

To get details on setting up the Grid servers for secure communication and node registration:

```shell
java -jar selenium-server-<version>.jar info security
```

### Session Map setup

By default, Grid uses a local session map to store session information. Grid supports additional storage options like Redis and JDBC - SQL supported databases. To set up different session storage, use the following command to get setup steps:

```shell
java -jar selenium-server-<version>.jar info sessionmap
```

### Setting up tracing with OpenTelemetry and Jaeger

By default, tracing is enabled. To export traces and visualize them via Jaeger, use the following command for instructions:

```shell
java -jar selenium-server-<version>.jar info tracing
```

## List the Selenium Grid commands

```shell
java -jar selenium-server-<version>.jar --config-help
```

It will show all the available commands and description for each one.

## Component help commands

Pass –help config option after the Selenium role to get component-specific config information.

### Standalone

```shell
java -jar selenium-server-<version>.jar standalone --help
```

### Hub

```shell
java -jar selenium-server-<version>.jar hub --help
```

### Sessions

```shell
java -jar selenium-server-<version>.jar sessions --help
```

### New Session Queue

```shell
java -jar selenium-server-<version>.jar sessionqueue --help
```

### Distributor

```shell
java -jar selenium-server-<version>.jar distributor --help
```

### Router

```shell
java -jar selenium-server-<version>.jar router --help
```

### Node

```shell
java -jar selenium-server-<version>.jar node --help
```

# 4.2 - CLI options in the Selenium Grid

All Grid components configuration CLI options in detail.

Different sections are available to configure a Grid. Each section has options can be configured through command line arguments.

A complete description of the component to section mapping can be seen below.

Note that this documentation could be outdated if an option was modified or added but has not been documented yet. In case you bump into this situation, please check the [“Config help”](https://www.selenium.dev/documentation/grid/configuration/help/) section and feel free to send us a pull request updating this page.

## Sections

|                               | Standalone | Hub | Node | Distributor | Router | Sessions | SessionQueue |
| ----------------------------- | ---------- | --- | ---- | ----------- | ------ | -------- | ------------ |
| [Distributor](#distributor)   | **         | **  |      | **          | **     |          |              |
| [Docker](#docker)             | **         |     | **   |             |        |          |              |
| [Kubernetes](#kubernetes)     | **         |     | **   |             |        |          |              |
| [Events](#events)             |            | **  | **   | **          |        | **       | **           |
| [Logging](#logging)           | **         | **  | **   | **          | **     | **       | **           |
| [Network](#network)           | **         | **  |      |             | **     |          |              |
| [Node](#node)                 | **         |     | **   |             |        |          |              |
| [Router](#router)             | **         | **  |      |             | **     |          |              |
| [Relay](#relay)               | **         |     | **   |             |        |          |              |
| [Server](#server)             | **         | **  | **   | **          | **     | **       | **           |
| [SessionQueue](#sessionqueue) | **         | **  |      | **          | **     |          | **           |
| [Sessions](#sessions)         |            |     |      | **          | **     | **       |              |

### Distributor

| Option                         | Type    | Value/Example                                                       | Description                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| ------------------------------ | ------- | ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--healthcheck-interval`       | int     | `120`                                                               | How often, in seconds, will the health check run for all Nodes. This ensures the server can ping all the Nodes successfully.                                                                                                                                                                                                                                                                                                                        |
| `--distributor`                | uri     | `http://localhost:5553`                                             | Url of the distributor.                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `--distributor-host`           | string  | `localhost`                                                         | Host on which the distributor is listening.                                                                                                                                                                                                                                                                                                                                                                                                         |
| `--distributor-implementation` | string  | `org.openqa.selenium.grid.distributor.local.LocalDistributor`       | Full class name of non-default distributor implementation                                                                                                                                                                                                                                                                                                                                                                                           |
| `--distributor-port`           | int     | `5553`                                                              | Port on which the distributor is listening.                                                                                                                                                                                                                                                                                                                                                                                                         |
| `--reject-unsupported-caps`    | boolean | `false`                                                             | Allow the Distributor to reject a request immediately if the Grid does not support the requested capability. Rejecting requests immediately is suitable for a Grid setup that does not spin up Nodes on demand.                                                                                                                                                                                                                                     |
| `--slot-matcher`               | string  | `org.openqa.selenium.grid.data.DefaultSlotMatcher`                  | Full class name of non-default slot matcher to use. This is used to determine whether a Node can support a particular session.                                                                                                                                                                                                                                                                                                                      |
| `--slot-selector`              | string  | `org.openqa.selenium.grid.distributor.selector.DefaultSlotSelector` | Full class name of non-default slot selector. This is used to select a slot in a Node once the Node has been matched.                                                                                                                                                                                                                                                                                                                               |
| `--newsession-threadpool-size` | int     | `24`                                                                | The Distributor uses a fixed-sized thread pool to create new sessions as it consumes new session requests from the queue. This allows configuring the size of the thread pool. The default value is no. of available processors \* 3. Note: If the no. of threads is way greater than the available processors it will not always increase the performance. A high number of threads causes more context switching which is an expensive operation. |
| `--purge-nodes-interval`       | int     | `30`                                                                | How often, in seconds, will the Distributor purge Nodes that have been down for a while. This is calculated based on the heartbeat received from a particular node.                                                                                                                                                                                                                                                                                 |

### Docker

| Option                          | Type      | Value/Example                                                     | Description                                                                                                                                                                                                                                                                                 |
| ------------------------------- | --------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--docker-assets-path`          | string    | `/opt/selenium/assets`                                            | Absolute path where assets will be stored                                                                                                                                                                                                                                                   |
| `--docker` / `-D`               | string\[] | `selenium/standalone-firefox:latest '{"browserName": "firefox"}'` | Docker configs which map image name to stereotype capabilities (example: `-D selenium/standalone-firefox:latest '{"browserName": "firefox"}'`)                                                                                                                                              |
| `--docker-devices`              | string\[] | `/dev/kvm:/dev/kvm`                                               | Exposes devices to a container. Each device mapping declaration must have at least the path of the device in both host and container separated by a colon like in this example: /device/path/in/host:/device/path/in/container                                                              |
| `--docker-host`                 | string    | `localhost`                                                       | Host name where the Docker daemon is running                                                                                                                                                                                                                                                |
| `--docker-port`                 | int       | `2375`                                                            | Port where the Docker daemon is running                                                                                                                                                                                                                                                     |
| `--docker-url`                  | string    | `http://localhost:2375`                                           | URL for connecting to the Docker daemon                                                                                                                                                                                                                                                     |
| `--docker-video-image`          | string    | `selenium/video:latest`                                           | Docker image to be used when video recording is enabled                                                                                                                                                                                                                                     |
| `--docker-host-config-keys`     | string\[] | `Dns DnsOptions DnsSearch ExtraHosts Binds`                       | Specify which docker host configuration keys should be passed to browser containers. Keys name can be found in the Docker API [documentation](https://docs.docker.com/engine/api/v1.41/#tag/Container/operation/ContainerCreate), or by running `docker inspect` the node-docker container. |
| `--docker-api-version`          | string    | `1.40`                                                            | Docker API version to use. Pin a specific API version instead of relying on auto-detection by the implementation.                                                                                                                                                                           |
| `--docker-server-start-timeout` | int       | `55`                                                              | Max time (in seconds) to wait for the browser server to successfully start up inside the container, before cancelling the process.                                                                                                                                                          |
| `--docker-grouping-labels`      | string\[] | `azure.container.group aws.ecs.cluster`                           | Custom labels used for grouping dynamic containers. Makes the system more flexible for different platforms and use cases.                                                                                                                                                                   |

### Kubernetes

| Option                                  | Type      | Value/Example                                                     | Description                                                                                                                                                                                                                                                                    |
| --------------------------------------- | --------- | ----------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--kubernetes-url`                      | string    | `"https://my-k8s-cluster:6443"`                                   | Kubernetes API server URL. When set, connects to a remote cluster instead of using in-cluster or kubeconfig auto-discovery.                                                                                                                                                    |
| `--kubernetes-configs` / `-K`           | string\[] | `selenium/standalone-firefox:latest '{"browserName": "firefox"}'` | Kubernetes configs which map image name to stereotype capabilities (example: `-K selenium/standalone-firefox:latest '{"browserName": "firefox"}'`). Use `configmap:[namespace/]<name>` as the key to load a Job template from a Kubernetes ConfigMap instead of an image name. |
| `--kubernetes-namespace`                | string    | `"selenium"`                                                      | Kubernetes namespace to create browser Jobs in. Auto-detected from the client when running in-cluster if not set.                                                                                                                                                              |
| `--kubernetes-service-account`          | string    | `"selenium-session"`                                              | Override service account for browser Jobs. Auto-inherited from the Node Pod when running in K8s.                                                                                                                                                                               |
| `--kubernetes-image-pull-policy`        | string    | `"IfNotPresent"`                                                  | Override image pull policy for browser containers (`Always`, `IfNotPresent`, `Never`). Auto-inherited from the Node Pod when running in K8s.                                                                                                                                   |
| `--kubernetes-server-start-timeout`     | int       | `120`                                                             | Max time (in seconds) to wait for the browser server to start up in the K8s Pod.                                                                                                                                                                                               |
| `--kubernetes-termination-grace-period` | int       | `30`                                                              | Seconds to wait for containers to shut down gracefully before force-killing them.                                                                                                                                                                                              |
| `--kubernetes-resource-requests`        | string    | `"cpu=500m,memory=512Mi"`                                         | Override resource requests for browser containers (comma-separated `key=value` pairs). Auto-inherited from the Node Pod when running in K8s.                                                                                                                                   |
| `--kubernetes-resource-limits`          | string    | `"cpu=1,memory=1Gi"`                                              | Override resource limits for browser containers (comma-separated `key=value` pairs). Auto-inherited from the Node Pod when running in K8s.                                                                                                                                     |
| `--kubernetes-node-selector`            | string    | `"disktype=ssd,region=us-west"`                                   | Override node selector for scheduling browser Pods (comma-separated `key=value` pairs). Auto-inherited from the Node Pod when running in K8s.                                                                                                                                  |
| `--kubernetes-video-image`              | string    | `"selenium/video:latest"`                                         | Container image to use as a video recording sidecar. Set to `false` to disable video recording (default).                                                                                                                                                                      |
| `--kubernetes-assets-path`              | string    | `"/opt/selenium/assets"`                                          | Absolute path where session assets will be stored.                                                                                                                                                                                                                             |
| `--kubernetes-label-inherit-prefix`     | string    | `"se/"`                                                           | Prefix filter for inheriting labels/annotations from the Node Pod to browser Jobs. Only labels/annotations whose keys start with this prefix are inherited. An empty string inherits all.                                                                                      |

### Events

| Option                        | Type    | Value/Example                                      | Description                                                                                                                                                                                                                                                                         |
| ----------------------------- | ------- | -------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--bind-bus`                  | boolean | `false`                                            | Whether the connection string should be bound or connected. When true, the component will be bound to the Event Bus (as in the Event Bus will also be started by the component, typically by the Distributor and the Hub). When false, the component will connect to the Event Bus. |
| `--events-implementation`     | string  | `org.openqa.selenium.events.zeromq.ZeroMqEventBus` | Full class name of non-default event bus implementation                                                                                                                                                                                                                             |
| `--publish-events`            | string  | `tcp://*:4442`                                     | Connection string for publishing events to the event bus                                                                                                                                                                                                                            |
| `--subscribe-events`          | string  | `tcp://*:4443`                                     | Connection string for subscribing to events from the event bus                                                                                                                                                                                                                      |
| `--eventbus-heartbeat-period` | int     | `30`                                               | How often, in seconds, will the EventBus socket send heartbeats.                                                                                                                                                                                                                    |

### Logging

| Option                   | Type    | Value/Example                                                                                                                                              | Description                                                                                                                                                            |
| ------------------------ | ------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--http-logs`            | boolean | `false`                                                                                                                                                    | Enable http logging. Tracing should be enabled to log http logs.                                                                                                       |
| `--log-encoding`         | string  | `UTF-8`                                                                                                                                                    | Log encoding                                                                                                                                                           |
| `--log`                  | string  | Windows path example : `'\path\to\file\gridlog.log'` or `'C:\path\path\to\file\gridlog.log'` Linux/Unix/MacOS path example : `'/path/to/file/gridlog.log'` | File to write out logs. Ensure the file path is compatible with the operating system’s file path.                                                                      |
| `--log-level`            | string  | `“INFO”`                                                                                                                                                   | Log level. Default logging level is INFO. Log levels are described here <https://docs.oracle.com/en/java/javase/11/docs/api/java.logging/java/util/logging/Level.html> |
| `--plain-logs`           | boolean | `true`                                                                                                                                                     | Use plain log lines                                                                                                                                                    |
| `--structured-logs`      | boolean | `false`                                                                                                                                                    | Use structured logs                                                                                                                                                    |
| `--tracing`              | boolean | `true`                                                                                                                                                     | Enable trace collection                                                                                                                                                |
| `--log-timestamp-format` | string  | `HH:mm:ss.SSS`                                                                                                                                             | Allows the configure log timestamp format                                                                                                                              |

### Network

| Option           | Type    | Value/Example | Description                                                                                                          |
| ---------------- | ------- | ------------- | -------------------------------------------------------------------------------------------------------------------- |
| `--relax-checks` | boolean | `false`       | Relax checks on origin header and content type of incoming requests, in contravention of strict W3C spec compliance. |

### Node

| Option                           | Type      | Value/Example                                                                                                                                                                                                                                                              | Description                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| -------------------------------- | --------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--detect-drivers`               | boolean   | `true`                                                                                                                                                                                                                                                                     | Autodetect which drivers are available on the current system, and add them to the Node.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `--driver-configuration`         | string\[] | `display-name="Firefox Nightly" max-sessions=2 webdriver-path="/usr/local/bin/geckodriver" stereotype="{\"browserName\": \"firefox\", \"browserVersion\": \"86\", \"moz:firefoxOptions\": {\"binary\":\"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"` | List of configured drivers a Node supports. It is recommended to provide this type of configuration through a toml config file to improve readability                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `--driver-factory`               | string\[] | `org.openqa.selenium.example.LynxDriverFactory '{"browserName": "lynx"}'`                                                                                                                                                                                                  | Mapping of fully qualified class name to a browser configuration that this matches against.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `--driver-implementation`        | string\[] | `"firefox"`                                                                                                                                                                                                                                                                | Drivers that should be checked. If specified, will skip autoconfiguration.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `--node-implementation`          | string    | `"org.openqa.selenium.grid.node.local.LocalNodeFactory"`                                                                                                                                                                                                                   | Full classname of non-default Node implementation. This is used to manage a session’s lifecycle.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        |
| `--grid-url`                     | string    | `https://grid.example.com`                                                                                                                                                                                                                                                 | Public URL of the Grid as a whole (typically the address of the Hub or the Router)                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `--heartbeat-period`             | int       | `60`                                                                                                                                                                                                                                                                       | How often, in seconds, will the Node send heartbeat events to the Distributor to inform it that the Node is up.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `--max-sessions`                 | int       | `8`                                                                                                                                                                                                                                                                        | Maximum number of concurrent sessions. Default value is the number of available processors.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             |
| `--override-max-sessions`        | boolean   | `false`                                                                                                                                                                                                                                                                    | The # of available processors is the recommended max sessions value (1 browser session per processor). Setting this flag to true allows the recommended max value to be overwritten. Session stability and reliability might suffer as the host could run out of resources.                                                                                                                                                                                                                                                                                                                             |
| `--register-cycle`               | int       | `10`                                                                                                                                                                                                                                                                       | How often, in seconds, the Node will try to register itself for the first time to the Distributor.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `--register-period`              | int       | `120`                                                                                                                                                                                                                                                                      | How long, in seconds, will the Node try to register to the Distributor for the first time. After this period is completed, the Node will not attempt to register again.                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `--session-timeout`              | int       | `300`                                                                                                                                                                                                                                                                      | Let X be the session-timeout in seconds. The Node will automatically kill a session that has not had any activity in the last X seconds. This will release the slot for other tests.                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `--vnc-env-var`                  | string\[] | `SE_START_XVFB SE_START_VNC SE_START_NO_VNC`                                                                                                                                                                                                                               | Environment variable to check in order to determine if a vnc stream is available or not.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `--no-vnc-port`                  | int       | `7900`                                                                                                                                                                                                                                                                     | If VNC is available, sets the port where the local noVNC stream can be obtained                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `--drain-after-session-count`    | int       | `1`                                                                                                                                                                                                                                                                        | Drain and shutdown the Node after X sessions have been executed. Useful for environments like Kubernetes. A value higher than zero enables this feature.                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `--hub`                          | string    | `http://localhost:4444`                                                                                                                                                                                                                                                    | The address of the Hub in a Hub-and-Node configuration. Can be a hostname or IP address (`hostname`), in which case the Hub will be assumed to be `http://hostname:4444`, the `--grid-url` will be the same `--publish-events` will be `tcp://hostname:4442` and `--subscribe-events` will be `tcp://hostname:4443`. If `hostname` contains a port number, that will be used for `--grid-url` but the URIs for the event bus will remain the same. Any of these default values may be overridden but setting the correct flags. If the hostname has a protocol (such as `https`) that will be used too. |
| `--enable-cdp`                   | boolean   | `true`                                                                                                                                                                                                                                                                     | Enable CDP proxying in Grid. A Grid admin can disable CDP if the network does not allow websockets. True by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `--enable-bidi`                  | boolean   | `true`                                                                                                                                                                                                                                                                     | Enable BiDi proxying in Grid. A Grid admin can disable BiDi if the network does not allow websockets. True by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| `--enable-managed-downloads`     | boolean   | `false`                                                                                                                                                                                                                                                                    | This causes the Node to auto manage files downloaded for a given session on the Node.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `--selenium-manager`             | boolean   | `false`                                                                                                                                                                                                                                                                    | When drivers are not available on the current system, use Selenium Manager. False by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                           |
| `--connection-limit-per-session` | int       | `10`                                                                                                                                                                                                                                                                       | Let X be the maximum number of websocket connections per session. This will ensure one session is not able to exhaust the connection limit of the host.                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `--delete-session-on-ui`         | boolean   | `false`                                                                                                                                                                                                                                                                    | Enable capability to support deleting a session via the Grid UI. False by default.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                      |
| `--register-shutdown-on-failure` | boolean   | `false`                                                                                                                                                                                                                                                                    | If enabled, the Node will shut down after the register period is completed without a successful registration. Useful in container environments to trigger a restart.                                                                                                                                                                                                                                                                                                                                                                                                                                    |
| `--node-down-failure-threshold`  | int       | `3`                                                                                                                                                                                                                                                                        | Maximum number of consecutive session creation failures before the Node is marked as DOWN. A value of `0` (default) disables this feature and allows unlimited retries.                                                                                                                                                                                                                                                                                                                                                                                                                                 |

### Relay

| Option                       | Type      | Value/Example                                                                                                     | Description                                                                                                                                                              |
| ---------------------------- | --------- | ----------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `--service-url`              | string    | `http://localhost:4723`                                                                                           | URL for connecting to the service that supports WebDriver commands like an Appium server or a cloud service.                                                             |
| `--service-host`             | string    | `localhost`                                                                                                       | Host name where the service that supports WebDriver commands is running                                                                                                  |
| `--service-port`             | int       | `4723`                                                                                                            | Port where the service that supports WebDriver commands is running                                                                                                       |
| `--service-status-endpoint`  | string    | `/status`                                                                                                         | Optional, endpoint to query the WebDriver service status, an HTTP 200 response is expected                                                                               |
| `--service-protocol-version` | string    | `HTTP/1.1`                                                                                                        | Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status                                                          |
| `--service-configuration`    | string\[] | `max-sessions=2 stereotype='{"browserName": "safari", "platformName": "iOS", "appium:platformVersion": "14.5"}}'` | Configuration for the service where calls will be relayed to. It is recommended to provide this type of configuration through a toml config file to improve readability. |

### Router

| Option         | Type    | Value/Example              | Description                                                                                                         |
| -------------- | ------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `--password`   | string  | `myStrongPassword`         | Password clients must use to connect to the server. Both this and the username need to be set in order to be used.  |
| `--username`   | string  | `admin`                    | User name clients must use to connect to the server. Both this and the password need to be set in order to be used. |
| `--sub-path`   | string  | `my_company/selenium_grid` | A sub-path that should be considered for all user facing routes on the Hub/Router/Standalone.                       |
| `--disable-ui` | boolean | `true`                     | Disable the Grid UI.                                                                                                |

### Server

| Option                  | Type    | Value/Example           | Description                                                                                                                                                                                                                                                                           |
| ----------------------- | ------- | ----------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--external-url`        | string  | `http://10.0.1.1:33333` | External URL where component is generally available. Useful on complex network topologies when components are on different networks and proxy servers are involved.                                                                                                                   |
| `--allow-cors`          | boolean | `true`                  | Whether the Selenium server should allow web browser connections from any host                                                                                                                                                                                                        |
| `--host`                | string  | `localhost`             | Server IP or hostname: usually determined automatically.                                                                                                                                                                                                                              |
| `--bind-host`           | boolean | `true`                  | Whether the server should bind to the host address/name, or only use it to" report its reachable url. Helpful in complex network topologies where the server cannot report itself with the current IP/hostname but rather an external IP or hostname (e.g. inside a Docker container) |
| `--https-certificate`   | path    | `/path/to/cert.pem`     | Server certificate for https. Get more detailed information by running “java -jar selenium-server.jar info security”                                                                                                                                                                  |
| `--https-private-key`   | path    | `/path/to/key.pkcs8`    | Private key for https. Get more detailed information by running “java -jar selenium-server.jar info security”                                                                                                                                                                         |
| `--max-threads`         | int     | `24`                    | Maximum number of listener threads. Default value is: (available processors) \* 3.                                                                                                                                                                                                    |
| `--port`                | int     | `4444`                  | Port to listen on. There is no default as this parameter is used by different components, for example, Router/Hub/Standalone will use 4444 and Node will use 5555.                                                                                                                    |
| `--registration-secret` | string  | `"Hunter2"`             | Shared secret used to authenticate Node registration requests. Must match the value set on the Hub/Distributor.                                                                                                                                                                       |

### SessionQueue

| Option                             | Type   | Value/Example           | Description                                                                                                                                                                            |
| ---------------------------------- | ------ | ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `--sessionqueue` / `--sq`          | uri    | `http://localhost:1237` | Address of the session queue server.                                                                                                                                                   |
| `--sessionqueue-host`              | string | `localhost`             | Host on which the session queue server is listening.                                                                                                                                   |
| `--sessionqueue-port`              | int    | `1234`                  | Port on which the session queue server is listening.                                                                                                                                   |
| `--session-request-timeout`        | int    | `300`                   | Timeout in seconds. A new incoming session request is added to the queue. Requests sitting in the queue for longer than the configured time will timeout.                              |
| `--session-request-timeout-period` | int    | `10`                    | How often, in seconds, the timeout for queued new session requests is checked.                                                                                                         |
| `--session-retry-interval`         | int    | `15`                    | Retry interval in milliseconds. If all slots are busy, new session request will be retried after the given interval.                                                                   |
| `--sessionqueue-batch-size`        | int    | `20`                    | Maximum number of session requests that can be consumed from the queue at a time, based on the available slots.                                                                        |
| `--maximum-response-delay`         | int    | `8`                     | How often, in seconds, will the SessionQueue respond in case there is no data, to reduce the http requests while polling for new session requests. (Config file only; not a CLI flag.) |

### Sessions

| Option            | Type   | Value/Example           | Description                                        |
| ----------------- | ------ | ----------------------- | -------------------------------------------------- |
| `--sessions`      | uri    | `http://localhost:1234` | Address of the session map server.                 |
| `--sessions-host` | string | `localhost`             | Host on which the session map server is listening. |
| `--sessions-port` | int    | `1234`                  | Port on which the session map server is listening. |

## Configuration examples

All the options mentioned above can be used when starting the Grid components. They are a good way of exploring the Grid options, and trying out values to find a suitable configuration.

We recommend the use of [Toml files](https://www.selenium.dev/documentation/grid/configuration/toml_options/) to configure a Grid. Configuration files improve readability, and you can also check them in source control.

When needed, you can combine a Toml file configuration with CLI arguments.

### Command-line flags

To pass config options as command-line flags, identify the valid options for the component and follow the template below.

```
java -jar selenium-server-<version>.jar <component> --<option> value
```

#### Standalone, setting max sessions and main port

```
java -jar selenium-server-<version>.jar standalone --max-sessions 4 --port 4444
```

#### Hub, setting a new session request timeout, a main port, and disabling tracing

```
java -jar selenium-server-<version>.jar hub --session-request-timeout 500 --port 3333 --tracing false
```

#### Node, with 4 max sessions, with debug(fine) log, 7777 as port, and only with Firefox and Edge

```
java -jar selenium-server-<version>.jar node --max-sessions 4 --log-level "fine" --port 7777 --driver-implementation "firefox" --driver-implementation "edge"
```

#### Distributor, setting Session Map server url, Session Queue server url, and disabling bus

```
java -jar selenium-server-<version>.jar distributor --sessions http://localhost:5556 --sessionqueue http://localhost:5559 --bind-bus false
```

#### Setting custom capabilities for matching specific Nodes

**Important:** Custom capabilities need to be set in the configuration in all Nodes. They also need to be included always in every session request.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node A with custom cap set to `true`

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":true}' --port 6161
```

##### Start the Node B with custom cap set to `false`

```
java -jar selenium-server-<version>.jar node --detect-drivers false --driver-configuration display-name="Chrome (custom capability true)" max-sessions=1 stereotype='{"browserName":"chrome","gsg:customcap":false}' --port 6262
```

##### Matching Node A

```java
ChromeOptions options = new ChromeOptions();
options.setCapability("gsg:customcap", true);
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

Set the custom capability to `false` in order to match the Node B.

#### Enabling Managed downloads by the Node

At times a test may need to access files that were downloaded by it on the Node. To retrieve such files, following can be done.

##### Start the Hub

```
java -jar selenium-server-<version>.jar hub
```

##### Start the Node with manage downloads enabled

```
java -jar selenium-server-<version>.jar node --enable-managed-downloads true
```

##### Set the capability at the test level

Tests that want to use this feature should set the capability `"se:downloadsEnabled"`to `true`

```java
options.setCapability("se:downloadsEnabled", true);
```

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

In the response the list of file names appear under the key `names`.

##### Dowloading a file:

* The endpoint to `POST` from is `/session/<sessionId>/se/files` with a payload of the form `{"name": "fileNameGoesHere}`
* The session needs to be active in order for the command to work.
* The raw response looks like below:

```json
{
	"value": {
		"filename": "Red-blue-green-channel.jpg",
		"contents": "Base64EncodedStringContentsOfDownloadedFileAsZipGoesHere"
	}
}
```

* The response blob contains two keys,

  * `filename` - The file name that was downloaded.
  * `contents` - Base64 encoded zipped contents of the file.

* The file contents are Base64 encoded and they need to be unzipped.

##### List files that can be downloaded

The below mentioned `curl` example can be used to list all the files that were downloaded by the current session in the Node, and which can be retrieved locally.

```bash
curl -X GET "http://localhost:4444/session/90c0149a-2e75-424d-857a-e78734943d4c/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "names": [
      "Red-blue-green-channel.jpg"
    ]
  }
}
```

##### Retrieve a downloaded file

Assuming the downloaded file is named `Red-blue-green-channel.jpg`, and using `curl`, the file could be downloaded with the following command:

```bash
curl -H "Accept: application/json" \
-H "Content-Type: application/json; charset=utf-8" \
-X POST -d '{"name":"Red-blue-green-channel.jpg"}' \
"http://localhost:4444/session/18033434-fa4f-4d11-a7df-9e6d75920e19/se/files"
```

A sample response would look like below:

```json
{
  "value": {
    "filename": "Red-blue-green-channel.jpg",
    "contents": "UEsDBBQACAgIAJpagVYAAAAAAAAAAAAAAAAaAAAAUmVkLWJsAAAAAAAAAAAAUmVkLWJsdWUtZ3JlZW4tY2hhbm5lbC5qcGdQSwUGAAAAAAEAAQBIAAAAcNkAAAAA"
  }
}
```

##### Complete sample code in Java

Below is an example in Java that does the following:

* Sets the capability to indicate that the test requires automatic managing of downloaded files.
* Triggers a file download via a browser.
* Lists the files that are available for retrieval from the remote node (These are essentially files that were downloaded in the current session)
* Picks one file and downloads the file from the remote node to the local machine.

```java
import com.google.common.collect.ImmutableMap;

import org.openqa.selenium.By;
import org.openqa.selenium.io.Zip;
import org.openqa.selenium.json.Json;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.HttpClient;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;

import java.io.File;
import java.net.URL;
import java.nio.file.Files;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.TimeUnit;

import static org.openqa.selenium.remote.http.Contents.asJson;
import static org.openqa.selenium.remote.http.Contents.string;
import static org.openqa.selenium.remote.http.HttpMethod.GET;
import static org.openqa.selenium.remote.http.HttpMethod.POST;

public class DownloadsSample {

  public static void main(String[] args) throws Exception {
    // Assuming the Grid is running locally.
    URL gridUrl = new URL("http://localhost:4444");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("se:downloadsEnabled", true);
    RemoteWebDriver driver = new RemoteWebDriver(gridUrl, options);
    try {
      demoFileDownloads(driver, gridUrl);
    } finally {
      driver.quit();
    }
  }

	private static void demoFileDownloads(RemoteWebDriver driver, URL gridUrl) throws Exception {
		driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
		// Download the two available files on the page
		driver.findElement(By.id("file-1")).click();
		driver.findElement(By.id("file-2")).click();

		// The download happens in a remote Node, which makes it difficult to know when the file
		// has been completely downloaded. For demonstration purposes, this example uses a
		// 10-second sleep which should be enough time for a file to be downloaded.
		// We strongly recommend to avoid hardcoded sleeps, and ideally, to modify your
		// application under test, so it offers a way to know when the file has been completely
		// downloaded.
		TimeUnit.SECONDS.sleep(10);

		//This is the endpoint which will provide us with list of files to download and also to
		//let us download a specific file.
		String downloadsEndpoint = String.format("/session/%s/se/files", driver.getSessionId());

		String fileToDownload;

		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To list all files that are were downloaded on the remote node for the current session
			// we trigger GET request.
			HttpRequest request = new HttpRequest(GET, downloadsEndpoint);
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			@SuppressWarnings("unchecked")
			List<String> names = (List<String>) value.get("names");
			// Let's say there were "n" files downloaded for the current session, we would like
			// to retrieve ONLY the first file.
			fileToDownload = names.get(0);
		}

		// Now, let's download the file
		try (HttpClient client = HttpClient.Factory.createDefault().createClient(gridUrl)) {
			// To retrieve a specific file from one or more files that were downloaded by the current session
			// on a remote node, we use a POST request.
			HttpRequest request = new HttpRequest(POST, downloadsEndpoint);
			request.setContent(asJson(ImmutableMap.of("name", fileToDownload)));
			HttpResponse response = client.execute(request);
			Map<String, Object> jsonResponse = new Json().toType(string(response), Json.MAP_TYPE);
			@SuppressWarnings("unchecked")
			Map<String, Object> value = (Map<String, Object>) jsonResponse.get("value");
			// The returned map would contain 2 keys,
			// filename - This represents the name of the file (same as what was provided by the test)
			// contents - Base64 encoded String which contains the zipped file.
			String zippedContents = value.get("contents").toString();
			// The file contents would always be a zip file and has to be unzipped.
			File downloadDir = Zip.unzipToTempDir(zippedContents, "download", "");
			// Read the file contents
			File downloadedFile = Optional.ofNullable(downloadDir.listFiles()).orElse(new File[]{})[0];
			String fileContent = String.join("", Files.readAllLines(downloadedFile.toPath()));
			System.out.println("The file which was "
					+ "downloaded in the node is now available in the directory: "
					+ downloadDir.getAbsolutePath() + " and has the contents: " + fileContent);
		}
	}


}
```

# 4.3 - TOML configuration options

```toml
[section1]
option1="value"

[section2]
option2=["value1","value2"]
option3=true
```

Below are some examples of Grid components configured with a Toml file, the component can be started in the following way:

```
java -jar selenium-server-<version>.jar <component> --config /path/to/file/<file-name>.toml
```

### Standalone

A Standalone server, running on port 4449, and a new session request timeout of 500 seconds.

```toml
[server]
port = 4449

[sessionqueue]
session-request-timeout = 500
```

### Specific browsers and a limit of max sessions

A Standalone server or a Node which only has Firefox and Chrome enabled by default.

```toml
[node]
drivers = ["chrome", "firefox"]
max-sessions = 3
```

### Configuring and customising drivers

Standalone or Node server with customised drivers, which allows things like having Firefox Beta or Nightly, and having different browser versions.

```toml
[node]
detect-drivers = false
[[node.driver-configuration]]
max-sessions = 100
display-name = "Firefox Nightly"
stereotype = "{\"browserName\": \"firefox\", \"browserVersion\": \"93\", \"platformName\": \"MAC\", \"moz:firefoxOptions\": {\"binary\": \"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"
[[node.driver-configuration]]
display-name = "Chrome Beta"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"94\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta\"}}"
[[node.driver-configuration]]
display-name = "Chrome Dev"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"95\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev\"}}"
webdriver-executable = '/path/to/chromedriver/95/chromedriver'
```

### Standalone or Node with Docker

A Standalone or Node server that is able to run each new session in a Docker container. Disabling drivers detection, having maximum 2 concurrent sessions. Stereotypes configured need to be mapped to a Docker image, and the Docker daemon needs to be exposed via http/tcp. In addition, it is possible to define which device files, accessible on the host, will be available in containers through the `devices` property. Refer to the [docker](https://docs.docker.com/engine/reference/commandline/run/#add-host-device-to-container---device) documentation for more information about how docker device mapping works.

```toml
[node]
detect-drivers = false
max-sessions = 2

[docker]
configs = [
    "selenium/standalone-chrome:93.0", "{\"browserName\": \"chrome\", \"browserVersion\": \"91\"}", 
    "selenium/standalone-firefox:92.0", "{\"browserName\": \"firefox\", \"browserVersion\": \"92\"}"
]
#Optionally define all device files that should be mapped to docker containers
#devices = [
#    "/dev/kvm:/dev/kvm"
#]
url = "http://localhost:2375"
video-image = "selenium/video:latest"
```

### Relaying commands to a service endpoint that supports WebDriver

It is useful to connect an external service that supports WebDriver to Selenium Grid. An example of such service could be a cloud provider or an Appium server. In this way, Grid can enable more coverage to platforms and versions not present locally.

The following is an en example of connecting an Appium server to Grid.

```toml
[node]
detect-drivers = false

[relay]
# Default Appium/Cloud server endpoint
url = "http://localhost:4723/wd/hub"
status-endpoint = "/status"
# Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status (e.g. HTTP/1.1, HTTP/2)
protocol-version = "HTTP/1.1"
# Stereotypes supported by the service. The initial number is "max-sessions", and will allocate 
# that many test slots to that particular configuration
configs = [
  "5", "{\"browserName\": \"chrome\", \"platformName\": \"android\", \"appium:platformVersion\": \"11\"}"
]
```

### Basic auth enabled

It is possible to protect a Grid with basic auth by configuring the Router/Hub/Standalone with a username and password. This user/password combination will be needed when loading the Grid UI or starting a new session.

```toml
[router]
username = "admin"
password = "myStrongPassword"
```

Here is a Java example showing how to start a session using the configured user and password.

```java
ClientConfig clientConfig = ClientConfig.defaultConfig()
  .baseUrl(new URL("http://localhost:4444"))
  .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"));
HttpCommandExecutor executor = new HttpCommandExecutor(clientConfig);
RemoteWebDriver driver = new RemoteWebDriver(executor, new ChromeOptions());
```

In other languages, you can use the URL http\://admin:myStrongPassword\@localhost:4444

### Setting custom capabilities for matching specific Nodes

**Important:** Custom capabilities need to be set in the configuration in all Nodes. They also need to be included always in every session request.

```toml
[node]
detect-drivers = false

[[node.driver-configuration]]
display-name = "firefox"
stereotype = '{"browserName": "firefox", "platformName": "macOS", "browserVersion":"96", "networkname:applicationName":"node_1", "nodename:applicationName":"app_1" }'
max-sessions = 5
```

Here is a Java example showing how to match that Node

```java
FirefoxOptions options = new FirefoxOptions();
options.setCapability("networkname:applicationName", "node_1");
options.setCapability("nodename:applicationName", "app_1");
options.setBrowserVersion("96");
options.setPlatformName("macOS");
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

### Enabling Managed downloads by the Node.

The Node can be instructed to manage downloads automatically. This will cause the Node to save all files that were downloaded for a particular session into a temp directory, which can later be retrieved from the node. To turn this capability on, use the below configuration:

```toml
[node]
enable-managed-downloads = true
```

Refer to the [CLI section](https://www.selenium.dev/documentation/grid/configuration/cli_options/#enabling-managed-downloads-by-the-node) for a complete example.

# 5 - Grid architecture

|               | Event Bus | Distributor | Node | Router | Session Map | Session Queue |
| ------------- | --------- | ----------- | ---- | ------ | ----------- | ------------- |
| Event Bus     | X         |             |      |        |             |               |
| Distributor   | ✅         | X           | ✅    |        |             | ✅             |
| Node          | ✅         |             | X    |        |             |               |
| Router        |           |             | ✅    | X      | ✅           |               |
| Session Map   |           |             |      |        | X           |               |
| Session Queue | ✅         |             |      |        |             | X             |

| Name               | Type    | Description                                                                                                                                                                                                                                  |
| ------------------ | ------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| availability       | string  | A string which is one of `up`, `draining`, or `down`. The important one is `draining`, which indicates that no new sessions should be sent to the Node, and once the last session on it closes, the Node will exit or restart.               |
| externalUrl        | string  | The URI that the other components in the Grid should connect to.                                                                                                                                                                             |
| lastSessionCreated | integer | The epoch timestamp of when the last session was created on this Node. The Distributor will attempt to send new sessions to the Node that has been idle longest if all other things are equal.                                               |
| maxSessionCount    | integer | Although a session count can be inferred by counting the number of available slots, this integer value is used to determine the maximum number of sessions that should be running simultaneously on the Node before it is considered “full”. |
| nodeId             | string  | A UUID used to identify this instance of the Node.                                                                                                                                                                                           |
| osInfo             | object  | An object with `arch`, `name`, and `version` fields. This is used by the Grid UI and the GraphQL queries.                                                                                                                                    |
| slots              | array   | An array of Slot objects (described below)                                                                                                                                                                                                   |
| version            | string  | The version of the Node (for Selenium, this will match the Selenium version number)                                                                                                                                                          |

It is recommended to put values in all fields.

### The Slot Object

The Slot object represents a single slot within a Node. A “slot” is where a single session may be run. It is possible that a Node will have more slots than it can run concurrently. For example, a node may be able to run up 10 sessions, but they could be any combination of Chrome, Edge, or Firefox; in this case, the Node would indicate a “max session count” of 10, and then also say it has 10 slots for Chrome, 10 for Edge, and 10 for Firefox.

| Name        | Type   | Description                                                                                                                                                                  |
| ----------- | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| id          | string | UUID to refer to the slot                                                                                                                                                    |
| lastStarted | string | When the slot last had a session started, in ISO-8601 format                                                                                                                 |
| stereotype  | object | The minimal set of [capabilities](https://w3c.github.io/webdriver/#dfn-merging-capabilities) this slot will match against. A minimal example is `{"browserName": "firefox"}` |
| session     | object | The Session object (see below)                                                                                                                                               |

### The Session Object

This represents a running session within a slot

| Name         | Type   | Description                                                                                                                                                                  |
| ------------ | ------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| capabilities | object | The actual capabilities provided by the session. Will match the return value from the [new session](https://w3c.github.io/webdriver/#new-session) command                    |
| startTime    | string | The start time of the session in ISO-8601 format                                                                                                                             |
| stereotype   | object | The minimal set of [capabilities](https://w3c.github.io/webdriver/#dfn-merging-capabilities) this slot will match against. A minimal example is `{"browserName": "firefox"}` |
| uri          | string | The URI used by the Node to communicate with the session                                                                                                                     |

# 6 - Advanced features of Selenium

To get all the details of the advanced features, understand how it works, and how to set up your own, please browse thorough the following sections.

# 6.1 - Observability in Selenium Grid

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar standalone --log-level FINE
```

2. Jaeger UI - OpenTelemetry provides the APIs and SDKs to instrument traces in the code. Whereas Jaeger is a tracing backend, that aids in collecting the tracing telemetry data and providing querying, filtering and visualizing features for the data.

Detailed instructions of visualizing traces using Jaeger UI can be obtained by running the command :

```shell
java -jar selenium-server-4.0.0-<selenium-version>.jar info tracing
```

[A very good example and scripts to run the server and send traces to Jaeger](https://github.com/manoj9788/tracing-selenium-grid)

## Leveraging event logs

Tracing has to be enabled for event logging as well, even if one does not wish to export traces to visualize them.\
**By default, tracing is enabled. No additional parameters need to be passed to see logs on the console.** All events within a span are logged at FINE level. Error events are logged at WARN level.

All event logs have the following fields :

| Field            | Field value     | Description                                                                                                                                                                            |
| ---------------- | --------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Event time       | eventId         | Timestamp of the event record in epoch nanoseconds.                                                                                                                                    |
| Trace Id         | tracedId        | Each trace is uniquely identified by a trace id.                                                                                                                                       |
| Span Id          | spanId          | Each span within a trace is uniquely identified by a span id.                                                                                                                          |
| Span Kind        | spanKind        | Span kind is a property of span indicating the type of span. It helps in understanding the nature of the unit of work done by the Span.                                                |
| Event name       | eventName       | This maps to the log message.                                                                                                                                                          |
| Event attributes | eventAttributes | This forms the crux of the event logs, based on the operation executed, it has JSON formatted key-value pairs. This also includes a handler class attribute, to show the logger class. |

Sample log

```
FINE [LoggingOptions$1.lambda$export$1] - {
  "traceId": "fc8aef1d44b3cc8bc09eb8e581c4a8eb",
  "spanId": "b7d3b9865d3ddd45",
  "spanKind": "INTERNAL",
  "eventTime": 1597819675128886121,
  "eventName": "Session request execution complete",
  "attributes": {
    "http.status_code": 200,
    "http.handler_class": "org.openqa.selenium.grid.router.HandleSession",
    "http.url": "\u002fsession\u002fdd35257f104bb43fdfb06242953f4c85",
    "http.method": "DELETE",
    "session.id": "dd35257f104bb43fdfb06242953f4c85"
  }
}
```

In addition to the above fields, based on [OpenTelemetry specification](https://github.com/open-telemetry/opentelemetry-specification/blob/master/specification/trace/semantic_conventions/exceptions.md) error logs consist of :

| Field                | Field value          | Description                                                                                                                   |
| -------------------- | -------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Exception type       | exception.type       | The class name of the exception.                                                                                              |
| Exception message    | exception.message    | Reason for the exception.                                                                                                     |
| Exception stacktrace | exception.stacktrace | Prints the call stack at the point of time when the exception was thrown. Helps in understanding the origin of the exception. |

Sample error log

```
WARN [LoggingOptions$1.lambda$export$1] - {
  "traceId": "7efa5ea57e02f89cdf8de586fe09f564",
  "spanId": "914df6bc9a1f6e2b",
  "spanKind": "INTERNAL",
  "eventTime": 1597820253450580272,
  "eventName": "exception",
  "attributes": {
    "exception.type": "org.openqa.selenium.ScriptTimeoutException",
    "exception.message": "Unable to execute request: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist ..." (full message will be printed),
    "exception.stacktrace": "org.openqa.selenium.ScriptTimeoutException: java.sql.SQLSyntaxErrorException: Table 'mysql.sessions_mappa' doesn't exist\nBuild info: version: '4.0.0-alpha-7', revision: 'Unknown'\nSystem info: host: 'XYZ-MacBook-Pro.local', ip: 'fe80:0:0:0:10d5:b63a:bdc6:1aff%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.13.6', java.version: '11.0.7'\nDriver info: driver.version: unknown ...." (full stack will be printed),
    "http.handler_class": "org.openqa.selenium.grid.distributor.remote.RemoteDistributor",
    "http.url": "\u002fsession",
    "http.method": "POST"
  }
}
```

# 6.2 - GraphQL query support

```shell
{
    session(id: "<session-id>") : {
        id,
        capabilities,
        startTime,
        uri,
        nodeId,
        nodeUri,
        sessionDurationMillis
        slot : {
            id,
            stereotype,
            lastStarted
        }
    }
    grid: {
        uri,
        totalSlots,
        nodeCount,
        maxSession,
        sessionCount,
        version,
        sessionQueueSize
    }
    sessionsInfo: {
        sessionQueueRequests,
        sessions: [
            {
                id,
                capabilities,
                startTime,
                uri,
                nodeId,
                nodeUri,
                sessionDurationMillis
                slot : {
                    id,
                    stereotype,
                    lastStarted
                }
            }
        ]
    }
    nodesInfo: {
        nodes : [
            {
                id,
                uri,
                status,
                maxSession,
                slotCount,
                sessions: [
                    {
                        id,
                        capabilities,
                        startTime,
                        uri,
                        nodeId,
                        nodeUri,
                        sessionDurationMillis
                        slot : {
                            id,
                            stereotype,
                            lastStarted
                        }
                    }
                ],
                sessionCount,
                stereotypes,
                version,
                osInfo: {
                    arch,
                    name,
                    version
                }
            }
        ]
    }
}
```

## Querying GraphQL

The best way to query GraphQL is by using `curl` requests. The query is interpreted as JSON. Ensure double quotes are properly escaped to avoid unexpected errors. GraphQL allows you to fetch only the data that you want, nothing more nothing less.

Some of the example GraphQL queries are given below. You can build your own queries as you like.

### Querying the number of `maxSession` and `sessionCount` in the grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ grid { maxSession, sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

Generally on local machine the `<LINK_TO_GRAPHQL_ENDPOINT>` would be `http://localhost:4444/graphql`

### Querying all details for session, node and the Grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { uri, maxSession, sessionCount }, nodesInfo { nodes { id, uri, status, sessions { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } }, slotCount, sessionCount }} }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the current session count in the Grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionCount } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the max session count in the Grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { maxSession } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting all session details for all nodes in the Grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, capabilities, startTime, uri, nodeId, nodeId, sessionDurationMillis } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query to get slot information for all sessions in each Node in the Grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessions { id, slot { id, stereotype, lastStarted } } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query to get session information for a given session:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ session (id: \"<session-id>\") { id, capabilities, startTime, uri, nodeId, nodeUri, sessionDurationMillis, slot { id, stereotype, lastStarted } } } "}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Querying the capabilities of each node in the grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { stereotypes } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Querying the status of each node in the grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { status } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Querying the URI of each node and the grid :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query": "{ nodesInfo { nodes { uri } } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the current requests in the New Session Queue:

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ sessionsInfo { sessionQueueRequests } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

### Query for getting the New Session Queue size :

```shell
curl -X POST -H "Content-Type: application/json" --data '{"query":"{ grid { sessionQueueSize } }"}' -s <LINK_TO_GRAPHQL_ENDPOINT>
```

# 6.3 - Grid endpoints

## Grid

### Grid Status

Grid status provides the current state of the Grid. It consists of details about every registered Node. For every Node, the status includes information regarding Node availability, sessions, and slots.

```shell
curl --request GET 'http://localhost:4444/status'
```

### Delete session

Deleting the session terminates the WebDriver session, quits the driver and removes it from the active sessions map. Any request using the removed session-id or reusing the driver instance will throw an error.

```shell
curl --request DELETE 'http://localhost:4444/session/<session-id>'
```

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret> '
```

In the fully distributed mode, the URL is the Router server address.

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET;'
```

### Drain Node

Node drain command is for graceful node shutdown. Draining a Node stops the Node after all the ongoing sessions are complete. However, it does not accept any new session requests.

In the Standalone mode, the Distributor URL is the Standalone server address.

In the Hub-Node mode, the Distributor URL is the Hub server address.

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret> '
```

In the fully distributed mode, the URL is the Router server address.

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request POST 'http://<Router-URL>/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET;'
```

## Node

The endpoints in this section are applicable for Hub-Node mode and fully distributed Grid mode where the Node runs independently. The default Node URL is http\://localhost:5555 in case of one Node. In case of multiple Nodes, use [Grid status](/documentation/grid/advanced_features/endpoints/#grid-status) to get all Node details and locate the Node address.

### Status

The Node status is essentially a health-check for the Node. Distributor pings the node status at regular intervals and updates the Grid Model accordingly. The status includes information regarding availability, sessions, and slots.

```shell
curl --request GET 'http://localhost:5555/status'
```

### Drain

Distributor passes the [drain](/documentation/grid/advanced_features/endpoints/#drain-node) command to the appropriate node identified by the node-id. To drain the Node directly, use the curl command enlisted below. Both endpoints are valid and produce the same result. Drain finishes the ongoing sessions before stopping the Node.

```shell
curl --request POST 'http://localhost:5555/se/grid/node/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request POST 'http://<node-URL>/se/grid/node/drain' --header 'X-REGISTRATION-SECRET;'
```

### Check session owner

To check if a session belongs to a Node, use the curl command enlisted below.

```shell
curl --request GET 'http://localhost:5555/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request GET 'http://<node-URL>/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

It will return true if the session belongs to the Node else it will return false.

### Delete session

Deleting the session terminates the WebDriver session, quits the driver and removes it from the active sessions map. Any request using the removed session-id or reusing the driver instance will throw an error.

```shell
curl --request DELETE 'http://localhost:5555/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request DELETE 'http://<node-URL>/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

## New Session Queue

### Clear New Session Queue

New Session Request Queue holds the new session requests. To clear the queue, use the curl command enlisted below. Clearing the queue rejects all the requests in the queue. For each such request, the server returns an error response to the respective client. The result of the clear command is the total number of deleted requests.

In the Standalone mode, the Queue URL is the Standalone server address.

In the Hub-Node mode, the Queue URL is the Hub server address.

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

In the fully distributed mode, the Queue URL is Router server address.

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

If no registration secret has been configured while setting up the Grid, then use

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET;'
```

### Get New Session Queue Requests

New Session Request Queue holds the new session requests. To get the current requests in the queue, use the curl command enlisted below. The response returns the total number of requests in the queue and the request payloads.

In the Standalone mode, the Queue URL is the Standalone server address.

In the Hub-Node mode, the Queue URL is the Hub server address.

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

In the fully distributed mode, the Queue URL is Router server address.

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

# 6.4 - Customizing a Node

```bash
java -jar custom_node-server.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

```bash
java -jar selenium-server-4.6.0.jar \
--ext custom_node-1.0-SNAPSHOT.jar node \
--node-implementation org.seleniumhq.samples.DecoratedLoggingNode
```

Below is a sample that just prints some messages on to the console whenever there’s an activity of interest (session created, session deleted, a webdriver command executed etc.,) on the Node.

Sample customized node

```java
package org.seleniumhq.samples;

import java.io.IOException;
import java.net.URI;
import java.util.UUID;
import java.util.function.Supplier;
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.NoSuchSessionException;
import org.openqa.selenium.WebDriverException;
import org.openqa.selenium.grid.config.Config;
import org.openqa.selenium.grid.data.CreateSessionRequest;
import org.openqa.selenium.grid.data.CreateSessionResponse;
import org.openqa.selenium.grid.data.NodeId;
import org.openqa.selenium.grid.data.NodeStatus;
import org.openqa.selenium.grid.data.Session;
import org.openqa.selenium.grid.log.LoggingOptions;
import org.openqa.selenium.grid.node.HealthCheck;
import org.openqa.selenium.grid.node.Node;
import org.openqa.selenium.grid.node.local.LocalNodeFactory;
import org.openqa.selenium.grid.security.Secret;
import org.openqa.selenium.grid.security.SecretOptions;
import org.openqa.selenium.grid.server.BaseServerOptions;
import org.openqa.selenium.internal.Either;
import org.openqa.selenium.io.TemporaryFilesystem;
import org.openqa.selenium.remote.SessionId;
import org.openqa.selenium.remote.http.HttpRequest;
import org.openqa.selenium.remote.http.HttpResponse;
import org.openqa.selenium.remote.tracing.Tracer;

public class DecoratedLoggingNode extends Node {

  private Node node;

  protected DecoratedLoggingNode(Tracer tracer, NodeId nodeId, URI uri, Secret registrationSecret, Duration sessionTimeout) {
    super(tracer, nodeId, uri, registrationSecret, sessionTimeout);
  }

  public static Node create(Config config) {
    LoggingOptions loggingOptions = new LoggingOptions(config);
    BaseServerOptions serverOptions = new BaseServerOptions(config);
    URI uri = serverOptions.getExternalUri();
    SecretOptions secretOptions = new SecretOptions(config);
    NodeOptions nodeOptions = new NodeOptions(config);
    Duration sessionTimeout = nodeOptions.getSessionTimeout();

    // Refer to the foot notes for additional context on this line.
    Node node = LocalNodeFactory.create(config);

    DecoratedLoggingNode wrapper = new DecoratedLoggingNode(loggingOptions.getTracer(),
        node.getId(),
        uri,
        secretOptions.getRegistrationSecret(),
        sessionTimeout);
    wrapper.node = node;
    return wrapper;
  }

  @Override
  public Either<WebDriverException, CreateSessionResponse> newSession(
      CreateSessionRequest sessionRequest) {
    return perform(() -> node.newSession(sessionRequest), "newSession");
  }

  @Override
  public HttpResponse executeWebDriverCommand(HttpRequest req) {
    return perform(() -> node.executeWebDriverCommand(req), "executeWebDriverCommand");
  }

  @Override
  public Session getSession(SessionId id) throws NoSuchSessionException {
    return perform(() -> node.getSession(id), "getSession");
  }

  @Override
  public HttpResponse uploadFile(HttpRequest req, SessionId id) {
    return perform(() -> node.uploadFile(req, id), "uploadFile");
  }

  @Override
  public HttpResponse downloadFile(HttpRequest req, SessionId id) {
    return perform(() -> node.downloadFile(req, id), "downloadFile");
  }

  @Override
  public TemporaryFilesystem getDownloadsFilesystem(UUID uuid) {
    return perform(() -> {
      try {
        return node.getDownloadsFilesystem(uuid);
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
    }, "downloadsFilesystem");
  }

  @Override
  public TemporaryFilesystem getUploadsFilesystem(SessionId id) throws IOException {
    return perform(() -> {
      try {
        return node.getUploadsFilesystem(id);
      } catch (IOException e) {
        throw new RuntimeException(e);
      }
    }, "uploadsFilesystem");

  }

  @Override
  public void stop(SessionId id) throws NoSuchSessionException {
    perform(() -> node.stop(id), "stop");
  }

  @Override
  public boolean isSessionOwner(SessionId id) {
    return perform(() -> node.isSessionOwner(id), "isSessionOwner");
  }

  @Override
  public boolean isSupporting(Capabilities capabilities) {
    return perform(() -> node.isSupporting(capabilities), "isSupporting");
  }

  @Override
  public NodeStatus getStatus() {
    return perform(() -> node.getStatus(), "getStatus");
  }

  @Override
  public HealthCheck getHealthCheck() {
    return perform(() -> node.getHealthCheck(), "getHealthCheck");
  }

  @Override
  public void drain() {
    perform(() -> node.drain(), "drain");
  }

  @Override
  public boolean isReady() {
    return perform(() -> node.isReady(), "isReady");
  }

  private void perform(Runnable function, String operation) {
    try {
      System.err.printf("[COMMENTATOR] Before %s()%n", operation);
      function.run();
    } finally {
      System.err.printf("[COMMENTATOR] After %s()%n", operation);
    }
  }

  private <T> T perform(Supplier<T> function, String operation) {
    try {
      System.err.printf("[COMMENTATOR] Before %s()%n", operation);
      return function.get();
    } finally {
      System.err.printf("[COMMENTATOR] After %s()%n", operation);
    }
  }
}
```

***Foot Notes:***

In the above example, the line `Node node = LocalNodeFactory.create(config);` explicitly creates a `LocalNode`.

There are basically 2 types of *user facing implementations* of `org.openqa.selenium.grid.node.Node` available.

These classes are good starting points to learn how to build a custom Node and also to learn the internals of a Node.

* `org.openqa.selenium.grid.node.local.LocalNode` - Used to represent a long running Node and is the default implementation that gets wired in when you start a `node`.

  * It can be created by calling `LocalNodeFactory.create(config);`, where:

    * `LocalNodeFactory` belongs to `org.openqa.selenium.grid.node.local`
    * `Config` belongs to `org.openqa.selenium.grid.config`

* `org.openqa.selenium.grid.node.k8s.OneShotNode` - This is a special reference implementation wherein the Node gracefully shuts itself down after servicing one test session. This class is currently not available as part of any pre-built maven artifact.

  * You can refer to the source code [here](https://github.com/SeleniumHQ/selenium/blob/trunk/java/src/org/openqa/selenium/grid/node/k8s/OneShotNode.java) to understand its internals.

  * To build it locally refer [here](https://github.com/SeleniumHQ/selenium/blob/trunk/deploys/k8s/README.md).

  * It can be created by calling `OneShotNode.create(config)`, where:

    * `OneShotNode` belongs to `org.openqa.selenium.grid.node.k8s`
    * `Config` belongs to `org.openqa.selenium.grid.config`

# 6.5 - External datastore

```sql
CREATE TABLE IF NOT EXISTS sessions_map(
    session_ids varchar(256),
    session_caps text,
    session_uri varchar(256),
    session_stereotype text,
    session_start varchar(256)
 );
```

* In the same directory as the `init.sql`, create a file named `docker-compose.yml` with its contents as below:

```yaml
version: '3.8'
services:
  db:
    image: postgres:9.6-bullseye
    restart: always
    environment:
      - POSTGRES_USER=seluser
      - POSTGRES_PASSWORD=seluser
      - POSTGRES_DB=selenium_sessions
    ports:
      - "5432:5432"
    volumes:
    - ./init.sql:/docker-entrypoint-initdb.d/init.sql
```

We can now start our database container by running:

```bash
docker-compose up -d
```

*Our database name is `selenium_sessions` with its username and password set to `seluser`*

If you are working with an already running PostGreSQL DB instance, then you just need to create a database named `selenium_sessions` and the table `sessions_map` using the above mentioned SQL statement.

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
implementation = "org.openqa.selenium.grid.sessionmap.jdbc.JdbcBackedSessionMap"
jdbc-url = "jdbc:postgresql://localhost:5432/selenium_sessions"
jdbc-user = "seluser"
jdbc-password = "seluser"
```

*Note:* If you plan to use an existing PostGreSQL DB instance, then replace `localhost:5432` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed Grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Sessions Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-jdbc:${SE_VERSION} org.postgresql:postgresql:42.3.1) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

```yaml
version: '3.8'
services:
  redis:
    image: redis:bullseye
    restart: always
    ports:
      - "6379:6379"
```

We can now start our Redis container by running:

```bash
docker-compose up -d
```

* Create a Selenium Grid configuration file named `sessions.toml` with the below contents:

```toml
[sessions]
scheme = "redis"
implementation = "org.openqa.selenium.grid.sessionmap.redis.RedisBackedSessionMap"
hostname = "localhost"
port = 6379
```

*Note:* If you plan to use an existing Redis Cache instance, then replace `localhost` and `6379` with the actual host and port number of your instance.

* Below is a simple shell script (let’s call it `distributed.sh`) that we will use to bring up our distributed grid.

```bash
SE_VERSION=<current_selenium_version>
JAR_NAME=selenium-server-${SE_VERSION}.jar
PUBLISH="--publish-events tcp://localhost:4442"
SUBSCRIBE="--subscribe-events tcp://localhost:4443"
SESSIONS="--sessions http://localhost:5556"
SESSIONS_QUEUE="--sessionqueue http://localhost:5559"
echo 'Starting Event Bus'
java -jar $JAR_NAME event-bus $PUBLISH $SUBSCRIBE --port 5557 &
echo 'Starting New Session Queue'
java -jar $JAR_NAME sessionqueue --port 5559 &
echo 'Starting Session Map'
java -jar $JAR_NAME \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions $PUBLISH $SUBSCRIBE --port 5556 --config sessions.toml &
echo 'Starting Distributor'
java -jar $JAR_NAME  distributor $PUBLISH $SUBSCRIBE $SESSIONS $SESSIONS_QUEUE --port 5553 --bind-bus false &
echo 'Starting Router'
java -jar $JAR_NAME router $SESSIONS --distributor http://localhost:5553 $SESSIONS_QUEUE --port 4444 &
echo 'Starting Node'
java -jar $JAR_NAME node $PUBLISH $SUBSCRIBE &
```

* At this point the current directory should contain the following files:

  * `docker-compose.yml`
  * `sessions.toml`
  * `distributed.sh`

* You can now spawn the Grid by running `distributed.sh` shell script and quickly run a test. You will notice that the Grid now stores session information into the Redis instance. You can perhaps make use of a Redis GUI such as [TablePlus](https://tableplus.com/) to see them (Make sure that you have setup a debug point in your test, because the values will get deleted as soon as the test runs to completion).

In the line which spawns a `SessionMap` on a machine:

```bash
export SE_VERSION=<current_selenium_version>
java -jar selenium-server-${SE_VERSION}.jar \
--ext $(coursier fetch -p org.seleniumhq.selenium:selenium-session-map-redis:${SE_VERSION}) \
sessions --publish-events tcp://localhost:4442 \
--subscribe-events tcp://localhost:4443 \
--port 5556 --config sessions.toml 
```

----
url: https://www.selenium.dev/ja/documentation/webdriver/browsers/chrome/
----

# Chrome固有の機能

```java
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L36-L37)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L9-L10)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L30-L31)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L51-L55)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_argument("--start-maximized")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L18)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L39)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.args << '--start-maximized'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L17)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L9-L12)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L53)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.binary_location = chrome_bin
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L29)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L49)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.add_argument('--disable-dev-shm-usage')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L27)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L41-L44)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
  @DisabledOnOs(OS.WINDOWS)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L64)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_extension(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L40)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L73-L84)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L36)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L62-L66)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```py
    options.add_experimental_option("detach", True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L51)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

**注意**: これはすでに.NETのデフォルトの動作です。

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L45)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L29-L32)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L78)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L62)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L82)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L53)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L19-L22)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L100-L101)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Javaでは、システムプロパティによってファイル出力を設定することもできます：\
プロパティキー: `ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY`\
プロパティ値: ログファイルへのパスを表す文字列

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L71)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L86)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service = Selenium::WebDriver::Service.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L67)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L114-L115)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Javaでは、システムプロパティによってコンソール出力を設定することもできます。\
プロパティキー: `ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY`\
プロパティ値: `DriverService.LOG_STDOUT` または `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L82)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

`$stdout` と `$stderr` はどちらも有効な値です。

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service = Selenium::WebDriver::Service.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L76)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L129-L130)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Javaでは、システムプロパティによってログレベルを設定することもできます：\
プロパティキー: `ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY`\
プロパティ値: `ChromiumDriverLogLevel` 列挙型の文字列表現

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L93)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L87)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L147-L148)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Javaでは、これらの機能をシステムプロパティによって切り替えることもできます：\
プロパティキー: `ChromeDriverService.CHROME_DRIVER_APPEND_LOG_PROPERTY` および`ChromeDriverService.CHROME_DRIVER_READABLE_TIMESTAMP`\
プロパティ値: `"true"` または `"false"`

```py
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L104)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service = Selenium::WebDriver::Service.chrome(args: args)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L97-L98)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L166-L167)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**注意**: Javaでは、システムプロパティによってビルドチェックを無効にすることもできます：\
プロパティキー: `ChromeDriverService.CHROME_DRIVER_DISABLE_BUILD_CHECK`\
プロパティ値: `"true"` または `"false"`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L115)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            service.DisableBuildCheck = true;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L155)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L108)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L230-L235)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L170-L174)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L119-L124)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L204-L210)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L129-L135)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
    it 'gets and sets network conditions' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L129)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L247)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    logs = driver.get_log("browser")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L186)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver = Selenium::WebDriver.for :chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L141)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    options.setBrowserVersion("stable");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L189)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    driver.set_permissions('camera', 'denied')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L149)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L149-L150)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### デベロッパー ツール

Chromeデベロッパーツールの使用に関する詳細については、\[Chromeデベロッパー ツール] セクションを参照してください。

最終更新 April 19, 2026: [\[dotnet\] fix: test (25b39a556d7)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/25b39a556d73f3c0aff65f33da011b33b8c4d202)

----
url: https://www.selenium.dev/ja/documentation/about/
----

# このドキュメントについて

これらのドキュメントは、コード自体と同様に、Seleniumコミュニティ内のボランティアによって100％維持されます。 当初から多くの人が使用してきましたが、多くの人が短期間しか使用しておらず、新しいユーザーのオンボーディングエクスペリエンスの改善に時間を割いてきました。

ドキュメントに問題がある場合、知りたいです！ 問題を伝える最良の方法は、[https://github.com/seleniumhq/seleniumhq.github.io/issues](//github.com/seleniumhq/seleniumhq.github.io/issues)にアクセスし、問題が既に報告されているかどうかを検索することです。 そうでない場合は、自由に開いてください！

コミュニティの多くのメンバーは、[Libera.chat](https://libera.chat/) で *#selenium* Liberaチャンネルに頻繁にアクセスします。 気軽に立ち寄って質問してください。 これらのドキュメントで役立つと思われるヘルプを受け取った場合は、必ず貢献を追加してください。 これらのドキュメントを更新することはできますが、通常のコミッター以外から投稿を受け取ると、誰にとってもずっと簡単になります。

***

##### [著作権と帰属](/ja/documentation/about/copyright/)

Copyright, contributions and all attributions for the different projects under the Selenium umbrella.

##### [Seleniumのサイトとドキュメントに貢献する](/ja/documentation/about/contributing/)

Seleniumのドキュメントとコード例を改善するための情報

##### [Style guide for Selenium documentation](/ja/documentation/about/style/)

Conventions for contributions to the Selenium documentation and code examples

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/getting_started/using_selenium/
----

# 组织和执行Selenium代码

使用IDE和Test Runner库组织Selenium的执行

如果你不仅仅只是想执行一小撮的一次性脚本，你需要能组织并编排好你的代码。 本章会启发你如何真正地使用 Selenium 代码做高效的事情。

## 常见用法

大部分人使用 Selenium 执行针对 Web 应用的自动化测试，但是 Selenium 其实可以支持任何场景的浏览器自动化。

### 重复性任务

有时候你需要往网站记录日志或者下载一些东西，或者提交一个表单， 你可以在预设的时间创建一个 Selenium 脚本去执行一个服务。

### 网页爬虫

你是否期望从一个不提供 API 的网站收集数据？Selenium 可以满足你， 但是请确保你了解该网站的服务条例， 因为有些网站不允许你这样做，甚至有些网站会屏蔽 Selenium。

### 测试

使用 Selenium 做测试需要在 Selenium 执行操作后进行断言，所以一个好的断言类库是很有必要的。 至于组织测试用例结构的一些额外特性则需要[Test Runner](/zh-cn/documentation/webdriver/getting_started/using_selenium/#test-runner)来完成。

## IDEs

不管你要用 Selenium 来做什么，没有一个好的集成开发环境，你的工作肯定不会高效。以下是一些常见的 IDE 选择：

即使不使用 Selenium 做测试，如果你有高级用例，使用一个 test runner 去更好地组织你的代码是很有意义的。 学会使用 before/after hooks 和分组执行或者并行执行将会非常有用。

### 候选

有非常多不同的 test runner 可供选择。

这个教程中所有使用到 test runner 的代码示例都可以在我们的示例目录中找到（或者正在被迁移过去）， 而且这些示例在每一次发版都会被执行，以确保代码是正确的和最新的。 下面是一份包含对应链接的 test runner 清单，其中第一项是被这个仓库和本页所有用例所使用的。

*
*
*
*
*
*

- [JUnit](https://junit.org/junit5/) - 一个广泛使用的用于基于 Java 的 Selenium 测试的测试框架。
- [TestNG](https://testng.org/) - 提供诸如并行测试执行和参数化测试等额外功能。

* [pytest](https://pytest.org/) - 由于其简单性和强大的插件，它成为许多人的首选。
* [unittest](https://docs.python.org/3/library/unittest.html) - Python 的标准测试库

- [NUnit](https://nunit.org/) - .NET的流行单元测试框架
- [MS Test](https://docs.microsoft.com/en-us/visualstudio/test/getting-started-with-unit-testing?view=vs-2019) - 微软自己的单元测试框架

* [RSpec](https://rspec.info/) - Ruby中运行Selenium测试最广泛使用的测试库
* [Minitest](https://github.com/seattlerb/minitest) - 一个随Ruby标准库附带的轻量级测试框架

- [Jest](https://jestjs.io/) - 主要作为React的测试框架而闻名，但也可以用于Selenium测试
- [Mocha](https://mochajs.org/) -最常用的运行Selenium测试的JavaScript库。

* [Kotest](https://kotest.io/) - 一个灵活且全面的测试框架，专为 Kotlin 设计。
* [JUnit5](https://junit.org/junit5/) - 标准的 Java 测试框架，完全兼容 Kotlin。

### 安装

在[安装 Selenium 类库](https://www.selenium.dev/zh-cn/documentation/webdriver/getting_started/install_library/)一节中详细说明了需要哪些东西。 这里的代码只展示在我们的文档示例项目中用到的示例。

To use it in a project, add it to the `requirements.txt` file:

in the project’s `csproj` file, specify the dependency as a `PackageReference` in `ItemGroup`:

Add to project’s gemfile

In your project’s `package.json`, add requirement to `dependencies`:

### 断言

*
*
*
*
*
*

```java
		String title = driver.getTitle();
		assertEquals("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L30-L31)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java
package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

```py
    title = driver.title
    assert title == "Web form"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L8-L9)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

```cs
            var title = driver.Title;
            Assert.AreEqual("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs#L19-L20)

##### /examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted
{
    [TestClass]
    public class UsingSeleniumTest
    {

        [TestMethod]
        public void EightComponents()
        {
            IWebDriver driver = new ChromeDriver();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

            var title = driver.Title;
            Assert.AreEqual("Web form", title);

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            var textBox = driver.FindElement(By.Name("my-text"));
            var submitButton = driver.FindElement(By.TagName("button"));
            
            textBox.SendKeys("Selenium");
            submitButton.Click();
            
            var message = driver.FindElement(By.Id("message"));
            var value = message.Text;
            Assert.AreEqual("Received!", value);
            
            driver.Quit();
        }
    }
}
```

```rb
    title = @driver.title
    expect(title).to eq('Web form')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb#L14-L15)

##### /examples/ruby/spec/getting\_started/using\_selenium\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

```js
    let title = await driver.getTitle();
    assert.equal("Web form", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L14-L15)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

```kt
        val title = driver.title
        assertEquals("Web form", title)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L20-21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

### Setting Up and Tearing Down

```java
	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L19-L22)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java
package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

### Tear Down

```java
	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java#L45-L48)

##### /examples/java/src/test/java/dev/selenium/getting\_started/UsingSeleniumTest.java

```java
package dev.selenium.getting_started;

import static org.junit.jupiter.api.Assertions.assertEquals;

import java.time.Duration;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

public class UsingSeleniumTest {

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

### Set Up

```py
def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L25-L28)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

### Tear Down

```py
def teardown(driver):
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py#L30-31)

##### /examples/python/tests/getting\_started/using\_selenium\_tests.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

### Set Up

```rb
  before do
    @driver = Selenium::WebDriver.for :chrome
  end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb#L7-L9)

##### /examples/ruby/spec/getting\_started/using\_selenium\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

### Tear Down

```rb
  config.after { @driver&.quit }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/spec_helper.rb#L30)

##### /examples/ruby/spec/spec\_helper.rb

```rb
# frozen_string_literal: true

require 'selenium-webdriver'
require 'selenium/webdriver/support/guards'

RSpec.configure do |config|
  # Enable flags like --only-failures and --next-failure
  config.example_status_persistence_file_path = '.rspec_status'

  # Disable RSpec exposing methods globally on `Module` and `main`
  config.disable_monkey_patching!
  Dir.mktmpdir('tmp')
  config.example_status_persistence_file_path = 'tmp/examples.txt'

  config.expect_with :rspec do |c|
    c.syntax = :expect
  end

  config.before do |example|
    bug_tracker = 'https://github.com/SeleniumHQ/seleniumhq.github.io/issues'
    guards = Selenium::WebDriver::Support::Guards.new(example,
                                                      bug_tracker: bug_tracker)
    guards.add_condition(:platform, Selenium::WebDriver::Platform.os)
    guards.add_condition(:ci, Selenium::WebDriver::Platform.ci)

    results = guards.disposition
    send(*results) if results
  end

  config.after { @driver&.quit }

  def start_session
    options = Selenium::WebDriver::Chrome::Options.new
    options.add_argument('disable-search-engine-choice-screen')
    options.add_argument('--no-sandbox')
    @driver = Selenium::WebDriver.for(:chrome, options: options)
  end

  def start_bidi_session
    options = Selenium::WebDriver::Chrome::Options.new(web_socket_url: true)
    @driver = Selenium::WebDriver.for :chrome, options: options
  end

  def start_firefox
    options = Selenium::WebDriver::Options.firefox(timeouts: {implicit: 1500})
    @driver = Selenium::WebDriver.for :firefox, options: options
  end
end
```

\### Set Up

```js
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L7-L9)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

\### Tear Down

```js
  after(async () => await driver.quit());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js#L30)

##### /examples/javascript/test/getting\_started/runningTests.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

### 执行

```shell
mvn clean test
```

### Gradle

```shell
gradle clean test
```

````md
```
````

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/README.md#L35)

##### /examples/python/README.md

````md
# Running tests from Selenium Python examples

#### 1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

#### 2. Navigate to `python` directory

```
cd seleniumhq.github.io/examples/python
```

#### 3. Create a virtual environment

- On Windows:

```
py -m venv venv
venv\Scripts\activate
```

- On Linux/Mac:

```
python3 -m venv venv
source venv/bin/activate
```

#### 4. Install dependencies:

```
pip install -r requirements.txt
```

> for help, see: https://packaging.python.org/en/latest/tutorials/installing-packages

#### 5. Run tests

- Run all tests with the default Python interpreter:

```
pytest
```

- Run all tests with every installed/supported Python interpreter:

```
tox
```

> Please have some patience - If you are doing it for the first time, it will take a little while to download the browser drivers

- Run a specific example:

```
pytest path/to/test_script.py
```

> Make sure to replace `path/to/test_script.py` with the path and name of the example you want to run
````

```md
dotnet test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/README.md#L44)

##### /examples/dotnet/README.md

````md

```bash
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

## Navigate to the .NET directory
### Change into the .NET examples directory:

```bash
cd seleniumhq.github.io/examples/dotnet/SeleniumDocs
```

## Running the Tests
### Restore dependencies
Install necessary dependencies using the .NET CLI:

```bash
dotnet restore
```

### Run all tests
To run all available tests:

```bash
dotnet test
```

### Run a Specific Test Method
To run a specific test method using its fully qualified name:

```bash
dotnet test --filter "FullyQualifiedName=Namespace.ClassName.MethodName"
```
For example:
```bash
dotnet test --filter "FullyQualifiedName=SeleniumDocs.GettingStarted.UsingSeleniumTest.EightComponents"
```

You can also filter by test name only (if it's unique):
```bash
dotnet test --filter "Name=EightComponents"
```
````

```md
bundle exec rspec
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/README.md#L26)

##### /examples/ruby/README.md

````md
# Running all tests from Selenium ruby example

Follow these steps to run all test example from selenium ruby

1. Clone this repository

```
git clone https://github.com/SeleniumHQ/seleniumhq.github.io.git
```

2. Navigate to `ruby` directory

```
cd seleniumhq.github.io/examples/ruby
```

3. Install dependencies using bundler

```
bundler install
```

4. Run all tests

```
bundle exec rspec
```

> Please keep some patience - If you are doing it for the first time, it will take a little while to verify and download the browser drivers

# Execute a ruby script

Use this command to run a ruby script and follow the first script example

```
ruby example_script.rb
```
````

### Mocha

```shell
mocha runningTests.spec.js
```

### npx

```shell
npx mocha runningTests.spec.js
```

[Add Example](/documentation/about/contributing/#creating-examples)

### 示例

在[第一个脚本](https://www.selenium.dev/zh-cn/documentation/webdriver/getting_started/first_script/)一节中，我们了解了 Selenium 脚本的每一个组件。 这里是使用 test runner 重新组织那个脚本的一个示例：

*
*
*
*
*
*

```java

	WebDriver driver;

	@BeforeEach
	public void setup() {
		driver = new ChromeDriver();
	}

	@Test
	public void eightComponents() {

		driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
		driver.get("https://www.selenium.dev/selenium/web/web-form.html");

		String title = driver.getTitle();
		assertEquals("Web form", title);

		WebElement textBox = driver.findElement(By.name("my-text"));
		WebElement submitButton = driver.findElement(By.cssSelector("button"));

		textBox.sendKeys("Selenium");
		submitButton.click();

		WebElement message = driver.findElement(By.id("message"));
		String value = message.getText();
		assertEquals("Received!", value);

	}

	@AfterEach
	public final void teardown() {
		if (driver != null) {
			driver.quit();
		}
	}

}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/UsingSeleniumTest.java)

```py
from selenium import webdriver
from selenium.webdriver.common.by import By


def test_eight_components():
    driver = setup()

    title = driver.title
    assert title == "Web form"

    driver.implicitly_wait(0.5)

    text_box = driver.find_element(by=By.NAME, value="my-text")
    submit_button = driver.find_element(by=By.CSS_SELECTOR, value="button")

    text_box.send_keys("Selenium")
    submit_button.click()

    message = driver.find_element(by=By.ID, value="message")
    value = message.text
    assert value == "Received!"

    teardown(driver)

def setup():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/web-form.html")
    return driver

def teardown(driver):
    driver.quit()
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/getting_started/using_selenium_tests.py)

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted
{
    [TestClass]
    public class UsingSeleniumTest
    {

        [TestMethod]
        public void EightComponents()
        {
            IWebDriver driver = new ChromeDriver();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

            var title = driver.Title;
            Assert.AreEqual("Web form", title);

            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            var textBox = driver.FindElement(By.Name("my-text"));
            var submitButton = driver.FindElement(By.TagName("button"));
            
            textBox.SendKeys("Selenium");
            submitButton.Click();
            
            var message = driver.FindElement(By.Id("message"));
            var value = message.Text;
            Assert.AreEqual("Received!", value);
            
            driver.Quit();
        }
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/UsingSeleniumTest.cs)

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium-webdriver'

RSpec.describe 'Using Selenium' do
  before do
    @driver = Selenium::WebDriver.for :chrome
  end

  it 'uses eight components' do
    @driver.get('https://www.selenium.dev/selenium/web/web-form.html')

    title = @driver.title
    expect(title).to eq('Web form')

    @driver.manage.timeouts.implicit_wait = 500

    text_box = @driver.find_element(name: 'my-text')
    submit_button = @driver.find_element(tag_name: 'button')

    text_box.send_keys('Selenium')
    submit_button.click

    message = @driver.find_element(id: 'message')
    value = message.text
    expect(value).to eq('Received!')
  end
end
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/getting_started/using_selenium_spec.rb)

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('First script', function () {
  let driver;

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });

  it('First Selenium script with mocha', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');

    let title = await driver.getTitle();
    assert.equal("Web form", title);

    await driver.manage().setTimeouts({implicit: 500});

    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));

    await textBox.sendKeys('Selenium');
    await submitButton.click();

    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  });

  after(async () => await driver.quit());
});
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/runningTests.spec.js)

[Add Example](/documentation/about/contributing/#creating-examples)

## 下一步

使用你目前所学到的知识构建你自己的 Selenium 代码吧！

想要了解更多的功能特性， 请继续阅读我们接下来的[WebDriver 教程](https://www.selenium.dev/zh-cn/documentation/webdriver/)

最后修改 February 25, 2026: [Update "Using Selenium" documentation with C# example from .NET README (#2584) (e1d46ea60e4)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/e1d46ea60e47ff168113cd1e609b27a142527573)

## Development Partners

[](https://www.browserstack.com/automate?utm_campaign=open-source-sponsor\&utm_campaigncode=701OW000009sQwVYAU\&utm_medium=partnered\&utm_source=seleniumorg)

[](https://saucelabs.com/resources/topic-hub/selenium?utm_source=selenium\&utm_medium=website\&utm_campaign=selenium-sponsorship-fy25)

[](https://www.testmuai.com)

## Selenium Level Sponsors

[](https://brightdata.com/?utm_source=brand\&utm_campaign=brnd-mkt_partners_selenium)

[](https://applitools.com/)

[](https://www.thordata.com/?ls=waOicIkB\&lk=selenium)

## Support the Selenium Project

Learn more or view the full list of sponsors.

[Learn more**](/sponsors)

----
url: https://www.selenium.dev/ja/_print/documentation/test_practices/discouraged/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/test_practices/discouraged/).

# 推奨されない行動

Seleniumでブラウザを自動化するときに避けるべきこと。

* 1: [CAPTCHA（キャプチャ）](#pg-39f9e51e0f4ba8c3e8698a77a7a121c9)
* 2: [ファイルダウンロード](#pg-13dc546cdf40904f2b8d17d2d10912b5)
* 3: [HTTPレスポンスコード](#pg-cd608bb3235f3fdba483c5af1d7989e8)
* 4: [Gmail、Eメール、Facebookログイン](#pg-2bda5750ae2f47398811b74c5335df8d)
* 5: [テストの依存関係](#pg-3838eea374f78e0ae303bf7bf2468369)
* 6: [パフォーマンステスト](#pg-eca347e22c127712a44437f535a8745b)
* 7: [リンクスパイダー](#pg-8314dd156c805a24994aecd6df02e160)
* 8: [二要素認証](#pg-fb1bf62414b2a3444b5611af6d361a5f)

# 1 - CAPTCHA（キャプチャ）

CAPTCHA（キャプチャ）は、 *Completely Automated Public Turing test to tell Computers and Humans Apart* （コンピューターと人間を区別するための完全に自動化された公開チューリングテスト）の略で、自動化を防ぐように明示的に設計されているため、試さないでください！ CAPTCHAチェックを回避するための2つの主要な戦略があります。

* テスト環境でCAPTCHAを無効にします
* テストがCAPTCHAをバイパスできるようにするフックを追加します

# 2 - ファイルダウンロード

Seleniumの管理下にあるブラウザーでリンクをクリックしてダウンロードを開始することは可能ですが、APIはダウンロードの進行状況を公開しないため、ダウンロードしたファイルのテストには理想的ではありません。 これは、ファイルのダウンロードは、Webプラットフォームとのユーザーインタラクションをエミュレートする重要な側面とは見なされないためです。 代わりに、Selenium（および必要なCookie）を使用してリンクを見つけ、 [curl](https://curl.se/) などのHTTPリクエストライブラリに渡します。

[HtmlUnitドライバー](https://github.com/SeleniumHQ/htmlunit-driver)は、 [AttachmentHandler](https://htmlunit.sourceforge.io/apidocs/com/gargoylesoftware/htmlunit/attachment/AttachmentHandler.html) インターフェイスを実装することで、 入力ストリームとして添付ファイルにアクセスすることによって、添付ファイルをダウンロードできます。 AttachmentHandlerは、[HtmlUnit](https://htmlunit.sourceforge.io/) に追加できます。

# 3 - HTTPレスポンスコード

Selenium RCの一部のブラウザー構成では、Seleniumはブラウザーと自動化されているサイトの間のプロキシとして機能しました。 これは、Seleniumを通過したすべてのブラウザートラフィックをキャプチャまたは操作できることを意味していました。 `captureNetworkTraffic()` メソッドは、HTTPレスポンスコードを含むブラウザーと自動化されているサイト間のすべてのネットワークトラフィックをキャプチャすることを目的としています。

Selenium WebDriverは、ブラウザーの自動化に対するまったく異なるアプローチであり、ユーザーのように振る舞うことを好むため、WebDriverを使用してテストを記述する方法で表現します。 自動化された機能テストでは、ステータスコードの確認はテストの失敗の特に重要な詳細ではありません。 それに先行する手順がより重要です。

ブラウザーは常にHTTPステータスコードを表します。たとえば、404または500エラーページを想像してください。 これらのエラーページの1つに遭遇したときに"早く失敗"する簡単な方法は、ページが読み込まれるたびにページタイトルまたは信頼できるポイント（たとえば `<h1>` タグ）のコンテンツをチェックすることです。 ページオブジェクトモデルを使用している場合、このチェックをクラスコンストラクターまたはページの読み込みが予想される同様のポイントに含めることができます。 場合によっては、HTTPコードがブラウザーのエラーページに表示されることもあります。 WebDriverを使用してこれを読み取り、デバッグ出力を改善できます。

Webページ自体を確認することは、WebDriverの理想的なプラクティスに沿っており、WebDriverのユーザーのWebサイトの見え方を表現し、主張します。

HTTPステータスコードをキャプチャするための高度なソリューションは、プロキシを使用してSelenium RCの動作を複製することです。 WebDriver APIは、ブラウザーのプロキシを設定する機能を提供します。 Webサーバーとの間で送受信されるリクエストのコンテンツをプログラムで操作できるプロキシがいくつかあります。 プロキシを使用すると、リダイレクトレスポンスコードへの応答方法を決めることができます。 さらに、すべてのブラウザーがWebDriverでレスポンスコードを利用できるようにするわけではないため、プロキシを使用することを選択すると、すべてのブラウザーで機能するソリューションが得られます。

# 4 - Gmail、Eメール、Facebookログイン

複数の理由から、WebDriverを使用してGmailやFacebookなどのサイトにログインすることはお勧めしません。 これらのサイトの使用条件（アカウントがシャットダウンされるリスクがある）に違反することは別として、それは遅く、信頼性がありません。

理想的なプラクティスは、メールプロバイダーが提供するAPIを使用すること、またはFacebookの場合、テストアカウントや友人などを作成するためのAPIを公開する開発者ツールサービスを使用することです。 APIの使用は少し大変な作業のように思えるかもしれませんが、速度、信頼性、および安定性に見返りがあります。 また、APIが変更されることはほとんどありませんが、WebページとHTMLロケーターは頻繁に変更され、テストフレームワークを更新する必要があります。

テストの任意の時点でWebDriverを使用してサードパーティのサイトにログインすると、テストが長くなるため、テストが失敗するリスクが高くなります。 一般的な経験則として、テストが長くなるほど脆弱で信頼性が低くなります。

[W3C準拠](//w3c.github.io/webdriver/webdriver-spec.html) のWebDriver実装は、サービス拒否攻撃を軽減できるように、`navigator`オブジェクトに`WebDriver`プロパティで注釈を付けます。

# 5 - テストの依存関係

自動テストに関する一般的な考え方と誤解は、特定のテスト順序に関するものです。 テストは **任意** の順序で実行でき、成功するために完了するために他のテストに依存してはなりません。

# 6 - パフォーマンステスト

通常、SeleniumとWebDriverを使用したパフォーマンステストはお勧めしません。 それができないからではなく、ジョブに最適化されておらず、良い結果が得られないからです。

ユーザーのコンテキストでパフォーマンステストを行うのが理想的なように思えるかもしれませんが、WebDriverテストスイートは、外部および内部の脆弱性の多くのポイントにさらされます。 たとえば、ブラウザの起動速度、HTTPサーバーの速度、JavaScriptまたはCSSをホストするサードパーティサーバーの応答、およびWebDriver実装自体の計測ペナルティ。 これらのポイントが変わることで、結果が変わります。 Webサイトのパフォーマンスと外部リソースのパフォーマンスの違いを区別することは困難です。また、ブラウザでWebDriverを使用すること、特にスクリプトを挿入する場合のパフォーマンスの低下を把握することも困難です。

他の潜在的な魅力は “時間の節約” です。 機能テストとパフォーマンステストを同時に実行します。 ただし、機能テストとパフォーマンステストには反対の目的があります。 機能をテストするために、テスターは忍耐強くロードを待つ必要があるかもしれませんが、これはパフォーマンステスト結果を曖昧にし、その逆もまた同様です。

Webサイトのパフォーマンスを改善するには、改善すべき点を知るために、環境の違いに関係なく全体的なパフォーマンスを分析し、貧弱なコードプラクティス、個々のリソース（例えば、CSSまたはJavaScript）のパフォーマンスの内訳を特定できる必要があります。 このジョブを実行できるパフォーマンステストツールが既にあり、それらは改善を提案できるレポートと分析を提供します。

使用する（オープンソース）パッケージの例は次のとおりです。: [JMeter](/ja/)

# 7 - リンクスパイダー

WebDriverを使用してリンクをスパイダーすることは、実行できないためではなく、最も理想的なツールではないため明らかに推奨される方法ではありません。 WebDriverの起動には時間が必要であり、テストの記述方法によっては、ページに到達してDOMを通過するために数秒から1分かかる場合があります。

このためにWebDriverを使用する代わりに、[curl](https://curl.se/) コマンドを実行するか、BeautifulSoupなどのライブラリを使用することにより、これらの方法はブラウザーの作成やページへの移動に依存しないため、時間を大幅に節約できます。 このタスクにWebDriverを使用しないことで、時間を大幅に節約できます。

# 8 - 二要素認証

----
url: https://www.selenium.dev/ja/documentation/webdriver/support_features/thread_guard/
----

# ThreadGuard

このクラスは、Javaバインディングでのみ使用可能です。

ThreadGuardは、ドライバーが、それを作成した同じスレッドからのみ呼び出されることを確認します。 特に並行してテストを実行する場合のスレッドの問題は、不可解でエラーの診断が難しい場合があります。 このラッパーを使用すると、このカテゴリのエラーが防止され、発生時に例外が発生します。

次の例は、スレッドの衝突をシミュレートします。

```java
public class DriverClash {
  //thread main (id 1) created this driver
  private WebDriver protectedDriver = ThreadGuard.protect(new ChromeDriver());

  static {
    System.setProperty("webdriver.chrome.driver", "<Set path to your Chromedriver>");
  }

  //Thread-1 (id 24) is calling the same driver causing the clash to happen
  Runnable r1 = () -> {protectedDriver.get("https://selenium.dev");};
  Thread thr1 = new Thread(r1);

  void runThreads(){
    thr1.start();
  }

  public static void main(String[] args) {
    new DriverClash().runThreads();
  }
}
```

結果は以下のとおりです。

```text
Exception in thread "Thread-1" org.openqa.selenium.WebDriverException:
Thread safety error; this instance of WebDriver was constructed
on thread main (id 1)and is being accessed by thread Thread-1 (id 24)
This is not permitted and *will* cause undefined behaviour
```


最終更新 September 23, 2022: [rename additional features section back to support features to re-emphasize the distinct purpose of support classes (c70272e7f8b)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/c70272e7f8be03fada236fd1f6dc75e81ec79638)

----
url: https://www.selenium.dev/ja/documentation/webdriver/interactions/print_page/
----

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L14-L17)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L12-L19)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L12-L14)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L23-L26)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L22-L29)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L18-L20)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L32-L35)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L32-L38)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L24-L26)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L41-L48)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L51-L57)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L30-L35)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L53-L57)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L61-L68)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L42-L45)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L63-L66)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L41-L48)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L49-L51)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L72-L75)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L71-L78)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L55-L57)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java#L27-L31)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.Pdf;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.PrintsPage;
import dev.selenium.BaseTest;

public class PrintsPageTest extends BaseTest{

    @BeforeEach
    public void setup() {
        ChromeOptions options = getDefaultChromeOptions();
        options.setCapability("webSocketUrl", true);
        driver = new ChromeDriver(options);
    }

    @Test
    public void PrintWithPrintsPageTest() 
    {
        driver.get("https://www.selenium.dev/");
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }

    @Test
    public void PrintWithBrowsingContextTest() 
    {
        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);
        Assertions.assertTrue(printPage.length() > 0);
    }
}
```

**BrowsingContext()**

```java
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        PrintOptions printOptions = new PrintOptions();
        String printPage = browsingContext.print(printOptions);
        Assertions.assertTrue(printPage.length() > 0);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java#L37-L41)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.Pdf;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.PrintsPage;
import dev.selenium.BaseTest;

public class PrintsPageTest extends BaseTest{

    @BeforeEach
    public void setup() {
        ChromeOptions options = getDefaultChromeOptions();
        options.setCapability("webSocketUrl", true);
        driver = new ChromeDriver(options);
    }

    @Test
    public void PrintWithPrintsPageTest() 
    {
        driver.get("https://www.selenium.dev/");
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }

    @Test
    public void PrintWithBrowsingContextTest() 
    {
        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);
        Assertions.assertTrue(printPage.length() > 0);
    }
}
```

```cs
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L81-L88)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

**print\_page()**

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    pdf = driver.print_page(print_options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_prints_page.py#L12-L14)

##### /examples/python/tests/interactions/test\_prints\_page.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_prints_page(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    pdf = driver.print_page(print_options)
    assert len(pdf) > 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

----
url: https://www.selenium.dev/documentation/test_practices/discouraged/
----

# Discouraged behaviors

Things to avoid when automating browsers with Selenium.

***

##### [Captchas](/documentation/test_practices/discouraged/captchas/)

##### [File downloads](/documentation/test_practices/discouraged/file_downloads/)

##### [HTTP response codes](/documentation/test_practices/discouraged/http_response_codes/)

##### [Gmail, email and Facebook logins](/documentation/test_practices/discouraged/gmail_email_and_facebook_logins/)

##### [Test dependency](/documentation/test_practices/discouraged/test_dependency/)

##### [Performance testing](/documentation/test_practices/discouraged/performance_testing/)

##### [Link spidering](/documentation/test_practices/discouraged/link_spidering/)

##### [Two Factor Authentication](/documentation/test_practices/discouraged/two_factor_authentication/)

----
url: https://www.selenium.dev/pt-br/documentation/grid/configuration/toml_options/
----

# Toml Options

```toml
[section1]
option1="value"

[section2]
option2=["value1","value2"]
option3=true
```

Below are some examples of Grid components configured with a Toml file, the component can be started in the following way:

```
java -jar selenium-server-<version>.jar <component> --config /path/to/file/<file-name>.toml
```

### Standalone

A Standalone server, running on port 4449, and a new session request timeout of 500 seconds.

```toml
[server]
port = 4449

[sessionqueue]
session-request-timeout = 500
```

### Specific browsers and a limit of max sessions

A Standalone server or a Node which only has Firefox and Chrome enabled by default.

```toml
[node]
drivers = ["chrome", "firefox"]
max-sessions = 3
```

### Configuring and customising drivers

Standalone or Node server with customised drivers, which allows things like having Firefox Beta or Nightly, and having different browser versions.

```toml
[node]
detect-drivers = false
[[node.driver-configuration]]
max-sessions = 100
display-name = "Firefox Nightly"
stereotype = "{\"browserName\": \"firefox\", \"browserVersion\": \"93\", \"platformName\": \"MAC\", \"moz:firefoxOptions\": {\"binary\": \"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"
[[node.driver-configuration]]
display-name = "Chrome Beta"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"94\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta\"}}"
[[node.driver-configuration]]
display-name = "Chrome Dev"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"95\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev\"}}"
webdriver-executable = '/path/to/chromedriver/95/chromedriver'
```

### Standalone or Node with Docker

A Standalone or Node server that is able to run each new session in a Docker container. Disabling drivers detection, having maximum 2 concurrent sessions. Stereotypes configured need to be mapped to a Docker image, and the Docker daemon needs to be exposed via http/tcp. In addition, it is possible to define which device files, accessible on the host, will be available in containers through the `devices` property. Refer to the [docker](https://docs.docker.com/engine/reference/commandline/run/#add-host-device-to-container---device) documentation for more information about how docker device mapping works.

```toml
[node]
detect-drivers = false
max-sessions = 2

[docker]
configs = [
    "selenium/standalone-chrome:93.0", "{\"browserName\": \"chrome\", \"browserVersion\": \"91\"}", 
    "selenium/standalone-firefox:92.0", "{\"browserName\": \"firefox\", \"browserVersion\": \"92\"}"
]
#Optionally define all device files that should be mapped to docker containers
#devices = [
#    "/dev/kvm:/dev/kvm"
#]
url = "http://localhost:2375"
video-image = "selenium/video:latest"
```

### Relaying commands to a service endpoint that supports WebDriver

It is useful to connect an external service that supports WebDriver to Selenium Grid. An example of such service could be a cloud provider or an Appium server. In this way, Grid can enable more coverage to platforms and versions not present locally.

The following is an en example of connecting an Appium server to Grid.

```toml
[node]
detect-drivers = false

[relay]
# Default Appium/Cloud server endpoint
url = "http://localhost:4723/wd/hub"
status-endpoint = "/status"
# Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status (e.g. HTTP/1.1, HTTP/2)
protocol-version = "HTTP/1.1"
# Stereotypes supported by the service. The initial number is "max-sessions", and will allocate 
# that many test slots to that particular configuration
configs = [
  "5", "{\"browserName\": \"chrome\", \"platformName\": \"android\", \"appium:platformVersion\": \"11\"}"
]
```

### Basic auth enabled

It is possible to protect a Grid with basic auth by configuring the Router/Hub/Standalone with a username and password. This user/password combination will be needed when loading the Grid UI or starting a new session.

```toml
[router]
username = "admin"
password = "myStrongPassword"
```

Here is a Java example showing how to start a session using the configured user and password.

```java
ClientConfig clientConfig = ClientConfig.defaultConfig()
  .baseUrl(new URL("http://localhost:4444"))
  .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"));
HttpCommandExecutor executor = new HttpCommandExecutor(clientConfig);
RemoteWebDriver driver = new RemoteWebDriver(executor, new ChromeOptions());
```

In other languages, you can use the URL http\://admin:myStrongPassword\@localhost:4444

### Setting custom capabilities for matching specific Nodes

**Important:** Custom capabilities need to be set in the configuration in all Nodes. They also need to be included always in every session request.

```toml
[node]
detect-drivers = false

[[node.driver-configuration]]
display-name = "firefox"
stereotype = '{"browserName": "firefox", "platformName": "macOS", "browserVersion":"96", "networkname:applicationName":"node_1", "nodename:applicationName":"app_1" }'
max-sessions = 5
```

Here is a Java example showing how to match that Node

```java
FirefoxOptions options = new FirefoxOptions();
options.setCapability("networkname:applicationName", "node_1");
options.setCapability("nodename:applicationName", "app_1");
options.setBrowserVersion("96");
options.setPlatformName("macOS");
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

### Enabling Managed downloads by the Node.

The Node can be instructed to manage downloads automatically. This will cause the Node to save all files that were downloaded for a particular session into a temp directory, which can later be retrieved from the node. To turn this capability on, use the below configuration:

```toml
[node]
enable-managed-downloads = true
```

Refer to the [CLI section](https://www.selenium.dev/pt-br/documentation/grid/configuration/cli_options/#enabling-managed-downloads-by-the-node) for a complete example.

Última modificação April 23, 2024: [\[grid\] update list CLI/TOML options (#1683) (1f27efd060f)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/1f27efd060fbacdd93b29416182faa8636bd6604)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/troubleshooting/upgrade_to_selenium_4/
----

# Como atualizar para Selenium 4

```java
DesiredCapabilities caps = DesiredCapabilities.firefox();
caps.setCapability("platform", "Windows 10");
caps.setCapability("version", "92");
caps.setCapability("build", myTestBuild);
caps.setCapability("name", myTestName);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), caps);
```

```javascript
caps = {};
caps['browserName'] = 'Firefox';
caps['platform'] = 'Windows 10';
caps['version'] = '92';
caps['build'] = myTestBuild;
caps['name'] = myTestName;
```

```csharp
DesiredCapabilities caps = new DesiredCapabilities();
caps.SetCapability("browserName", "firefox");
caps.SetCapability("platform", "Windows 10");
caps.SetCapability("version", "92");
caps.SetCapability("build", myTestBuild);
caps.SetCapability("name", myTestName);
var driver = new RemoteWebDriver(new Uri(CloudURL), caps);
```

```rb
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L123-L130)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```python
caps = {}
caps['browserName'] = 'firefox'
caps['platform'] = 'Windows 10'
caps['version'] = '92'
caps['build'] = my_test_build
caps['name'] = my_test_name
driver = webdriver.Remote(cloud_url, desired_capabilities=caps)
```

```java
FirefoxOptions browserOptions = new FirefoxOptions();
browserOptions.setPlatformName("Windows 10");
browserOptions.setBrowserVersion("92");
Map<String, Object> cloudOptions = new HashMap<>();
cloudOptions.put("build", myTestBuild);
cloudOptions.put("name", myTestName);
browserOptions.setCapability("cloud:options", cloudOptions);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), browserOptions);
```

```javascript
capabilities = {
  browserName: 'firefox',
  browserVersion: '92',
  platformName: 'Windows 10',
  'cloud:options': {
     build: myTestBuild,
     name: myTestName,
  }
}
```

```csharp
var browserOptions = new FirefoxOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "92";
var cloudOptions = new Dictionary<string, object>();
cloudOptions.Add("build", myTestBuild);
cloudOptions.Add("name", myTestName);
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);
var driver = new RemoteWebDriver(new Uri(CloudURL), browserOptions);
```

```rb
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L38-L47)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```python
from selenium.webdriver.firefox.options import Options as FirefoxOptions
options = FirefoxOptions()
options.browser_version = '92'
options.platform_name = 'Windows 10'
cloud_options = {}
cloud_options['build'] = my_test_build
cloud_options['name'] = my_test_name
options.set_capability('cloud:options', cloud_options)
driver = webdriver.Remote(cloud_url, options=options)
```

### Utilitário para encontrar elemento (s) no Java

O utilitário para localizar elementos no Java (interfaces `FindsBy`) foram removidos visto que se destinavam apenas a uso interno. Os exemplos de código a seguir explicam isso melhor.

Encontrando um único elemento com `findElement*`

Antes

```java

driver.findElementByClassName("className");
driver.findElementByCssSelector(".className");
driver.findElementById("elementId");
driver.findElementByLinkText("linkText");
driver.findElementByName("elementName");
driver.findElementByPartialLinkText("partialText");
driver.findElementByTagName("elementTagName");
driver.findElementByXPath("xPath");
```

Depois

```java

driver.findElement(By.className("className"));
driver.findElement(By.cssSelector(".className"));
driver.findElement(By.id("elementId"));
driver.findElement(By.linkText("linkText"));
driver.findElement(By.name("elementName"));
driver.findElement(By.partialLinkText("partialText"));
driver.findElement(By.tagName("elementTagName"));
driver.findElement(By.xpath("xPath"));
```

Encontrando multiplos elementos com `findElements*`

Antes

```java

driver.findElementsByClassName("className");
driver.findElementsByCssSelector(".className");
driver.findElementsById("elementId");
driver.findElementsByLinkText("linkText");
driver.findElementsByName("elementName");
driver.findElementsByPartialLinkText("partialText");
driver.findElementsByTagName("elementTagName");
driver.findElementsByXPath("xPath");
```

Depois

```java

driver.findElements(By.className("className"));
driver.findElements(By.cssSelector(".className"));
driver.findElements(By.id("elementId"));
driver.findElements(By.linkText("linkText"));
driver.findElements(By.name("elementName"));
driver.findElements(By.partialLinkText("partialText"));
driver.findElements(By.tagName("elementTagName"));
driver.findElements(By.xpath("xPath"));
```

## Atualizando as dependências

Verifique as subseções abaixo para isntalar o Selenium 4 e atualizar as dependências do seu projeto

### Java

O processo de atualização do Selenium depende de qual ferramenta de compilação está sendo usada. Vamos mostrar as mais comuns para Java, como [Maven](https://maven.apache.org/) e [Gradle](https://gradle.org/). A versão minínma do Java ainda é 8.

#### Maven

Antes

```xml

<dependencies>
  <!-- more dependencies ... -->
  <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.141.59</version>
  </dependency>
  <!-- more dependencies ... -->
</dependencies>
```

Depois

```xml

<dependencies>
    <!-- more dependencies ... -->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.4.0</version>
    </dependency>
    <!-- more dependencies ... -->
</dependencies>
```

Após realizar a mudança, você pode executar `mvn clean compile` no mesmo diretório, onde o arquivo `pom.xml` está.

#### Gradle

Antes

```jsonpath

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.141.59'
}
test {
    useJUnitPlatform()
}
```

Depois

```jsonpath

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '4.4.0'
}
test {
    useJUnitPlatform()
}
```

Após realizar a mudança, você pode executar `./gradlew clean build` no mesmo diretório onde o arquivo `build.gradle`está.

Para verifica todas as versões do Java, você pode ir até [MVNRepository](https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java).

### C\#

O local para obter atualizações para Selenium 4 em C# é [NuGet](https://www.nuget.org/) Dentro do pacaote [`Selenium.WebDriver`](https://www.nuget.org/packages/Selenium.WebDriver/4.4.0) você pode seguir as instruções para atualizar para ultima versão. Dentro do Visual Studio, através do NuGet Package Manager você pode executar:

```shell
PM> Install-Package Selenium.WebDriver -Version 4.4.0
```

### Python

A mudança mais importante para usar o Python é a versão minima requerida. Para Selenium 4 a versão miníma requerida será Python3.7 ou superior. Mais detalhes podem ser encontrados aqui:[Python Package Index](https://pypi.org/project/selenium/4.4.3/). Para atualizar através da linha de comando, você pode executar:

```shell
pip install selenium==4.4.3
```

### Ruby

Detalhes para atualizar para o Selenium 4 podem ser vistos aqui: [selenium-webdriver](https://rubygems.org/gems/selenium-webdriver/versions/4.4.0) gem in RubyGems Para instalar a ultima versão, você pode executar:

```shell
gem install selenium-webdriver
```

Para adicioná-lo ao seu Gemfile:

```shell
gem 'selenium-webdriver', '~> 4.4.0'
```

### JavaScript

O pacote selenium-webdriver pode ser encontrado pelo Node package manager, [npmjs](https://www.npmjs.com). Selenium 4 pode ser encontrado [aqui](https://www.npmjs.com/package/selenium-webdriver/v/4.4.0). Para instalar, você pode executar:

```shell
npm install selenium-webdriver
```

Ou, atualize o seu package.json e execute `npm install`:

```json
{
  "name": "selenium-tests",
  "version": "1.0.0",
  "dependencies": {
    "selenium-webdriver": "^4.4.0"
  }
}
```

## Possíveis erros e mensagens de descontinuação

Aqui temos um conjunto de exemplos de código que o ajudarão a superar as mensagens de descontinuação, que você pode encontrar após atualizar para o Selenium 4.

### Java

#### Waits e Timeout

Os parametros que eram esperados de ser recebidos em um Timeout trocaram de `(long time, TimeUnit unit)` para o `(Duration duration)`.

Antes

```java

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(2, TimeUnit.MINUTES);
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
```

Depois

```java

driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().timeouts().scriptTimeout(Duration.ofMinutes(2));
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
```

As esperas(waits) também esperam parâmetros diferentes agora. O `WebDriverWait` agora espera uma `Duration` em vez de um tempo limite `long` em segundos e milissegundos. Os métodos utilitários `withTimeout` e `pollingEvery` do `FluentWait` passaram do `(long time, TimeUnit unit)` para o `(Duration duration)`.

Antes

```java

new WebDriverWait(driver, 3)
.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(30, TimeUnit.SECONDS)
  .pollingEvery(5, TimeUnit.SECONDS)
  .ignoring(NoSuchElementException.class);
```

Depois

```java

new WebDriverWait(driver, Duration.ofSeconds(3))
  .until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

  Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(Duration.ofSeconds(30))
  .pollingEvery(Duration.ofSeconds(5))
  .ignoring(NoSuchElementException.class);
```

#### A fusão de recursos não estã mais alterando o objeto de invocação

Antes era possível fundir um conjunto diferente de recursos em outro counjunto, e isso alterava o objeto de chamada. Agora, o resultado da operação de fusão precisa ser atribuído.

Antes

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options.merge(capabilities);

//Como resultado, o objeto `options` estava sendo modificado.
```

Depois

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options = options.merge(capabilities);

// O resultado da chamada `merge`  precisa ser atribuído a um objeto.
```

#### Firefox Legacy

Antes do GeckoDriver existir, o projeto Selenium tinha uma implementação de driver para automatizar o Firefox(versão<48). Entretanto, esta implementação não é mais necessária, pois não funciona nas versões mais recentes do Firefox. Para evitar graves problemas ao atualizar para o Selenium 4, a opção `setLegacy` será mostrada como obsoleta. A recomendação é parar de utilizar a implementação antiga e depender apenas do GeckoDriver. O código a seguir mostrará a linha `setLegacy` obsoleta após atualizar.

```java
FirefoxOptions options = new FirefoxOptions();
options.setLegacy(true);
```

#### `BrowserType`

A interface `BrowserType` existe há um bom tempo, más ela está ficando obsoleta a favor da nova interface `Browser`.

Antes

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", BrowserType.FIREFOX);
```

Depois

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", Browser.FIREFOX);
```

### C\#

#### `AddAdditionalCapability` está descontinuada

Em vez dela, `AddAdditionalOption` é recomendada. Aqui está um exemplo mostrando isso:

Antes

```cs

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalCapability("cloud:options", cloudOptions, true);
```

Depois

```cs

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);
```

### Python

#### `executable_path foi descontinuada, por favor, passe um Service object`

No Selenium 4, você precisara definir o `executable_path` a partir de um objeto Service para evitar avisos de depreciação. (Ou não defina o caminho e, em vez disso, certifique-se de que o driver que você precisa esteja no System PATH.)

Antes

```python

from selenium import webdriver
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(
    executable_path=CHROMEDRIVER_PATH, 
    options=options
)
```

Depois

```python

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
options = webdriver.ChromeOptions()
service = ChromeService(executable_path=CHROMEDRIVER_PATH)
driver = webdriver.Chrome(service=service, options=options)
```

## Resumo

Passamos pelas principais mudanças a serem levadas em consideração ao atualizar para o Selenium 4. Cobrimos os diferentes aspectos a serem cobertos quando o código de teste é preparado para a atualização, incluindo sugestões sobre como evitar possíveis problemas que podem aparecer ao usar a nova versão do Selenium. Para finalizar, também abordamos um conjunto de possíveis problemas com os quais você pode se deparar depois da atualização e compartilhamos possíveis correções para esses problemas.

*Este tópico foi originalmente postado no site <https://saucelabs.com/resources/articles/how-to-upgrade-to-selenium-4>*

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/support_features/colors/
----

# 同颜色一起工作

```java
import org.openqa.selenium.support.Color;
  
```

```python
from selenium.webdriver.support.color import Color
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
include Selenium::WebDriver::Support
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
import org.openqa.selenium.support.Color
```

```java
private final Color HEX_COLOUR = Color.fromString("#2F7ED8");
private final Color RGB_COLOUR = Color.fromString("rgb(255, 255, 255)");
private final Color RGB_COLOUR = Color.fromString("rgb(40%, 20%, 40%)");
private final Color RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)");
private final Color RGBA_COLOUR = Color.fromString("rgba(40%, 20%, 40%, 0.5)");
private final Color HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)");
private final Color HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)");
  
```

```python
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
private val HEX_COLOUR = Color.fromString("#2F7ED8")
private val RGB_COLOUR = Color.fromString("rgb(255, 255, 255)")
private val RGB_COLOUR_PERCENT = Color.fromString("rgb(40%, 20%, 40%)")
private val RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)")
private val RGBA_COLOUR_PERCENT = Color.fromString("rgba(40%, 20%, 40%, 0.5)")
private val HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)")
private val HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)")
  
```

```java
private final Color BLACK = Color.fromString("black");
private final Color CHOCOLATE = Color.fromString("chocolate");
private final Color HOTPINK = Color.fromString("hotpink");
  
```

```python
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
private val BLACK = Color.fromString("black")
private val CHOCOLATE = Color.fromString("chocolate")
private val HOTPINK = Color.fromString("hotpink")
  
```

```java
private final Color TRANSPARENT = Color.fromString("transparent");
  
```

```python
TRANSPARENT = Color.from_string('transparent')
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
TRANSPARENT = Color.from_string('transparent')
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
private val TRANSPARENT = Color.fromString("transparent")
  
```

```java
Color loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"));

Color loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"));
  
```

```python
login_button_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('color'))

login_button_background_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('background-color'))
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
login_button_colour = Color.from_string(driver.find_element(id: 'login').css_value('color'))

login_button_background_colour = Color.from_string(driver.find_element(id: 'login').css_value('background-color'))
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
val loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"))

val loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"))
  
```

```java
assert loginButtonBackgroundColour.equals(HOTPINK);
  
```

```python
assert login_button_background_colour == HOTPINK
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
assert(login_button_background_colour == HOTPINK)
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
assert(loginButtonBackgroundColour.equals(HOTPINK))
  
```

```java
assert loginButtonBackgroundColour.asHex().equals("#ff69b4");
assert loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)");
assert loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)");
  
```

```python
assert login_button_background_colour.hex == '#ff69b4'
assert login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)'
assert login_button_background_colour.rgb == 'rgb(255, 105, 180)'
  
```

```csharp
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```ruby
assert(login_button_background_colour.hex == '#ff69b4')
assert(login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)')
assert(login_button_background_colour.rgb == 'rgb(255, 105, 180)')
  
```

```javascript
// This feature is not implemented - Help us by sending a pr to implement this feature
  
```

```kotlin
assert(loginButtonBackgroundColour.asHex().equals("#ff69b4"))
assert(loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)"))
assert(loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)"))
  
```

颜色不再是问题.

最后修改 August 3, 2023: [update wait documentation (#1358)\[deploy site\] (d1af4fe2409)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/d1af4fe2409e2101eaabf23f4e5716428e0bdd56)

----
url: https://www.selenium.dev/_print/documentation/webdriver/browsers/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/webdriver/browsers/).

# Supported Browsers

* 1: [Chrome specific functionality](#pg-4b57d1c19310cdcfaca466338935d932)
* 2: [Edge specific functionality](#pg-f69eab33f76076d768e194ec37783f82)
* 3: [Firefox specific functionality](#pg-ea21098ee4a511484d835225f978be40)
* 4: [IE specific functionality](#pg-3b3d03aa5e50219cec5d2a9563860996)
* 5: [Safari specific functionality](#pg-bf08921e54c39d8aa9ef331a234be1d7)

Each browser has custom capabilities and unique features.

# 1 - Chrome specific functionality

```java
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L36-L37)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L9-L10)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L30-L31)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L51-L55)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_argument("--start-maximized")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L18)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L39)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.args << '--start-maximized'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L17)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L9-L12)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L53)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.binary_location = chrome_bin
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L29)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L49)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.binary = chrome_location
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L29)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L41-L44)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
  @DisabledOnOs(OS.WINDOWS)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L64)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_extension(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L40)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L73-L84)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.add_extension(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L38)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L62-L66)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```py
    options.add_experimental_option("detach", True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L51)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

**Note**: This is already the default behavior in .NET.

```rb
      @driver = Selenium::WebDriver.for :chrome, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L49)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L29-L32)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L78)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L62)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L82)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      @driver = Selenium::WebDriver.for :chrome, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L57)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L19-L22)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L100-L101)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY`\
Property value: String representing path to log file

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L71)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L86)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      @driver = Selenium::WebDriver.for :chrome, service: service
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L71)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L114-L115)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L82)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

`$stdout` and `$stderr` are both valid values

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      expect {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L80)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L129-L130)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY`\
Property value: String representation of `ChromiumDriverLogLevel` enum

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L93)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      @driver = Selenium::WebDriver.for :chrome, service: service
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L91)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L147-L148)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows toggling these features by System Property:\
Property keys: `ChromeDriverService.CHROME_DRIVER_APPEND_LOG_PROPERTY` and `ChromeDriverService.CHROME_DRIVER_READABLE_TIMESTAMP`\
Property value: `"true"` or `"false"`

```py
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L104)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb

      @driver = Selenium::WebDriver.for :chrome, service: service
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L101-L102)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L166-L167)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows disabling build checks by System Property:\
Property key: `ChromeDriverService.CHROME_DRIVER_DISABLE_BUILD_CHECK`\
Property value: `"true"` or `"false"`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L115)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            service.DisableBuildCheck = true;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L155)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      @driver = Selenium::WebDriver.for :chrome, service: service
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L112)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L230-L235)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L170-L174)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L123-L128)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L204-L210)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L129-L135)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
        'offline' => false,
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L133)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L247)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    logs = driver.get_log("browser")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L186)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L145)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    options.setBrowserVersion("stable");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L189)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    driver.set_permissions('camera', 'denied')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L149)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L153-L154)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### DevTools

See the [Chrome DevTools](https://www.selenium.dev/documentation/webdriver/bidi/cdp/) section for more information about using Chrome DevTools

# 2 - Edge specific functionality

```java

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L38-L39)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options = get_default_edge_options()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L9-L10)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        {
            var options = new EdgeOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L30-L31)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let options = new edge.Options();
    driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/openEdgeTest.spec.js#L11-L15)

##### /examples/javascript/test/getting\_started/openEdgeTest.spec.js

```js
const {Browser, Builder} = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');


describe('Open Edge', function () {
  let driver;



  before(async function () {
    let options = new edge.Options();
    driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options)
      .build();
  });

  after(async () => await driver.quit());

  it('Basic Edge test', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
  public void arguments() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L46)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L18)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L39)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.args << '--start-maximized'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L17)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.addArguments('--headless=new'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L12)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```java
  public void setBrowserLocation() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L55)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L29)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L49)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.binary = edge_location
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L25)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L66)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L40)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L61)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.add_extension(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L34)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L55)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L51)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

**Note**: This is already the default behavior in .NET.

```rb
      options.detach = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L45)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.detachDriver(true))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L32)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```java
  public void excludeSwitches() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L79)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L62)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L76)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.exclude_switches << 'disable-popup-blocking'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L53)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L22)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```java
  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L101)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY`\
Property value: String representing path to log file

```py
def test_log_to_file(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L71)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L86)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L67)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    File logLocation = getTempFile("logsToConsole", ".log");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L114)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
def test_log_to_stdout(capfd):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L82)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

`$stdout` and `$stderr` are both valid values

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L76)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L127-L128)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY`\
Property value: String representation of `ChromiumDriverLogLevel` enum

```py
def test_log_level(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L93)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '--log-level=DEBUG'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L87)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L143-L144)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows toggling these features by System Property:\
Property keys: `EdgeDriverService.EDGE_DRIVER_APPEND_LOG_PROPERTY` and `EdgeDriverService.EDGE_DRIVER_READABLE_TIMESTAMP`\
Property value: `"true"` or `"false"`

```py
def test_log_features(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L104)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << '--append-log'
      service.args << '--readable-timestamp'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L97-L98)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L161-L162)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows disabling build checks by System Property:\
Property key: `EdgeDriverService.EDGE_DRIVER_DISABLE_BUILD_CHECK`\
Property value: `"true"` or `"false"`

```py
def test_build_checks(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L115)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L155)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << '--disable-build-check'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L108)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L225-L230)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L170-L174)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L119-L123)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L198-L204)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L129-L135)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L129)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    consoleLogButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L242)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L186)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      sleep 1
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L141)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    EdgeDriver driver = new EdgeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L184)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L149)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L149-L150)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### DevTools

See the [Chrome DevTools](https://www.selenium.dev/documentation/webdriver/bidi/cdp/) section for more information about using DevTools in Edge

# 3 - Firefox specific functionality

```java
    driver = new FirefoxDriver(options);
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L36-L37)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L10-L11)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
        public void BasicOptions()
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L34-L35)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/openFirefoxTest.spec.js#L10-L13)

##### /examples/javascript/test/getting\_started/openFirefoxTest.spec.js

```js
const {Browser, Builder} = require('selenium-webdriver');
const firefox = require('selenium-webdriver/firefox');


describe('Open Firefox', function () {
  let driver;

  before(async function () {
    let options = new firefox.Options();
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options)
      .build();
  });

  after(async () => await driver.quit());

  it('Basic Firefox test', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options.add_argument("-headless")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L19)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            var options = new FirefoxOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L43)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options.args << '-headless'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L17)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
      .setFirefoxOptions(options.addArguments('--headless'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L12)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L54)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options.binary_location = firefox_bin
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L28)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            var options = new FirefoxOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L53)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options.binary = firefox_location
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L25)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
    driver = new FirefoxDriver(options);
  }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L211-L216)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L160-L168)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```csharp
var options = new FirefoxOptions();
var profile = new FirefoxProfile();
options.Profile = profile;
var driver = new FirefoxDriver(options);
  
```

```rb
      profile = Selenium::WebDriver::Firefox::Profile.new
        profile['browser.download.dir'] = '/tmp/webdriver-downloads'
        options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L139-L141)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true
  
  require 'spec_helper'
  
  RSpec.describe 'Firefox' do
    describe 'Options' do
      let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }
  
      it 'basic options' do
        options = Selenium::WebDriver::Options.firefox
        @driver = Selenium::WebDriver.for :firefox, options: options
      end
  
      it 'add arguments' do
        options = Selenium::WebDriver::Options.firefox
  
        options.args << '-headless'
  
        @driver = Selenium::WebDriver.for :firefox, options: options
      end
  
      it 'sets location of binary' do
        options = Selenium::WebDriver::Options.firefox
  
        options.binary = firefox_location
  
        @driver = Selenium::WebDriver.for :firefox, options: options
      end
    end
  
    describe 'Service' do
      let(:file_name) { Tempfile.new('geckodriver').path }
      let(:root_directory) { Dir.mktmpdir }
  
      after do
        FileUtils.rm_f(file_name)
        FileUtils.rm_rf(root_directory)
      end
  
      it 'logs to file' do
        service = Selenium::WebDriver::Service.firefox
  
        service.log = file_name
  
        @driver = Selenium::WebDriver.for :firefox, service: service
        expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
      end
  
      it 'logs to console' do
        service = Selenium::WebDriver::Service.firefox
  
        service.log = $stdout
  
        expect {
          @driver = Selenium::WebDriver.for :firefox, service: service
        }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
      end
  
      it 'sets log level' do
        service = Selenium::WebDriver::Service.firefox
        service.log = file_name
  
        service.args += %w[--log debug]
  
        @driver = Selenium::WebDriver.for :firefox, service: service
        expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
      end
  
      it 'stops truncating log lines' do
        service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])
  
        service.args << '--log-no-truncate'
  
        @driver = Selenium::WebDriver.for :firefox, service: service
        expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
      end
  
      it 'sets default profile location' do
        service = Selenium::WebDriver::Service.firefox
  
        service.args += ['--profile-root', root_directory]
  
        @driver = Selenium::WebDriver.for :firefox, service: service
        profile_location = Dir.new(@driver.capabilities['moz:profile'])
        expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
      end
    end
  
    describe 'Features' do
      let(:driver) { start_firefox }
  
      it 'installs addon' do
        extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
  
        driver.install_addon(extension_file_path)
  
        driver.get 'https://www.selenium.dev/selenium/web/blank.html'
        injected = driver.find_element(id: 'webextensions-selenium-example')
        expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
      end
  
      it 'uninstalls addon' do
        extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
        extension_id = driver.install_addon(extension_file_path)
  
        driver.uninstall_addon(extension_id)
  
        driver.get 'https://www.selenium.dev/selenium/web/blank.html'
        expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
      end
  
      it 'installs unsigned addon' do
        extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)
  
        driver.install_addon(extension_dir_path, true)
  
        driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
        injected = driver.find_element(id: 'webextensions-selenium-example')
        expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
      end
  
      it 'takes full page screenshot' do
        driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
        Dir.mktmpdir('screenshot_test') do |dir|
          screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))
  
          expect(screenshot).to be_a File
        end
      end
  
      it 'sets the context' do
        driver.context = 'content'
        expect(driver.context).to eq 'content'
      end
    end
  
    describe 'Profile' do
      it 'creates a new profile' do
        profile = Selenium::WebDriver::Firefox::Profile.new
        profile['browser.download.dir'] = '/tmp/webdriver-downloads'
        options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
        expect(options.profile).to eq(profile)
      end
    end
  
    def driver_finder
      options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
      service = Selenium::WebDriver::Service.firefox
      finder = Selenium::WebDriver::DriverFinder.new(options, service)
      ENV['GECKODRIVER_BIN'] = finder.driver_path
      ENV['FIREFOX_BIN'] = finder.browser_path
    end
  end
  
```

```javascript
const { Builder } = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');

const options = new firefox.Options();
let profile = '/path to custom profile';
options.setProfile(profile);
const driver = new Builder()
    .forBrowser('firefox')
    .setFirefoxOptions(options)
    .build();
  
```

```kotlin
val options = FirefoxOptions()
options.profile = FirefoxProfile()
driver = FirefoxDriver(options)
  
```

```java
        new GeckoDriverService.Builder().withLogFile(logLocation).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L62-L63)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY`\
Property value: String representing path to log file

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L36)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L43)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withLogOutput(System.out).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L76-L77)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L48)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L52)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L90-L91)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY`\
Property value: String representation of `FirefoxDriverLogLevel` enum

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L59)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args += %w[--log debug]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L63)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L106-L107)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_NO_TRUNCATE`\
Property value: `"true"` or `"false"`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L70)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '--log-no-truncate'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L72)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L118-L119)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_PROFILE_ROOT`\
Property value: String representing path to profile root directory

```py
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L81)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args += ['--profile-root', root_directory]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L81)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L133)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.install_addon(addon_path_xpi)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L94)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L137)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      driver.install_addon(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L95)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    let id = await driver.installAddon(xpiPath);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L25)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L148)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.uninstall_addon(id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L106)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```cs
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L152)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      driver.uninstall_addon(extension_id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L106)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    await driver.uninstallAddon(id);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L26)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L160)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.install_addon(addon_path_dir, temporary=True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L115)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```cs
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L165)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```rb
      driver.install_addon(extension_dir_path, true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L115)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    let id = await driver.installAddon(xpiPath, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L41)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L181)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.save_full_page_screenshot("full_page_screenshot.png")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L139)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L125)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
    // Verify the context is back to "content"
    Assertions.assertEquals(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L197-L198)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L151-L152)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      driver.context = 'content'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L132)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

**Note**: As of Firefox 138, geckodriver needs to be started with the argument `--allow-system-access` to switch the context to `CHROME`.

# 4 - IE specific functionality

```java
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#38-L41)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

```py
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L11-L14)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L35-L38)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

```rb
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L17-L20)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#46-L47)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

```py
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L21-L22)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L44-L45)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L24-L25)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
let driver = await new Builder()
.forBrowser('internet explorer')
.setIEOptions(options)
.build();
```

```kotlin
val options = InternetExplorerOptions()
val driver = InternetExplorerDriver(options)
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.waitForUploadDialogUpTo(Duration.ofSeconds(2));
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L28-L29)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.FileUploadDialogTimeout = TimeSpan.FromMilliseconds(2000);
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.file_upload_dialog_timeout = 2000
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L29)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().fileUploadDialogTimeout(2000);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.waitForUploadDialogUpTo(Duration.ofSeconds(2))
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.destructivelyEnsureCleanSession();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ensure_clean_session = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L38-L39)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.EnsureCleanSession = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ensure_clean_session = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L35)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true
    
    require 'spec_helper'
    
    RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
      describe 'Options' do
        let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
        let(:url) { 'https://www.selenium.dev/selenium/web/' }
    
        before do
          @options = Selenium::WebDriver::IE::Options.new
          @options.attach_to_edge_chrome = true
          @options.edge_executable_path = edge_location
        end
    
        it 'basic options Win10' do
          options = Selenium::WebDriver::IE::Options.new
          options.attach_to_edge_chrome = true
          options.edge_executable_path = edge_location
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'basic options Win11' do
          options = Selenium::WebDriver::Options.ie
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'sets the file upload dialog timeout' do
          @options.file_upload_dialog_timeout = 2000
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ensures a clean session' do
          @options.ensure_clean_session = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the zoom setting' do
          @options.ignore_zoom_level = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the protected mode settings' do
          @options.ignore_protected_mode_settings = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'adds the silent option' do
          @options.silent = true
          expect(@options.silent).to be_truthy
        end
    
        it 'sets the command line options' do
          @options.add_argument('-k')
          Selenium::WebDriver.for(:ie, options: @options)
        end
    
        it 'launches ie with the create process api' do
          @options.force_create_process_api = true
          Selenium::WebDriver.for(:ie, options: @options)
          expect(@options.instance_variable_get(:@options)['force_create_process_api'])
            .to eq({force_create_process_api: true})
        end
      end
    
      describe 'Service' do
        let(:file_name) { Tempfile.new('iedriver').path }
        let(:root_directory) { Dir.mktmpdir }
    
        after do
          FileUtils.rm_f(file_name)
          FileUtils.remove_entry root_directory
        end
    
        it 'logs to file' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = file_name
    
          @driver = Selenium::WebDriver.for :ie, service: service
          expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
        end
    
        it 'logs to console' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = $stdout
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
        end
    
        it 'sets log level' do
          service = Selenium::WebDriver::Service.ie
          service.log = $stdout
    
          service.args << '-log-level=WARN'
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
        end
    
        it 'sets location for supporting files' do
          service = Selenium::WebDriver::Service.ie
    
          service.args << "–extract-path=#{root_directory}"
    
          @driver = Selenium::WebDriver.for :ie, service: service
        end
      end
    end
    
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().ensureCleanSession(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.destructivelyEnsureCleanSession()
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.ignoreZoomSettings();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L48-L49)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.IgnoreZoomLevel = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ignore_zoom_level = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L41)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true
    
    require 'spec_helper'
    
    RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
      describe 'Options' do
        let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
        let(:url) { 'https://www.selenium.dev/selenium/web/' }
    
        before do
          @options = Selenium::WebDriver::IE::Options.new
          @options.attach_to_edge_chrome = true
          @options.edge_executable_path = edge_location
        end
    
        it 'basic options Win10' do
          options = Selenium::WebDriver::IE::Options.new
          options.attach_to_edge_chrome = true
          options.edge_executable_path = edge_location
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'basic options Win11' do
          options = Selenium::WebDriver::Options.ie
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'sets the file upload dialog timeout' do
          @options.file_upload_dialog_timeout = 2000
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ensures a clean session' do
          @options.ensure_clean_session = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the zoom setting' do
          @options.ignore_zoom_level = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the protected mode settings' do
          @options.ignore_protected_mode_settings = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'adds the silent option' do
          @options.silent = true
          expect(@options.silent).to be_truthy
        end
    
        it 'sets the command line options' do
          @options.add_argument('-k')
          Selenium::WebDriver.for(:ie, options: @options)
        end
    
        it 'launches ie with the create process api' do
          @options.force_create_process_api = true
          Selenium::WebDriver.for(:ie, options: @options)
          expect(@options.instance_variable_get(:@options)['force_create_process_api'])
            .to eq({force_create_process_api: true})
        end
      end
    
      describe 'Service' do
        let(:file_name) { Tempfile.new('iedriver').path }
        let(:root_directory) { Dir.mktmpdir }
    
        after do
          FileUtils.rm_f(file_name)
          FileUtils.remove_entry root_directory
        end
    
        it 'logs to file' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = file_name
    
          @driver = Selenium::WebDriver.for :ie, service: service
          expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
        end
    
        it 'logs to console' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = $stdout
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
        end
    
        it 'sets log level' do
          service = Selenium::WebDriver::Service.ie
          service.log = $stdout
    
          service.args << '-log-level=WARN'
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
        end
    
        it 'sets location for supporting files' do
          service = Selenium::WebDriver::Service.ie
    
          service.args << "–extract-path=#{root_directory}"
    
          @driver = Selenium::WebDriver.for :ie, service: service
        end
      end
    end
    
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().ignoreZoomSetting(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.ignoreZoomSettings()
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.introduceFlakinessByIgnoringSecurityDomains();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L58-L59)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.IntroduceInstabilityByIgnoringProtectedModeSettings = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ignore_protected_mode_settings = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L47)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true
    
    require 'spec_helper'
    
    RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
      describe 'Options' do
        let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
        let(:url) { 'https://www.selenium.dev/selenium/web/' }
    
        before do
          @options = Selenium::WebDriver::IE::Options.new
          @options.attach_to_edge_chrome = true
          @options.edge_executable_path = edge_location
        end
    
        it 'basic options Win10' do
          options = Selenium::WebDriver::IE::Options.new
          options.attach_to_edge_chrome = true
          options.edge_executable_path = edge_location
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'basic options Win11' do
          options = Selenium::WebDriver::Options.ie
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'sets the file upload dialog timeout' do
          @options.file_upload_dialog_timeout = 2000
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ensures a clean session' do
          @options.ensure_clean_session = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the zoom setting' do
          @options.ignore_zoom_level = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the protected mode settings' do
          @options.ignore_protected_mode_settings = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'adds the silent option' do
          @options.silent = true
          expect(@options.silent).to be_truthy
        end
    
        it 'sets the command line options' do
          @options.add_argument('-k')
          Selenium::WebDriver.for(:ie, options: @options)
        end
    
        it 'launches ie with the create process api' do
          @options.force_create_process_api = true
          Selenium::WebDriver.for(:ie, options: @options)
          expect(@options.instance_variable_get(:@options)['force_create_process_api'])
            .to eq({force_create_process_api: true})
        end
      end
    
      describe 'Service' do
        let(:file_name) { Tempfile.new('iedriver').path }
        let(:root_directory) { Dir.mktmpdir }
    
        after do
          FileUtils.rm_f(file_name)
          FileUtils.remove_entry root_directory
        end
    
        it 'logs to file' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = file_name
    
          @driver = Selenium::WebDriver.for :ie, service: service
          expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
        end
    
        it 'logs to console' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = $stdout
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
        end
    
        it 'sets log level' do
          service = Selenium::WebDriver::Service.ie
          service.log = $stdout
    
          service.args << '-log-level=WARN'
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
        end
    
        it 'sets location for supporting files' do
          service = Selenium::WebDriver::Service.ie
    
          service.args << "–extract-path=#{root_directory}"
    
          @driver = Selenium::WebDriver.for :ie, service: service
        end
      end
    end
    
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().introduceFlakinessByIgnoringProtectedModeSettings(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.introduceFlakinessByIgnoringSecurityDomains()
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.setCapability("silent", true);
WebDriver driver = new InternetExplorerDriver(options);
  
```

```py
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L68-L69)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
InternetExplorerOptions options = new InternetExplorerOptions();
options.AddAdditionalInternetExplorerOption("silent", true);
IWebDriver driver = new InternetExplorerDriver(options);
  
```

```rb
      @options.silent = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L53)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true
    
    require 'spec_helper'
    
    RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
      describe 'Options' do
        let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
        let(:url) { 'https://www.selenium.dev/selenium/web/' }
    
        before do
          @options = Selenium::WebDriver::IE::Options.new
          @options.attach_to_edge_chrome = true
          @options.edge_executable_path = edge_location
        end
    
        it 'basic options Win10' do
          options = Selenium::WebDriver::IE::Options.new
          options.attach_to_edge_chrome = true
          options.edge_executable_path = edge_location
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'basic options Win11' do
          options = Selenium::WebDriver::Options.ie
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'sets the file upload dialog timeout' do
          @options.file_upload_dialog_timeout = 2000
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ensures a clean session' do
          @options.ensure_clean_session = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the zoom setting' do
          @options.ignore_zoom_level = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the protected mode settings' do
          @options.ignore_protected_mode_settings = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'adds the silent option' do
          @options.silent = true
          expect(@options.silent).to be_truthy
        end
    
        it 'sets the command line options' do
          @options.add_argument('-k')
          Selenium::WebDriver.for(:ie, options: @options)
        end
    
        it 'launches ie with the create process api' do
          @options.force_create_process_api = true
          Selenium::WebDriver.for(:ie, options: @options)
          expect(@options.instance_variable_get(:@options)['force_create_process_api'])
            .to eq({force_create_process_api: true})
        end
      end
    
      describe 'Service' do
        let(:file_name) { Tempfile.new('iedriver').path }
        let(:root_directory) { Dir.mktmpdir }
    
        after do
          FileUtils.rm_f(file_name)
          FileUtils.remove_entry root_directory
        end
    
        it 'logs to file' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = file_name
    
          @driver = Selenium::WebDriver.for :ie, service: service
          expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
        end
    
        it 'logs to console' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = $stdout
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
        end
    
        it 'sets log level' do
          service = Selenium::WebDriver::Service.ie
          service.log = $stdout
    
          service.args << '-log-level=WARN'
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
        end
    
        it 'sets location for supporting files' do
          service = Selenium::WebDriver::Service.ie
    
          service.args << "–extract-path=#{root_directory}"
    
          @driver = Selenium::WebDriver.for :ie, service: service
        end
      end
    end
    
```

```javascript
const {Builder,By, Capabilities} = require('selenium-webdriver');
let caps = Capabilities.ie();
caps.set('silent', true);

(async function example() {
    let driver = await new Builder()
        .forBrowser('internet explorer')
        .withCapabilities(caps)
        .build();
    try {
        await driver.get('http://www.google.com/ncr');
    }
    finally {
        await driver.quit();
    }
})();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.setCapability("silent", true)
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  
```

```java
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;

public class ieTest {
    public static void main(String[] args) {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.useCreateProcessApiToLaunchIe();
        options.addCommandSwitches("-k");
        InternetExplorerDriver driver = new InternetExplorerDriver(options);
        try {
            driver.get("https://google.com/ncr");
            Capabilities caps = driver.getCapabilities();
            System.out.println(caps);
        } finally {
            driver.quit();
        }
    }
}
  
```

```py
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L76-L79)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;

namespace ieTest {
 class Program {
  static void Main(string[] args) {
   InternetExplorerOptions options = new InternetExplorerOptions();
   options.ForceCreateProcessApi = true;
   options.BrowserCommandLineArguments = "-k";
   IWebDriver driver = new InternetExplorerDriver(options);
   driver.Url = "https://google.com/ncr";
  }
 }
}
  
```

```rb
      @options.add_argument('-k')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L58)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true
    
    require 'spec_helper'
    
    RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
      describe 'Options' do
        let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
        let(:url) { 'https://www.selenium.dev/selenium/web/' }
    
        before do
          @options = Selenium::WebDriver::IE::Options.new
          @options.attach_to_edge_chrome = true
          @options.edge_executable_path = edge_location
        end
    
        it 'basic options Win10' do
          options = Selenium::WebDriver::IE::Options.new
          options.attach_to_edge_chrome = true
          options.edge_executable_path = edge_location
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'basic options Win11' do
          options = Selenium::WebDriver::Options.ie
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'sets the file upload dialog timeout' do
          @options.file_upload_dialog_timeout = 2000
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ensures a clean session' do
          @options.ensure_clean_session = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the zoom setting' do
          @options.ignore_zoom_level = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the protected mode settings' do
          @options.ignore_protected_mode_settings = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'adds the silent option' do
          @options.silent = true
          expect(@options.silent).to be_truthy
        end
    
        it 'sets the command line options' do
          @options.add_argument('-k')
          Selenium::WebDriver.for(:ie, options: @options)
        end
    
        it 'launches ie with the create process api' do
          @options.force_create_process_api = true
          Selenium::WebDriver.for(:ie, options: @options)
          expect(@options.instance_variable_get(:@options)['force_create_process_api'])
            .to eq({force_create_process_api: true})
        end
      end
    
      describe 'Service' do
        let(:file_name) { Tempfile.new('iedriver').path }
        let(:root_directory) { Dir.mktmpdir }
    
        after do
          FileUtils.rm_f(file_name)
          FileUtils.remove_entry root_directory
        end
    
        it 'logs to file' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = file_name
    
          @driver = Selenium::WebDriver.for :ie, service: service
          expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
        end
    
        it 'logs to console' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = $stdout
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
        end
    
        it 'sets log level' do
          service = Selenium::WebDriver::Service.ie
          service.log = $stdout
    
          service.args << '-log-level=WARN'
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
        end
    
        it 'sets location for supporting files' do
          service = Selenium::WebDriver::Service.ie
    
          service.args << "–extract-path=#{root_directory}"
    
          @driver = Selenium::WebDriver.for :ie, service: service
        end
      end
    end
    
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options();
options.addBrowserCommandSwitches('-k');
options.addBrowserCommandSwitches('-private');
options.forceCreateProcessApi(true);

driver = await env.builder()
          .setIeOptions(options)
          .build();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.useCreateProcessApiToLaunchIe()
    options.addCommandSwitches("-k")
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  
```

```java
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;

public class ieTest {
    public static void main(String[] args) {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.useCreateProcessApiToLaunchIe();
        InternetExplorerDriver driver = new InternetExplorerDriver(options);
        try {
            driver.get("https://google.com/ncr");
            Capabilities caps = driver.getCapabilities();
            System.out.println(caps);
        } finally {
            driver.quit();
        }
    }
}
  
```

```py
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L87-L90)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;

namespace ieTest {
 class Program {
  static void Main(string[] args) {
   InternetExplorerOptions options = new InternetExplorerOptions();
   options.ForceCreateProcessApi = true;
   IWebDriver driver = new InternetExplorerDriver(options);
   driver.Url = "https://google.com/ncr";
  }
 }
}
  
```

```rb
      @options.force_create_process_api = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L63)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true
    
    require 'spec_helper'
    
    RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
      describe 'Options' do
        let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
        let(:url) { 'https://www.selenium.dev/selenium/web/' }
    
        before do
          @options = Selenium::WebDriver::IE::Options.new
          @options.attach_to_edge_chrome = true
          @options.edge_executable_path = edge_location
        end
    
        it 'basic options Win10' do
          options = Selenium::WebDriver::IE::Options.new
          options.attach_to_edge_chrome = true
          options.edge_executable_path = edge_location
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'basic options Win11' do
          options = Selenium::WebDriver::Options.ie
          @driver = Selenium::WebDriver.for :ie, options: options
        end
    
        it 'sets the file upload dialog timeout' do
          @options.file_upload_dialog_timeout = 2000
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ensures a clean session' do
          @options.ensure_clean_session = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the zoom setting' do
          @options.ignore_zoom_level = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'ignores the protected mode settings' do
          @options.ignore_protected_mode_settings = true
          driver = Selenium::WebDriver.for(:ie, options: @options)
          driver.quit
        end
    
        it 'adds the silent option' do
          @options.silent = true
          expect(@options.silent).to be_truthy
        end
    
        it 'sets the command line options' do
          @options.add_argument('-k')
          Selenium::WebDriver.for(:ie, options: @options)
        end
    
        it 'launches ie with the create process api' do
          @options.force_create_process_api = true
          Selenium::WebDriver.for(:ie, options: @options)
          expect(@options.instance_variable_get(:@options)['force_create_process_api'])
            .to eq({force_create_process_api: true})
        end
      end
    
      describe 'Service' do
        let(:file_name) { Tempfile.new('iedriver').path }
        let(:root_directory) { Dir.mktmpdir }
    
        after do
          FileUtils.rm_f(file_name)
          FileUtils.remove_entry root_directory
        end
    
        it 'logs to file' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = file_name
    
          @driver = Selenium::WebDriver.for :ie, service: service
          expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
        end
    
        it 'logs to console' do
          service = Selenium::WebDriver::Service.ie
    
          service.log = $stdout
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
        end
    
        it 'sets log level' do
          service = Selenium::WebDriver::Service.ie
          service.log = $stdout
    
          service.args << '-log-level=WARN'
    
          expect {
            @driver = Selenium::WebDriver.for :ie, service: service
          }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
        end
    
        it 'sets location for supporting files' do
          service = Selenium::WebDriver::Service.ie
    
          service.args << "–extract-path=#{root_directory}"
    
          @driver = Selenium::WebDriver.for :ie, service: service
        end
      end
    end
    
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options();
options.forceCreateProcessApi(true);

driver = await env.builder()
          .setIeOptions(options)
          .build();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.useCreateProcessApiToLaunchIe()
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  
```

```java
                .withLogFile(getLogLocation())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L53)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY`\
Property value: String representing path to log file

```py
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L97-L99)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L82)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
                .withLogOutput(System.out)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L67)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L109-L111)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L91)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L82)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGLEVEL_PROPERTY`\
Property value: String representation of `InternetExplorerDriverLogLevel.DEBUG.toString()` enum

```py
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L121-L123)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            if (_tempPath == null || !File.Exists(_tempPath))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L85)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '-log-level=WARN'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L102)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
                .withExtractPath(getTempDirectory())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L94)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

\*\*Note\*\*: Java also allows setting log level by System Property:\ Property key: \`InternetExplorerDriverService.IE\_DRIVER\_EXTRACT\_PATH\_PROPERTY\`\ Property value: String representing path to supporting files directory

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L133-L135)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L98)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << "–extract-path=#{root_directory}"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L112)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

# 5 - Safari specific functionality

These are capabilities and features specific to Apple Safari browsers.

Unlike Chromium and Firefox drivers, the safaridriver is installed with the Operating System. To enable automation on Safari, run the following command from the terminal:

```shell
safaridriver --enable
```

```java
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#24-L25)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

```py
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L9-L10)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

```cs
            var options = new SafariOptions();
            driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/SafariTest.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/Browsers/SafariTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Safari;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("OSX")]
    public class SafariTest
    {
        private SafariDriver driver;

        [TestCleanup]
        public void QuitDriver()
        {
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new SafariOptions();
            driver = new SafariDriver(options);
        }
    }
}
```

```rb
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L8-L9)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

```js
    let driver = new Builder()
      .forBrowser(Browser.SAFARI)
      .setSafariOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/safariSpecificCap.spec.js#L8-L11)

##### /examples/javascript/test/browser/safariSpecificCap.spec.js

```js
const safari = require('selenium-webdriver/safari');
const {Browser, Builder} = require("selenium-webdriver");
const options = new safari.Options();
const process  =  require('node:process');

describe('Should be able to Test Command line arguments', function () {
  (process.platform === 'darwin' ? it : it.skip)('safari caps', async function () {
    let driver = new Builder()
      .forBrowser(Browser.SAFARI)
      .setSafariOptions(options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
  val options = SafariOptions()
  val driver = SafariDriver(options)
```

```java
                .withLogging(true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `SafariDriverService.SAFARI_DRIVER_LOGGING`\
Property value: `"true"` or `"false"`

[Selenium v4.26](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.26.0)

```py
    service = webdriver.SafariService(enable_logging=True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L17)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L20)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

```java
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#L39-L40)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

```py
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L25-L30)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L38-L39)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/browsers/internet_explorer/
----

# IE 特定功能

这些是 Microsoft Internet Explorer 浏览器特有的功能和特性.

自2022年6月起, Selenium 正式不再支持独立的 Internet Explorer. Internet Explorer 驱动程序仍支持在 “IE 兼容模式” 下运行 Microsoft Edge.

## 特别注意事项

IE 驱动程序是 Selenium 项目直接维护的唯一驱动程序. 虽然 32 位和 64 位版本的版本的二进制文件, 但有一些64位驱动程序的 [已知限制](//jimevansmusic.blogspot.co.uk/2014/09/screenshots-sendkeys-and-sixty-four.html). 因此, 建议使用 32 位驱动程序.

有关使用 Internet Explorer 的其他信息, 请参见 [IE 驱动程序服务器页面](https://www.selenium.dev/zh-cn/documentation/ie_driver_server/)

## 选项

在 Internet Explorer 兼容模式下启动 Microsoft Edge 浏览器, 并使用基本定义的选项, 看起来就像这样:

*
*
*
*
*
*

```java
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#38-L41)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

```py
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L11-L14)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L35-L38)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

```rb
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L17-L20)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

截至 Internet Explorer 驱动程序 v4.5.0:

* 如果系统中没有 IE（Windows 11 中的默认设置）, 则无需使用上述两个参数. 使用上述两个参数.IE 驱动程序将使用 Edge, 并自动对其进行定位.
* 如果系统上同时存在 IE 和 Edge, 则只需设置附加到 Edge、 IE 驱动程序将自动在系统中定位 Edge.

因此, 如果系统中没有 IE, 您只需要:

*
*
*
*
*
*

```java
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#46-L47)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

```py
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L21-L22)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L44-L45)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L24-L25)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
let driver = await new Builder()
.forBrowser('internet explorer')
.setIEOptions(options)
.build();
```

```kotlin
<p><a href=/documentation/about/contributing/#moving-examples>
<span class="selenium-badge-code" data-bs-toggle="tooltip" data-bs-placement="right"
      title="One or more of these examples need to be implemented in the examples directory; click for details in the contribution guide">Move Code</span></a></p>


val options = InternetExplorerOptions()
val driver = InternetExplorerDriver(options)
```

以下是几种具有不同功能的常见用例:

### fileUploadDialogTimeout

在某些环境中, 当打开文件上传对话框时, Internet Explorer可能会超时. IEDriver的默认超时为1000毫秒, 但您可以使用fileUploadDialogTimeout功能来增加超时时间.

*
*
*
*
*
*

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.waitForUploadDialogUpTo(Duration.ofSeconds(2));
WebDriver driver = new RemoteWebDriver(options); 
  
```

```py
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L28-L29)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.FileUploadDialogTimeout = TimeSpan.FromMilliseconds(2000);
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.file_upload_dialog_timeout = 2000
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L29)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().fileUploadDialogTimeout(2000);
let driver = await Builder()
          .setIeOptions(options)
          .build();  
  
```

```kotlin
val options = InternetExplorerOptions()
options.waitForUploadDialogUpTo(Duration.ofSeconds(2))
val driver = RemoteWebDriver(options)
  
```

### ensureCleanSession

设置为 `true`时, 此功能将清除InternetExplorer所有正在运行实例的 *缓存, 浏览器历史记录和Cookies* (包括手动启动或由驱动程序启动的实例) . 默认情况下, 此设置为 `false`.

使用此功能将导致启动浏览器时性能下降, 因为驱动程序将等待直到缓存清除后再启动IE浏览器.

此功能接受一个布尔值作为参数.

*
*
*
*
*
*

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.destructivelyEnsureCleanSession();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ensure_clean_session = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L38-L39)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.EnsureCleanSession = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ensure_clean_session = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L35)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().ensureCleanSession(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.destructivelyEnsureCleanSession()
val driver = RemoteWebDriver(options)
  
```

### ignoreZoomSetting

InternetExplorer驱动程序期望浏览器的缩放级别为100%, 否则驱动程序将可能抛出异常. 通过将 *ignoreZoomSetting* 设置为 *true*, 可以禁用此默认行为.

此功能接受一个布尔值作为参数.

*
*
*
*
*
*

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.ignoreZoomSettings();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L48-L49)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.IgnoreZoomLevel = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ignore_zoom_level = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L41)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().ignoreZoomSetting(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.ignoreZoomSettings()
val driver = RemoteWebDriver(options)
  
```

### ignoreProtectedModeSettings

启动新的IE会话时是否跳过 *保护模式* 检查.

如果未设置, 并且所有区域的 *保护模式* 设置都不同, 则驱动程序将可能引发异常.

如果将功能设置为 `true`, 则测试可能会变得不稳定, 无响应, 或者浏览器可能会挂起. 但是, 到目前为止, 这仍然是第二好的选择, 并且第一选择应该 *始终* 是手动实际设置每个区域的保护模式设置. 如果用户正在使用此属性, 则只会给予 “尽力而为” 的支持.

此功能接受一个布尔值作为参数.

*
*
*
*
*
*

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.introduceFlakinessByIgnoringSecurityDomains();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L58-L59)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.IntroduceInstabilityByIgnoringProtectedModeSettings = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ignore_protected_mode_settings = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L47)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().introduceFlakinessByIgnoringProtectedModeSettings(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.introduceFlakinessByIgnoringSecurityDomains()
val driver = RemoteWebDriver(options)
  
```

### silent

设置为 `true`时, 此功能将禁止IEDriverServer的诊断输出.

此功能接受一个布尔值作为参数.

*
*
*
*
*
*

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.setCapability("silent", true);
WebDriver driver = new InternetExplorerDriver(options);
  
```

```py
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L68-L69)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
InternetExplorerOptions options = new InternetExplorerOptions();
options.AddAdditionalInternetExplorerOption("silent", true);
IWebDriver driver = new InternetExplorerDriver(options);
  
```

```rb
      @options.silent = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L53)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const {Builder,By, Capabilities} = require('selenium-webdriver');
let caps = Capabilities.ie();
caps.set('silent', true);

(async function example() {
    let driver = await new Builder()
        .forBrowser('internet explorer')
        .withCapabilities(caps)
        .build();
    try {
        await driver.get('http://www.google.com/ncr');
    }
    finally {
        await driver.quit();
    }
})();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.setCapability("silent", true)
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  
```

### IE 命令行选项

Internet Explorer包含几个命令行选项, 使您可以进行故障排除和配置浏览器.

下面介绍了一些受支持的命令行选项

* *-private* : 用于在私有浏览模式下启动IE. 这适用于IE 8和更高版本.

* *-k* : 在kiosk模式下启动Internet Explorer. 浏览器在一个最大化的窗口中打开, 该窗口不显示地址栏, 导航按钮或状态栏.

* *-extoff* : 在无附加模式下启动IE. 此选项专门用于解决浏览器加载项问题. 在IE 7和更高版本中均可使用.

注意: **forceCreateProcessApi** 应该启用命令行参数才能正常工作.

*
*
*
*
*
*

```java
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;

public class ieTest {
    public static void main(String[] args) {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.useCreateProcessApiToLaunchIe();
        options.addCommandSwitches("-k");
        InternetExplorerDriver driver = new InternetExplorerDriver(options);
        try {
            driver.get("https://google.com/ncr");
            Capabilities caps = driver.getCapabilities();
            System.out.println(caps);
        } finally {
            driver.quit();
        }
    }
}
  
```

```py
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L76-L79)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;

namespace ieTest {
 class Program {
  static void Main(string[] args) {
   InternetExplorerOptions options = new InternetExplorerOptions();
   options.ForceCreateProcessApi = true;
   options.BrowserCommandLineArguments = "-k";
   IWebDriver driver = new InternetExplorerDriver(options);
   driver.Url = "https://google.com/ncr";
  }
 }
}
  
```

```rb
      @options.add_argument('-k')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L58)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options();
options.addBrowserCommandSwitches('-k');
options.addBrowserCommandSwitches('-private');
options.forceCreateProcessApi(true);

driver = await env.builder()
          .setIeOptions(options)
          .build();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.useCreateProcessApiToLaunchIe()
    options.addCommandSwitches("-k")
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  
```

### forceCreateProcessApi

强制使用CreateProcess API启动Internet Explorer. 默认值为false.

对于IE 8及更高版本, 此选项要求将 “TabProcGrowth” 注册表值设置为0.

*
*
*
*
*
*

```java
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;

public class ieTest {
    public static void main(String[] args) {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.useCreateProcessApiToLaunchIe();
        InternetExplorerDriver driver = new InternetExplorerDriver(options);
        try {
            driver.get("https://google.com/ncr");
            Capabilities caps = driver.getCapabilities();
            System.out.println(caps);
        } finally {
            driver.quit();
        }
    }
}
  
```

```py
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L87-L90)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;

namespace ieTest {
 class Program {
  static void Main(string[] args) {
   InternetExplorerOptions options = new InternetExplorerOptions();
   options.ForceCreateProcessApi = true;
   IWebDriver driver = new InternetExplorerDriver(options);
   driver.Url = "https://google.com/ncr";
  }
 }
}
  
```

```rb
      @options.force_create_process_api = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L63)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options();
options.forceCreateProcessApi(true);

driver = await env.builder()
          .setIeOptions(options)
          .build();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.useCreateProcessApiToLaunchIe()
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  
```

## 服务

[Service page](https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/service/) 描述了所有浏览器通用的服务设置.

### 日志输出

获取驱动程序日志有助于调试各种问题. 服务类可让您指示日志的去向. 除非用户指定了日志输出的位置, 否则日志输出将被忽略.

```java
                .withLogFile(getLogLocation())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L53)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY`\
Property value: String representing path to log file

```py
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L97-L99)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L82)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
                .withLogOutput(System.out)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L67)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L109-L111)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L91)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### 日志级别

有 6 种可用的日志级别:`FATAL`、`ERROR`、`WARN`、`INFO`、`DEBUG` 和 `TRACE` 如果指定了日志输出, 默认级别为`FATAL`.

*
*
*
*
*
*

```java
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L82)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGLEVEL_PROPERTY`\
Property value: String representation of `InternetExplorerDriverLogLevel.DEBUG.toString()` enum

```py
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L121-L123)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            if (_tempPath == null || !File.Exists(_tempPath))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L85)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '-log-level=WARN'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L102)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### 辅助文件路径

*
*
*
*
*
*

```java
                .withExtractPath(getTempDirectory())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L94)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

\*\*Note\*\*: Java also allows setting log level by System Property:\ Property key: \`InternetExplorerDriverService.IE\_DRIVER\_EXTRACT\_PATH\_PROPERTY\`\ Property value: String representing path to supporting files directory

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L133-L135)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L98)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << "–extract-path=#{root_directory}"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L112)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

----
url: https://www.selenium.dev/ja/documentation/grid/advanced_features/endpoints/
----

# Grid エンドポイント

## Grid

### Grid ステータス

Grid ステータスは Grid の現在の状態を提供します。 登録されている全てのノードの詳細で構成されます。 各ノードのステータスには、ノードの稼働状況、セッション、およびスロットに関する情報が含まれます。

```shell
curl --request GET 'http://localhost:4444/status'
```

### セッションの削除

セッションを削除すると、WebDriver セッションが終了し、ドライバがアクティブなセッションマップから削除されます。 削除されたセッション ID を使用するリクエストや、ドライバのインスタンスを再利用しようとすると、エラーとなります。

```shell
curl --request DELETE 'http://localhost:4444/session/<session-id>'
```

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret> '
```

完全分散モードでは、ディストリビューター URL は ディストリビューターのアドレスになります。

```shell
curl --request DELETE 'http://localhost:4444/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

Grid の設定時に登録用の secret を設定していない場合は次のようにします:

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/distributor/node/<node-id>' --header 'X-REGISTRATION-SECRET;'
```

### ノードのドレイン

ノードドレインコマンドはノードをグレースフルシャットダウンするために利用します。 ドレインは実行中のセッションがすべて完了した後にノードを停止します。 新規のセッションは受け付けません。

スタンドアロンモードでは、ディストリビューターの URL はスタンドアロンサーバーのアドレスとなります。

ハブ&ノードモードでは、ディストリビューターの URL は ハブのアドレスになります。

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret> '
```

完全分散モードでは、ディストリビューター URL は ディストリビューターのアドレスになります。

```shell
curl --request POST 'http://localhost:4444/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

Grid の設定時に登録用の secret を設定していない場合は次のようにします:

```shell
curl --request POST 'http://<Router-URL>/se/grid/distributor/node/<node-id>/drain' --header 'X-REGISTRATION-SECRET;'
```

## ノード

この節でのエンドポイントは、ハブ&ノードモードとノードが独立して動作する完全分散型 Grid モードに適用されます。 ノードが 1 つの場合、デフォルトのノード URL は http\://localhost:5555 です。 複数のノードがある場合は、[Grid ステータス](/ja/documentation/grid/advanced_features/endpoints/#grid-%e3%82%b9%e3%83%86%e3%83%bc%e3%82%bf%e3%82%b9) を使ってすべてのノードの詳細とノードアドレスを取得してください。

### ステータス

ノードステータスは基本的にノードのヘルスチェックのためのものです。 ディストリビューターは定期的にノードの状態を ping で取得し、それに応じて Grid モデルを更新します。 ステータスには稼働状況、セッション、およびスロットに関する情報が含まれます。

```shell
curl --request GET 'http://localhost:5555/status'
```

### ドレイン

ディストリビューターは [ドレイン](/ja/documentation/grid/advanced_features/endpoints/#%e3%83%8e%e3%83%bc%e3%83%89%e3%81%ae%e3%83%89%e3%83%ac%e3%82%a4%e3%83%b3)コマンドを適切なノードに渡します。 ノードを直接ドレインするには以下の curl コマンドを使います。 どちらのエンドポイントも有効であり、同じ結果になります。 ドレインは、ノードを停止する前に進行中のセッションを終了させます。

```shell
curl --request POST 'http://localhost:5555/se/grid/node/drain' --header 'X-REGISTRATION-SECRET: <secret>'
```

Grid の設定時に登録用の secret を設定していない場合は次のようにします:

```shell
curl --request POST 'http://<node-URL>/se/grid/node/drain' --header 'X-REGISTRATION-SECRET;'
```

### セッションオーナーのチェック

あるセッションがノードに属しているかどうかをチェックするには、以下の curl コマンドを使います。

```shell
curl --request GET 'http://localhost:5555/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

Grid の設定時に登録用の secret を設定していない場合は次のようにします:

```shell
curl --request GET 'http://<node-URL>/se/grid/node/owner/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

もしセッションがノードに属していたら true を返し、そうでなければ false が返ります。

### セッションの削除

セッションを削除すると、WebDriver セッションが終了し、ドライバがアクティブなセッションマップから削除されます。 削除されたセッション ID を使用するリクエストや、ドライバのインスタンスを再利用しようとすると、エラーとなります。

```shell
curl --request DELETE 'http://localhost:5555/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET: <secret>'
```

Grid の設定時に登録用の secret を設定していない場合は次のようにします:

```shell
curl --request DELETE 'http://<node-URL>/se/grid/node/session/<session-id>' --header 'X-REGISTRATION-SECRET;'
```

## 新規セッションキュー

### 新規セッションキューのクリア

新規セッションキューには、新規セッションリクエストが格納されます。 キューをクリアするには、以下に挙げる curl コマンドを使用します。 キューを消去すると、キューにあるすべてのリクエストを拒否します。 サーバーは各リクエストのそれぞれのクライアントにエラーレスポンスを返します。 クリアコマンドの結果は、削除されたリクエストの数です。

スタンドアロンモードでは、キューの URL はスタンドアロンサーバーのアドレスとなります。

ハブ&ノードモードでは、キューの URL は ハブのアドレスになります。

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

完全分散モードでは、キューの URL は 新規セッションキューのアドレスになります。

```shell
curl --request DELETE 'http://localhost:4444/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET: <secret>'
```

Grid の設定時に登録用の secret を設定していない場合は次のようにします:

```shell
curl --request DELETE 'http://<Router-URL>/se/grid/newsessionqueue/queue' --header 'X-REGISTRATION-SECRET;'
```

### 新規セッションリクエストの取得

新規セッションキューには、新規セッションリクエストが格納されます。 キューにある現在のリクエストを取得するには、以下に挙げる curl コマンドを使用します。 レスポンスはキュー内のリクエストの数とリクエストのペイロードを返します。

スタンドアロンモードでは、キューの URL はスタンドアロンサーバーのアドレスとなります。

ハブ&ノードモードでは、キューの URL は ハブのアドレスになります。

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

完全分散モードでは、キューの URL は 新規セッションキューのアドレスになります。

```shell
curl --request GET 'http://localhost:4444/se/grid/newsessionqueue/queue'
```

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/actions_api/wheel/
----

```java
        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L17-L20)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L11-L14)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L11-L14)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L16-L19)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L18-L21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L29-L33)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L22-L26)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L31-L35)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L22-L26)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L26-L31)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L30-L34)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L42-L46)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L35-L39)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L46-L53)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L34-L38)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L40-L44)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L43-L47)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L57-L61)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L50-L54)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L66-L75)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L57-L61)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L62-L66)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L59-L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L73-L76)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L66-L70)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L89-L97)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L63-L66)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L75-L77)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L75-L78)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

----
url: https://www.selenium.dev/ja/_print/documentation/webdriver/troubleshooting/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/webdriver/troubleshooting/).

# トラブルシューティングの支援

WebDriverの問題を管理する方法。

* 1: [Understanding Common Errors](#pg-e336429f0e9062797bc400580671e0b2)
* * 1.1: [Unable to Locate Driver Error](#pg-7dc6ce7850b813d8da2361fdcd2b0480)
  2: [Logging Selenium commands](#pg-e867b1aef80f7e8f0374136051c16718)
* 3: [Selenium4にアップグレードする方法](#pg-0e5117655421cde643531393b73e64d1)

It is not always obvious the root cause of errors in Selenium.

1. The most common Selenium-related error is a result of poor synchronization. Read about [Waiting Strategies](https://www.selenium.dev/ja/documentation/webdriver/waits/). If you aren’t sure if it is a synchronization strategy you can try *temporarily* hard coding a large sleep where you see the issue, and you’ll know if adding an explicit wait can help.

2. Note that many errors that get reported to the project are actually caused by issues in the underlying drivers that Selenium sends the commands to. You can rule out a driver problem by executing the command in multiple [browsers](https://www.selenium.dev/ja/documentation/webdriver/browsers/).

3. If you have questions about how to do things, check out the [Support options](/support/) for ways get assistance.

4. If you think you’ve found a problem with Selenium code, go ahead and file a [Bug Report](https://github.com/SeleniumHQ/selenium/issues/new?assignees=\&labels=I-defect%2Cneeds-triaging\&template=bug-report.yml\&title=%5B%F0%9F%90%9B+Bug%5D%3A+) on GitHub.

# 1 - Understanding Common Errors

# 1.1 - Unable to Locate Driver Error

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.bash_profile
source ~/.bash_profile
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Terminal and execute:

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.zshenv
source ~/.zshenv
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Command Prompt and execute:

```shell
echo %PATH%
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
setx PATH "%PATH%;C:\WebDriver\bin"
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver.exe --version
```

| ブラウザー             | サポートするOS                    | 維持管理機関           | ダウンロード                                                                       | イシュートラッカー                                                        |
| ----------------- | --------------------------- | ---------------- | ---------------------------------------------------------------------------- | ---------------------------------------------------------------- |
| Chromium/Chrome   | Windows/macOS/Linux         | Google           | [Downloads](//chromedriver.chromium.org/downloads)                           | [Issues](//bugs.chromium.org/p/chromedriver/issues/list)         |
| Firefox           | Windows/macOS/Linux         | Mozilla          | [Downloads](//github.com/mozilla/geckodriver/releases)                       | [Issues](//github.com/mozilla/geckodriver/issues)                |
| Edge              | Windows/macOS/Linux         | Microsoft        | [Downloads](//developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/) | [Issues](https://github.com/MicrosoftDocs/edge-developer/issues) |
| Internet Explorer | Windows                     | Selenium Project | [Downloads](/downloads)                                                      | [Issues](//github.com/SeleniumHQ/selenium/labels/D-IE)           |
| Safari            | macOS High Sierra and newer | Apple            | Built in                                                                     | [Issues](//bugreport.apple.com/logon)                            |

```java
    public void logging() throws IOException {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Java Logging is not exactly straightforward, and if you are just looking for an easy way to look at the important Selenium logs, take a look at the [Selenium Logger project](https://github.com/titusfortner/selenium-logger#selenium-logger)

Python logs are typically created per module. You can match all submodules by referencing the top level module. So to work with all loggers in selenium module, you can do this:

```py
    logger = logging.getLogger('selenium')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L5)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

You must also create and add a log handler (`StreamHandler`, `FileHandler`, etc).

To save logs to a file, you can do this:

```py
log_path = '/path/to/log'
handler = logging.FileHandler(log_path)
logger.addHandler(handler)
```

To display logs in the console, you can do this:

```py
handler = logging.StreamHandler()
logger.addHandler(handler)
```

.NET logger is managed with a static class, so all access to logging is managed simply by referencing `Log` from the `OpenQA.Selenium.Internal.Logging` namespace.

If you want to see as much debugging as possible in all the classes, you can turn on debugging globally in Ruby by setting `$DEBUG = true`.

For more fine-tuned control, Ruby Selenium created its own Logger class to wrap the default `Logger` class. This implementation provides some interesting additional features. Obtain the logger directly from the `#logger`class method on the `Selenium::WebDriver` module:

```rb
    logger = Selenium::WebDriver.logger
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L11)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

```javascript
const logging = require('selenium-webdriver/lib/logging')
logger = logging.getLogger('webdriver')
```

```java
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L32-L35)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Python has 6 logger levels: `CRITICAL`, `ERROR`, `WARNING`, `INFO`, `DEBUG`, and `NOTSET`. The default is `WARNING`

To change the level of the logger:

```py
    logger.setLevel(logging.DEBUG)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L7)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

Things get complicated when you use PyTest, though. By default, PyTest hides logging unless the test fails. You need to set 3 things to get PyTest to display logs on passing tests.

To always output logs with PyTest you need to run with additional arguments. First, `-s` to prevent PyTest from capturing the console. Second, `-p no:logging`, which allows you to override the default PyTest logging settings so logs can be displayed regardless of errors.

So you need to set these flags in your IDE, or run PyTest on command line like:

```bash
pytest -s -p no:logging
```

Finally, since you turned off logging in the arguments above, you now need to add configuration to turn it back on:

```py
logging.basicConfig(level=logging.WARN)
```

.NET has 6 logger levels: `Error`, `Warn`, `Info`, `Debug`, `Trace` and `None`. The default level is `Warn`.

To change the level of the logger:

```cs
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L18)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

Ruby logger has 5 logger levels: `:debug`, `:info`, `:warn`, `:error`, `:fatal`. As of Selenium v4.9.1, The default is `:info`.

To change the level of the logger:

```rb
    logger.level = :debug
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L13)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

JavaScript has 9 logger levels: `OFF`, `SEVERE`, `WARNING`, `INFO`, `DEBUG`, `FINE`, `FINER`, `FINEST`, `ALL`. The default is `OFF`.

To change the level of the logger:

```javascript
logger.setLevel(logging.Level.INFO)
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
WARNING: this is a warning
```

Python logs actionable content at logger level — `WARNING` Details about deprecations are logged at this level.

Example:

```text
WARNING  selenium:test_logging.py:23 this is a warning
```

.NET logs actionable content at logger level `Warn`.

Example:

```text
11:04:40.986 WARN LoggingTest: this is a warning
```

Ruby logs actionable content at logger level — `:warn`. Details about deprecations are logged at this level.

For example:

```text
2023-05-08 20:53:13 WARN Selenium [:example_id] this is a warning 
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
INFO: this is useful information
```

Python logs useful information at logger level — `INFO`

Example:

```text
INFO     selenium:test_logging.py:22 this is useful information
```

.NET logs useful information at logger level `Info`.

Example:

```text
11:04:40.986 INFO LoggingTest: this is useful information
```

Ruby logs useful information at logger level — `:info`.

Example:

```text
2023-05-08 20:53:13 INFO Selenium [:example_id] this is useful information 
```

```text
May 08, 2023 9:23:38 PM dev.selenium.troubleshooting.LoggingTest logging
FINE: this is detailed debug information
```

Python logs debugging details at logger level — `DEBUG`

Example:

```text
DEBUG    selenium:test_logging.py:24 this is detailed debug information
```

.NET logs most debug content at logger level `Debug`.

Example:

```text
11:04:40.986 DEBUG LoggingTest: this is detailed debug information
```

Ruby only provides one level for debugging, so all details are at logger level — `:debug`.

Example:

```text
2023-05-08 20:53:13 DEBUG Selenium [:example_id] this is detailed debug information 
```

```java

      Path output = artifactsDir().resolve("selenium.xml");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L37-L38)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

By default all logs are sent to `sys.stderr`. To direct output somewhere else, you need to add a handler with either a `StreamHandler` or a `FileHandler`:

```py
    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L9-L10)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

By default all logs are sent to `System.Console.Error` output. To direct output somewhere else, you need to add a handler with a `FileLogHandler`:

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L20)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

By default, logs are sent to the console in `stdout`.\
To store the logs in a file:

```rb
    logger.output = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L15)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

JavaScript does not currently support sending output to a file.

To send logs to console output:

```javascript
logging.installConsoleHandler()
```

```java
        logger.addHandler(handler);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java#L40-L41)

##### /examples/java/src/test/java/dev/selenium/troubleshooting/LoggingTest.java

```java
package dev.selenium.troubleshooting;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
import java.util.logging.FileHandler;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.Logger;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.manager.SeleniumManager;
import org.openqa.selenium.remote.RemoteWebDriver;

public class LoggingTest extends BaseTest {

    @AfterEach
    public void loggingOff() {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.INFO);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.INFO);
        });
    }

    @Test
    public void logging() throws IOException {
        Logger logger = Logger.getLogger("");
        logger.setLevel(Level.FINE);
        Arrays.stream(logger.getHandlers()).forEach(handler -> {
            handler.setLevel(Level.FINE);
        });

      Path output = artifactsDir().resolve("selenium.xml");
      Handler handler = new FileHandler(output.toString());
        logger.addHandler(handler);

        Logger.getLogger(RemoteWebDriver.class.getName()).setLevel(Level.FINEST);
        Logger.getLogger(SeleniumManager.class.getName()).setLevel(Level.SEVERE);

        Logger localLogger = Logger.getLogger(this.getClass().getName());
        localLogger.warning("this is a warning");
        localLogger.info("this is useful information");
        localLogger.fine("this is detailed debug information");

        byte[] bytes = Files.readAllBytes(output);
        String fileContent = new String(bytes);

        Assertions.assertTrue(fileContent.contains("this is a warning"));
        Assertions.assertTrue(fileContent.contains("this is useful information"));
        Assertions.assertTrue(fileContent.contains("this is detailed debug information"));
    }
}
```

Because logging is managed by module, instead of working with just "selenium", you can specify different levels for different modules:

```py
    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/troubleshooting/test_logging.py#L12-L13)

##### /examples/python/tests/troubleshooting/test\_logging.py

```py
import logging


def test_logging(log_path):
    logger = logging.getLogger('selenium')

    logger.setLevel(logging.DEBUG)

    handler = logging.FileHandler(log_path)
    logger.addHandler(handler)

    logging.getLogger('selenium.webdriver.remote').setLevel(logging.WARN)
    logging.getLogger('selenium.webdriver.common').setLevel(logging.DEBUG)

    logger.info("this is useful information")
    logger.warning("this is a warning")
    logger.debug("this is detailed debug information")

    with open(log_path, 'r') as fp:
        assert len(fp.readlines()) == 3
```

.NET logging is managed on a per class level, set the level you want to use on a per-class basis:

```cs

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/Troubleshooting/LoggingTest.cs

```cs
﻿using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Internal.Logging;
using OpenQA.Selenium.Manager;
using OpenQA.Selenium.Remote;
using System;
using System.IO;

namespace SeleniumDocs.Troubleshooting
{
    [TestClass]
    public class LoggingTest
    {
        private const string filePath = "Selenium.log";

        [TestMethod]
        public void Logging()
        {
            Log.SetLevel(LogEventLevel.Trace);

            Log.Handlers.Add(new FileLogHandler(filePath));

            Log.SetLevel(typeof(RemoteWebDriver), LogEventLevel.Debug);
            Log.SetLevel(typeof(SeleniumManager), LogEventLevel.Info);

            Warn("this is a warning");
            Info("this is useful information");
            Debug("this is detailed debug information");

            using (var fileStream = File.Open(filePath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                using (var streamReader = new StreamReader(fileStream))
                {
                    var fileLogContent = streamReader.ReadToEnd();

                    StringAssert.Contains(fileLogContent, "this is a warning");
                    StringAssert.Contains(fileLogContent, "this is useful information");
                    StringAssert.Contains(fileLogContent, "this is detailed debug information");
                }
            }
        }

        [TestCleanup]
        public void TestCleanup()
        {
            // reset log to default
            Log.SetLevel(LogEventLevel.Info)
                .Handlers.Clear()
                .Handlers.Add(new TextWriterHandler(Console.Error));
        }

        // logging is only for internal usage
        // hacking it via reflection

        private void Debug(string message)
        {
            LogMessage("Debug", message);
        }

        private void Warn(string message)
        {
            LogMessage("Warn", message);
        }

        private void Info(string message)
        {
            LogMessage("Info", message);
        }

        private void LogMessage(string methodName, string message)
        {
            var getLoggerMethod = typeof(Log).GetMethod("GetLogger", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.NonPublic, new Type[] { typeof(Type) });

            var logger = getLoggerMethod.Invoke(null, new object[] { typeof(LoggingTest) });

            var emitMethod = logger.GetType().GetMethod(methodName);

            emitMethod.Invoke(logger, new object[] { message });
        }
    }
}
```

Ruby’s logger allows you to opt in (“allow”) or opt out (“ignore”) of log messages based on their IDs. Everything that Selenium logs includes an ID. You can also turn on or off all deprecation notices by using `:deprecations`.

These methods accept one or more symbols or an array of symbols:

```rb
    logger.ignore(:jwp_caps, :logger_info)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L17)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

or

```rb
    logger.allow(%i[selenium_manager example_id])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/troubleshooting/logging_spec.rb#L18)

##### /examples/ruby/spec/troubleshooting/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:file_name) { Tempfile.new('logging').path }

  after { FileUtils.rm_f(file_name) }

  it 'logs things' do
    logger = Selenium::WebDriver.logger

    logger.level = :debug

    logger.output = file_name

    logger.ignore(:jwp_caps, :logger_info)
    logger.allow(%i[selenium_manager example_id])

    logger.warn('this is a warning', id: :example_id)
    logger.info('this is useful information', id: :example_id)
    logger.debug('this is detailed debug information', id: :example_id)

    expect(File.readlines(file_name).grep(/\[:example_id\]/).size).to eq 3
  end
end
```

# 3 - Selenium4にアップグレードする方法

```java
DesiredCapabilities caps = DesiredCapabilities.firefox();
caps.setCapability("platform", "Windows 10");
caps.setCapability("version", "92");
caps.setCapability("build", myTestBuild);
caps.setCapability("name", myTestName);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), caps);
```

```javascript
caps = {};
caps['browserName'] = 'Firefox';
caps['platform'] = 'Windows 10';
caps['version'] = '92';
caps['build'] = myTestBuild;
caps['name'] = myTestName;
```

```csharp
DesiredCapabilities caps = new DesiredCapabilities();
caps.SetCapability("browserName", "firefox");
caps.SetCapability("platform", "Windows 10");
caps.SetCapability("version", "92");
caps.SetCapability("build", myTestBuild);
caps.SetCapability("name", myTestName);
var driver = new RemoteWebDriver(new Uri(CloudURL), caps);
```

```rb
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L123-L130)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```python
caps = {}
caps['browserName'] = 'firefox'
caps['platform'] = 'Windows 10'
caps['version'] = '92'
caps['build'] = my_test_build
caps['name'] = my_test_name
driver = webdriver.Remote(cloud_url, desired_capabilities=caps)
```

```java
FirefoxOptions browserOptions = new FirefoxOptions();
browserOptions.setPlatformName("Windows 10");
browserOptions.setBrowserVersion("92");
Map<String, Object> cloudOptions = new HashMap<>();
cloudOptions.put("build", myTestBuild);
cloudOptions.put("name", myTestName);
browserOptions.setCapability("cloud:options", cloudOptions);
WebDriver driver = new RemoteWebDriver(new URL(cloudUrl), browserOptions);
```

```javascript
capabilities = {
  browserName: 'firefox',
  browserVersion: '92',
  platformName: 'Windows 10',
  'cloud:options': {
     build: myTestBuild,
     name: myTestName,
  }
}
```

```csharp
var browserOptions = new FirefoxOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "92";
var cloudOptions = new Dictionary<string, object>();
cloudOptions.Add("build", myTestBuild);
cloudOptions.Add("name", myTestName);
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);
var driver = new RemoteWebDriver(new Uri(CloudURL), browserOptions);
```

```rb
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L38-L47)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```python
from selenium.webdriver.firefox.options import Options as FirefoxOptions
options = FirefoxOptions()
options.browser_version = '92'
options.platform_name = 'Windows 10'
cloud_options = {}
cloud_options['build'] = my_test_build
cloud_options['name'] = my_test_name
options.set_capability('cloud:options', cloud_options)
driver = webdriver.Remote(cloud_url, options=options)
```

### Javaで要素ユーティリティメソッドを検索する

Javaバインディング（`FindsBy` インターフェイス）の要素を検索するユーティリティメソッドは、内部使用のみを目的としていたため、削除されました。 次のコードサンプルは、これを分かりやすく説明しています。

`findElement *` で単一の要素を検索する。

Before

```java

driver.findElementByClassName("className");
driver.findElementByCssSelector(".className");
driver.findElementById("elementId");
driver.findElementByLinkText("linkText");
driver.findElementByName("elementName");
driver.findElementByPartialLinkText("partialText");
driver.findElementByTagName("elementTagName");
driver.findElementByXPath("xPath");
```

After

```java

driver.findElement(By.className("className"));
driver.findElement(By.cssSelector(".className"));
driver.findElement(By.id("elementId"));
driver.findElement(By.linkText("linkText"));
driver.findElement(By.name("elementName"));
driver.findElement(By.partialLinkText("partialText"));
driver.findElement(By.tagName("elementTagName"));
driver.findElement(By.xpath("xPath"));
```

`findElements *` で複数の要素を検索する。

Before

```java

driver.findElementsByClassName("className");
driver.findElementsByCssSelector(".className");
driver.findElementsById("elementId");
driver.findElementsByLinkText("linkText");
driver.findElementsByName("elementName");
driver.findElementsByPartialLinkText("partialText");
driver.findElementsByTagName("elementTagName");
driver.findElementsByXPath("xPath");
```

After

```java

driver.findElements(By.className("className"));
driver.findElements(By.cssSelector(".className"));
driver.findElements(By.id("elementId"));
driver.findElements(By.linkText("linkText"));
driver.findElements(By.name("elementName"));
driver.findElements(By.partialLinkText("partialText"));
driver.findElements(By.tagName("elementTagName"));
driver.findElements(By.xpath("xPath"));
```

## 依存関係のアップグレード

以下のサブセクションを確認してSelenium4をインストールし、プロジェクトの依存関係をアップグレードしてください。

### Java

Seleniumをアップグレードするプロセスは、使用されているビルドツールによって異なります。 Javaで最も一般的なものである[Maven](https://maven.apache.org/)と[Gradle](https://gradle.org/)について説明します。 必要なJavaの最小バージョンはまだ8です。

#### Maven

Before

```xml

<dependencies>
  <!-- more dependencies ... -->
  <dependency>
    <groupId>org.seleniumhq.selenium</groupId>
    <artifactId>selenium-java</artifactId>
    <version>3.141.59</version>
  </dependency>
  <!-- more dependencies ... -->
</dependencies>
```

After

```xml

<dependencies>
    <!-- more dependencies ... -->
    <dependency>
        <groupId>org.seleniumhq.selenium</groupId>
        <artifactId>selenium-java</artifactId>
        <version>4.4.0</version>
    </dependency>
    <!-- more dependencies ... -->
</dependencies>
```

変更を加えた後、`pom.xml` ファイルと同じディレクトリで `mvn clean compile` を実行できます。

#### Gradle

Before

```jsonpath

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '3.141.59'
}
test {
    useJUnitPlatform()
}
```

After

```jsonpath

plugins {
    id 'java'
}
group 'org.example'
version '1.0-SNAPSHOT'
repositories {
    mavenCentral()
}
dependencies {
    testImplementation 'org.junit.jupiter:junit-jupiter-api:5.7.0'
    testRuntimeOnly 'org.junit.jupiter:junit-jupiter-engine:5.7.0'
    implementation group: 'org.seleniumhq.selenium', name: 'selenium-java', version: '4.4.0'
}
test {
    useJUnitPlatform()
}
```

変更を加えた後、 `build.gradle` ファイルと同じディレクトリで `./gradlew cleanbuild` を実行できます。

すべてのJavaリリースを確認するには、 [MVNRepository](https://mvnrepository.com/artifact/org.seleniumhq.selenium/selenium-java) にアクセスしてください。

### C\#

C#でSelenium4の更新を取得する場所は [NuGet](https://www.nuget.org/) です。 [`Selenium.WebDriver`](https://www.nuget.org/packages/Selenium.WebDriver/4.4.0) パッケージの下で、最新バージョンに更新するための手順を入手できます。 Visual Studio内では、NuGetパッケージマネージャーを使用して次の操作を実行できます。

```shell
PM> Install-Package Selenium.WebDriver -Version 4.4.0
```

### Python

Pythonを使用するための最も重要な変更は、最低限必要なバージョンです。 Selenium 4には、Python3.7以降が必要です。 詳細については、[Python Package Index](https://pypi.org/project/selenium/4.4.3/)を参照してください。 コマンドラインからアップグレードするには、次のコマンドを実行できます。

```shell
pip install selenium==4.4.3
```

### Ruby

Selenium 4の更新の詳細は、RubyGemsの[selenium-webdriver](https://rubygems.org/gems/selenium-webdriver/versions/4.4.0)で確認できます。 最新バージョンをインストールするには、次のコマンドを実行できます。

```shell
gem install selenium-webdriver
```

Gemfileには下記のように追加します。

```shell
gem 'selenium-webdriver', '~> 4.4.0'
```

### JavaScript

selenium-webdriverパッケージは、Nodeパッケージマネージャーの[npmjs](https://www.npmjs.com)にあります。 Selenium4は[here](https://www.npmjs.com/package/selenium-webdriver/v/4.4.0)にあります。 これをインストールするには、次のいずれかを実行します。

```shell
npm install selenium-webdriver
```

または、package.jsonを更新して、 `npm install` を実行します。

```json
{
  "name": "selenium-tests",
  "version": "1.0.0",
  "dependencies": {
    "selenium-webdriver": "^4.4.0"
  }
}
```

## 潜在的なエラーと非推奨メッセージ

これは、Selenium4にアップグレードした後に発生する可能性のある非推奨メッセージを克服するのに役立つ一連のコード例です。

### Java

#### 待機とタイムアウト

タイムアウトで受信するパラメーターは、期待値 `(long time, TimeUnit unit)` から期待値 `(Duration duration)` に替わりました。

Before

```java

driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(2, TimeUnit.MINUTES);
driver.manage().timeouts().pageLoadTimeout(10, TimeUnit.SECONDS);
```

After

```java

driver.manage().timeouts().implicitlyWait(Duration.ofSeconds(10));
driver.manage().timeouts().scriptTimeout(Duration.ofMinutes(2));
driver.manage().timeouts().pageLoadTimeout(Duration.ofSeconds(10));
```

現在、待機も異なるパラメーターを期待しています。 `WebDriverWait`は、秒とミリ秒単位のタイムアウトに、 `long` ではなく`Duration`を期待するようになりました。 `FluentWait` の `withTimeout` および `pollingEvery` ユーティリティメソッドは、期待値 `(long time, TimeUnit unit)` から `(Duration duration)` に替わりました。

Before

```java

new WebDriverWait(driver, 3)
.until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(30, TimeUnit.SECONDS)
  .pollingEvery(5, TimeUnit.SECONDS)
  .ignoring(NoSuchElementException.class);
```

After

```java

new WebDriverWait(driver, Duration.ofSeconds(3))
  .until(ExpectedConditions.elementToBeClickable(By.cssSelector("#id")));

  Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
  .withTimeout(Duration.ofSeconds(30))
  .pollingEvery(Duration.ofSeconds(5))
  .ignoring(NoSuchElementException.class);
```

#### マージCapabilitiesは、もはや呼び出し元のオブジェクトを変更しなくなりました

以前は、別のCapabilitiesセットを別のセットにマージすることが可能であり、呼び出し元のオブジェクトを変更していました。 今は、ここで、マージ操作の結果を割り当てる必要があります。

Before

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options.merge(capabilities);
As a result, the `options` object was getting modified.
```

After

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("platformVersion", "Windows 10");
FirefoxOptions options = new FirefoxOptions();
options.setHeadless(true);
options = options.merge(capabilities);
The result of the `merge` call needs to be assigned to an object.
```

#### 古いFirefox

GeckoDriverが登場する前は、SeleniumプロジェクトにはFirefoxを自動化するためのドライバー実装がありました（バージョン<48）。 ただし、この実装は最近のバージョンのFirefoxでは機能しないため、もう必要ありません。 Selenium 4にアップグレードする際の大きな問題を回避するために、`setLegacy` オプションは非推奨として表示されます。 古い実装の使用をやめ、GeckoDriverのみに依存することをお勧めします。 次のコードは、アップグレード後に非推奨になった`setLegacy` 行を示しています。

```java
FirefoxOptions options = new FirefoxOptions();
options.setLegacy(true);
```

#### `BrowserType`

`BrowserType` インターフェースは長い間使用されてきましたが、新しい `Browser` インターフェースを優先して非推奨になります。

Before

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", BrowserType.FIREFOX);
```

After

```java

MutableCapabilities capabilities = new MutableCapabilities();
capabilities.setCapability("browserVersion", "92");
capabilities.setCapability("browserName", Browser.FIREFOX);
```

### C\#

#### `AddAdditionalCapability` は非推奨になりました

その代わりに、 `AddAdditionalOption` をお勧めします。 これを示す例を次に示します。

Before

```cs

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalCapability("cloud:options", cloudOptions, true);
```

After

```cs

var browserOptions = new ChromeOptions();
browserOptions.PlatformName = "Windows 10";
browserOptions.BrowserVersion = "latest";
var cloudOptions = new Dictionary<string, object>();
browserOptions.AddAdditionalOption("cloud:options", cloudOptions);
```

### Python

#### `execute_pathは非推奨になりました。Serviceオブジェクトを渡してください`

Selenium 4では、非推奨の警告を防ぐために、Serviceオブジェクトからドライバーの `executable_path` を設定する必要があります。 （または、PATHを設定せず、代わりに必要なドライバーがシステムPATH上にあることを確認してください。）

Before

```python

from selenium import webdriver
options = webdriver.ChromeOptions()
driver = webdriver.Chrome(
    executable_path=CHROMEDRIVER_PATH, 
    options=options
)
```

After

```python

from selenium import webdriver
from selenium.webdriver.chrome.service import Service as ChromeService
options = webdriver.ChromeOptions()
service = ChromeService(executable_path=CHROMEDRIVER_PATH)
driver = webdriver.Chrome(service=service, options=options)
```

## まとめ

Selenium 4にアップグレードする際に考慮すべき主な変更点を確認しました。 アップグレードのためにテストコードを準備する際にカバーするさまざまな側面について説明します。 これには、新しいバージョンのSeleniumを使用する時に発生する可能性のある潜在的な問題を防ぐ方法の提案も含まれます。 最後に、アップグレード後に発生する可能性のある一連の問題についても説明し、それらの問題に対する潜在的な修正を共有しました。

*これは元々は <https://saucelabs.com/resources/articles/how-to-upgrade-to-selenium-4> に投稿されました*

----
url: https://www.selenium.dev/documentation/test_practices/overview/
----

# Overview of Test Automation

```java
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
User user = UserFactory.createCommonUser(); //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
AccountPage accountPage = loginAs(user.getEmail(), user.getPassword());
  
```

```python
# Create a user who has read-only permissions--they can configure a unicorn,
# but they do not have payment information set up, nor do they have
# administrative privileges. At the time the user is created, its email
# address and password are randomly generated--you don't even need to
# know them.
user = user_factory.create_common_user() #This method is defined elsewhere.

# Log in as this user.
# Logging in on this site takes you to your personal "My Account" page, so the
# AccountPage object is returned by the loginAs method, allowing you to then
# perform actions from the AccountPage.
account_page = login_as(user.get_email(), user.get_password())
  
```

```csharp
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
User user = UserFactory.CreateCommonUser(); //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
AccountPage accountPage = LoginAs(user.Email, user.Password);
  
```

```ruby
# Create a user who has read-only permissions--they can configure a unicorn,
# but they do not have payment information set up, nor do they have
# administrative privileges. At the time the user is created, its email
# address and password are randomly generated--you don't even need to
# know them.
user = UserFactory.create_common_user #This method is defined elsewhere.

# Log in as this user.
# Logging in on this site takes you to your personal "My Account" page, so the
# AccountPage object is returned by the loginAs method, allowing you to then
# perform actions from the AccountPage.
account_page = login_as(user.email, user.password)
  
```

```javascript
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
var user = userFactory.createCommonUser(); //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
var accountPage = loginAs(user.email, user.password);
  
```

```kotlin
// Create a user who has read-only permissions--they can configure a unicorn,
// but they do not have payment information set up, nor do they have
// administrative privileges. At the time the user is created, its email
// address and password are randomly generated--you don't even need to
// know them.
val user = UserFactory.createCommonUser() //This method is defined elsewhere.

// Log in as this user.
// Logging in on this site takes you to your personal "My Account" page, so the
// AccountPage object is returned by the loginAs method, allowing you to then
// perform actions from the AccountPage.
val accountPage = loginAs(user.getEmail(), user.getPassword())
  
```

```java
// The Unicorn is a top-level Object--it has attributes, which are set here. 
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
Unicorn sparkles = new Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS);

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.
AddUnicornPage addUnicornPage = accountPage.addUnicorn();

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
UnicornConfirmationPage unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles);
  
```

```python
# The Unicorn is a top-level Object--it has attributes, which are set here.
# This only stores the values; it does not fill out any web forms or interact
# with the browser in any way.
sparkles = Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

# Since we're already "on" the account page, we have to use it to get to the
# actual place where you configure unicorns. Calling the "Add Unicorn" method
# takes us there.
add_unicorn_page = account_page.add_unicorn()

# Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
# its createUnicorn() method. This method will take Sparkles' attributes,
# fill out the form, and click submit.
unicorn_confirmation_page = add_unicorn_page.create_unicorn(sparkles)
  
```

```csharp
// The Unicorn is a top-level Object--it has attributes, which are set here. 
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
Unicorn sparkles = new Unicorn("Sparkles", UnicornColors.Purple, UnicornAccessories.Sunglasses, UnicornAdornments.StarTattoos);

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.
AddUnicornPage addUnicornPage = accountPage.AddUnicorn();

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
UnicornConfirmationPage unicornConfirmationPage = addUnicornPage.CreateUnicorn(sparkles);
  
```

```ruby
# The Unicorn is a top-level Object--it has attributes, which are set here.
# This only stores the values; it does not fill out any web forms or interact
# with the browser in any way.
sparkles = Unicorn.new('Sparkles', UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

# Since we're already "on" the account page, we have to use it to get to the
# actual place where you configure unicorns. Calling the "Add Unicorn" method
# takes us there.
add_unicorn_page = account_page.add_unicorn

# Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
# its createUnicorn() method. This method will take Sparkles' attributes,
# fill out the form, and click submit.
unicorn_confirmation_page = add_unicorn_page.create_unicorn(sparkles)
  
```

```javascript
// The Unicorn is a top-level Object--it has attributes, which are set here.
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
var sparkles = new Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS);

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.

var addUnicornPage = accountPage.addUnicorn();

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
var unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles);

  
```

```kotlin
// The Unicorn is a top-level Object--it has attributes, which are set here. 
// This only stores the values; it does not fill out any web forms or interact
// with the browser in any way.
val sparkles = Unicorn("Sparkles", UnicornColors.PURPLE, UnicornAccessories.SUNGLASSES, UnicornAdornments.STAR_TATTOOS)

// Since we are already "on" the account page, we have to use it to get to the
// actual place where you configure unicorns. Calling the "Add Unicorn" method
// takes us there.
val addUnicornPage = accountPage.addUnicorn()

// Now that we're on the AddUnicornPage, we will pass the "sparkles" object to
// its createUnicorn() method. This method will take Sparkles' attributes,
// fill out the form, and click submit.
unicornConfirmationPage = addUnicornPage.createUnicorn(sparkles)

  
```

```java
// The exists() method from UnicornConfirmationPage will take the Sparkles 
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
Assert.assertTrue("Sparkles should have been created, with all attributes intact", unicornConfirmationPage.exists(sparkles));
  
```

```python
# The exists() method from UnicornConfirmationPage will take the Sparkles
# object--a specification of the attributes you want to see, and compare
# them with the fields on the page.
assert unicorn_confirmation_page.exists(sparkles), "Sparkles should have been created, with all attributes intact"
  
```

```csharp
// The exists() method from UnicornConfirmationPage will take the Sparkles 
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
Assert.True(unicornConfirmationPage.Exists(sparkles), "Sparkles should have been created, with all attributes intact");
  
```

```ruby
# The exists() method from UnicornConfirmationPage will take the Sparkles
# object--a specification of the attributes you want to see, and compare
# them with the fields on the page.
expect(unicorn_confirmation_page.exists?(sparkles)).to be, 'Sparkles should have been created, with all attributes intact'
  
```

```javascript
// The exists() method from UnicornConfirmationPage will take the Sparkles
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
assert(unicornConfirmationPage.exists(sparkles), "Sparkles should have been created, with all attributes intact");

  
```

```kotlin
// The exists() method from UnicornConfirmationPage will take the Sparkles 
// object--a specification of the attributes you want to see, and compare
// them with the fields on the page.
assertTrue("Sparkles should have been created, with all attributes intact", unicornConfirmationPage.exists(sparkles))
  
```

Note that the tester still has not done anything but talk about unicorns in this code– no buttons, no locators, no browser controls. This method of *modelling* the application allows you to keep these test-level commands in place and unchanging, even if Larry decides next week that he no longer likes Ruby-on-Rails and decides to re-implement the entire site in the latest Haskell bindings with a Fortran front-end.

Your page objects will require some small maintenance in order to conform to the site redesign, but these tests will remain the same. Taking this basic design, you will want to keep going through your workflows with the fewest browser-facing steps possible. Your next workflow will involve adding a unicorn to the shopping cart. You will probably want many iterations of this test in order to make sure the cart is keeping its state properly: Is there more than one unicorn in the cart before you start? How many can fit in the shopping cart? If you create more than one with the same name and/or features, will it break? Will it only keep the existing one or will it add another?

Each time you move through the workflow, you want to try to avoid having to create an account, login as the user, and configure the unicorn. Ideally, you will be able to create an account and pre-configure a unicorn via the API or database. Then all you have to do is log in as the user, locate Sparkles, and add her to the cart.

### To automate or not to automate?

Is automation always advantageous? When should one decide to automate test cases?

It is not always advantageous to automate test cases. There are times when manual testing may be more appropriate. For instance, if the application’s user interface will change considerably in the near future, then any automation might need to be rewritten anyway. Also, sometimes there simply is not enough time to build test automation. For the short term, manual testing may be more effective. If an application has a very tight deadline, there is currently no test automation available, and it’s imperative that the testing gets done within that time frame, then manual testing is the best solution.


----
url: https://www.selenium.dev/pt-br/documentation/grid/configuration/help/
----

# Ajuda de configuração

```shell
java -jar selenium-server-<version>.jar info config
```

### Segurança

Para obter detalhes em como configurar os servidores Grid para comunicação segura e para o registo de **Nodes**:

```shell
java -jar selenium-server-<version>.jar info security
```

### Configuração Session Map

Por omissão, a Grid usa um `local session map` para armazenar informação de sessões. A Grid permite armazenamento opcional em Redis ou bancos de dados JDBC SQL. Para obter informação de como usar, use o seguinte comando:

```shell
java -jar selenium-server-<version>.jar info sessionmap
```

### Traceamento com OpenTelemetry e Jaeger

Por omissao, traceamento está activo. Para exportar e visualizar através de Jaeger, use o comando seguinte para instruções de como o efectuar:

```shell
java -jar selenium-server-<version>.jar info tracing
```

## Lista de comandos Selenium Grid

Irá mostrar todos os comandos disponíveis e também a descrição de cada um.

```shell
java -jar selenium-server-<version>.jar --config-help
```

## Comandos de ajuda para componente

Adicione `--help` após o Selenium role para obter informação específica de configuração do componente.

### Standalone

```shell
java -jar selenium-server-<version>.jar standalone --help
```

### Hub

```shell
java -jar selenium-server-<version>.jar hub --help
```

### Sessions

```shell
java -jar selenium-server-<version>.jar sessions --help
```

### New Session Queue

```shell
java -jar selenium-server-<version>.jar sessionqueue --help
```

### Distributor

```shell
java -jar selenium-server-<version>.jar distributor --help
```

### Router

```shell
java -jar selenium-server-<version>.jar router --help
```

### Node

```shell
java -jar selenium-server-<version>.jar node --help
```

----
url: https://www.selenium.dev/zh-cn/documentation/grid/getting_started/
----

# Selenium Grid快速起步

     * [Selenium Manager](https://www.selenium.dev/zh-cn/documentation/selenium_manager/) will configure the drivers automatically if you add `--selenium-manager true`.
     * [需要已经安装并配置了 PATH 环境变量](https://www.selenium.dev/zh-cn/documentation/webdriver/troubleshooting/errors/driver_location/#3-path-环境变量)

```shell
java -jar selenium-server-<version>.jar standalone
```

```shell
java -jar selenium-server-<version>.jar hub
```

默认情况下，服务器将在 <http://localhost:4444> 上监听`RemoteWebDriver`请求。

#### Node

在启动时，**Node**将从系统的[`PATH`](https://www.selenium.dev/zh-cn/documentation/webdriver/troubleshooting/errors/driver_location/#3-path-环境变量)中检测可用的驱动程序。

以下命令假设**Node**正在运行的机器与**Hub**在同一台机器上。

```shell
java -jar selenium-server-<version>.jar node
```

##### 同一台机器上的多个Node

**Node** 1

```shell
java -jar selenium-server-<version>.jar node --port 5555
```

**Node** 2

```shell
java -jar selenium-server-<version>.jar node --port 6666
```

##### 不同机器上的Node和Hub

**Hub**和**Nodes**通过HTTP和[**事件总线**](https://www.selenium.dev/zh-cn/documentation/grid/components/#event-bus)（**事件总线**位于**Hub**内部）进行通信。

**Node**通过事件总线向**Hub**发送消息以开始注册过程。当**Hub**收到消息时，通过HTTP与**Node**联系以确认其存在。

要成功将**Node**注册到**Hub**，重要的是要在**Hub**机器上公开**事件总线**端口（默认为4442和4443）。这也适用于**Node**端口。有了这个，**Hub**和**Node**都能够通信。

如果**Hub**使用默认端口，则可以使用 `--hub` 注册**Node**。

```shell
java -jar selenium-server-<version>.jar node --hub http://<hub-ip>:4444
```

当**Hub**未使用默认端口时，需要使用`--publish-events`和`--subscribe-events`。

例如，如果**Hub**使用端口8886、8887和8888。

```shell
java -jar selenium-server-<version>.jar hub --publish-events tcp://<hub-ip>:8886 --subscribe-events tcp://<hub-ip>:8887 --port 8888
```

**Node**需要使用这些端口才能成功注册。

```shell
java -jar selenium-server-<version>.jar node --publish-events tcp://<hub-ip>:8886 --subscribe-events tcp://<hub-ip>:8887
```

### 分部署部署（Distributed）

在使用分布式Grid时，每个组件都需要单独启动，并且理想情况下应该在不同的机器上。

重要的是要正确暴露所有端口，以允许所有组件之间的流畅通信。

1. **事件总线（Event Bus）**: 使不同网格组件之间的内部通信成为可能。

默认端口为：`4442`、`4443`和`5557`。

```shell
java -jar selenium-server-<version>.jar event-bus --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --port 5557
```

2. **新会话队列（New Session Queue）**: 将新的会话请求添加到一个队列中，Distributor将查询该队列。

默认端口为`5559`。

```shell
java -jar selenium-server-<version>.jar sessionqueue --port 5559
```

3. **会话映射（Session Map）**: 将会话ID映射到运行该会话的节点。

默认**会话映射**端口为`5556`。**会话映射**与**事件总线**进行交互。

```shell
java -jar selenium-server-<version>.jar sessions --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --port 5556
```

4. **分配器（Distributor）**: 查询新 **会话队列（New Session Queue）** 以获取新会话请求，并在能力匹配时将其分配给 **Node**。 **Nodes** 注册到 **Distributor** 的方式与在 **Hub/Node** 网格中注册到 **Hub** 相同。

默认**分配器**端口为`5553`。**分配器** 与 **新会话队列**、**会话映射**、**事件总线** 和 **Node(s)** 进行交互。

```shell
java -jar selenium-server-<version>.jar distributor --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443 --sessions http://<sessions-ip>:5556 --sessionqueue http://<new-session-queue-ip>:5559 --port 5553 --bind-bus false
```

5. **路由器（Router）**: 将新会话请求重定向到队列，并将正在运行的会话请求重定向到运行该会话的**Node**。

默认**路由器**端口为`4444`。**路由器** 与 **新会话队列**、**会话映射**和**分配器** 进行交互。

```shell
java -jar selenium-server-<version>.jar router --sessions http://<sessions-ip>:5556 --distributor http://<distributor-ip>:5553 --sessionqueue http://<new-session-queue-ip>:5559 --port 4444
```

6. **Node(s)**

默认 **Node** 端口是 `5555`.

```shell
java -jar selenium-server-<version>.jar node --publish-events tcp://<event-bus-ip>:4442 --subscribe-events tcp://<event-bus-ip>:4443
```

## 测试中的 Metadata

向测试中添加 `Metadata` 并通过[GraphQL](https://www.selenium.dev/zh-cn/documentation/grid/advanced_features/graphql_support/)进行消费，或通过 `Selenium Grid UI` 可视化其部分内容（例如`se:name`）。

可以通过在 `capability` 前加上 `se:` 来添加元数据。以下是一个Java的快速示例。

```java
ChromeOptions chromeOptions = new ChromeOptions();
chromeOptions.setCapability("browserVersion", "100");
chromeOptions.setCapability("platformName", "Windows");
// Showing a test name instead of the session id in the Grid UI
chromeOptions.setCapability("se:name", "My simple test"); 
// Other type of metadata can be seen in the Grid UI by clicking on the 
// session info or via GraphQL
chromeOptions.setCapability("se:sampleMetadata", "Sample metadata value"); 
WebDriver driver = new RemoteWebDriver(new URL("http://gridUrl:4444"), chromeOptions);
driver.get("http://www.google.com");
driver.quit();
```

```bash
java -Dwebdriver.http.factory=jdk-http-client -jar selenium-server-<version>.jar --ext selenium-http-jdk-client-<version>.jar standalone
```

下载 `selenium-http-jdk-client` jar 文件的替代方法是使用 [Coursier](https://get-coursier.io/docs/cli-installation)。

```bash
java -Dwebdriver.http.factory=jdk-http-client -jar selenium-server-<version>.jar --ext $(coursier fetch -p org.seleniumhq.selenium:selenium-http-jdk-client:<version>) standalone
```

最后修改 August 1, 2025: [\[deploy site\] fixing bug 2402, detectify link removal (#2407) (0b29bc6e614)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/0b29bc6e6148f4e99aab014c39ae33e5fefe7222)

----
url: https://www.selenium.dev/ja/documentation/webdriver/support_features/
----

# サポート機能

サポート クラスは、オプションの上位レベル機能を提供します。

The core libraries of Selenium try to be low level and non-opinionated. The Support classes in each language provide opinionated wrappers for common interactions that may be used to simplify some behaviors.

***

##### [Waiting with Expected Conditions](/ja/documentation/webdriver/support_features/expected_conditions/)

These are classes used to describe what needs to be waited for.

##### [Command Listeners](/ja/documentation/webdriver/support_features/listeners/)

##### [色を扱う](/ja/documentation/webdriver/support_features/colors/)

##### [選択要素の操作](/ja/documentation/webdriver/support_features/select_lists/)

選択リストには、他の要素と比較して特別な動作があります。

##### [ThreadGuard](/ja/documentation/webdriver/support_features/thread_guard/)

----
url: https://www.selenium.dev/ja/documentation/webdriver/getting_started/
----

# 入門

Seleniumを初めて使用する場合は、すぐに習得するのに役立つリソースがいくつかあります。

***

##### [Seleniumライブラリのインストール](/ja/documentation/webdriver/getting_started/install_library/)

お気に入りのプログラミング言語用にSeleniumライブラリを設定します。

##### [最初のSeleniumスクリプトを書く](/ja/documentation/webdriver/getting_started/first_script/)

Seleniumスクリプトを作成するための段階的な説明

##### [Seleniumコードの整理と実行](/ja/documentation/webdriver/getting_started/using_selenium/)

IDEとテストランナーライブラリを使用したSelenium実行のスケーリング

----
url: https://www.selenium.dev/pt-br/documentation/legacy/selenium_ide/html_runner/
----

# HTML runner

```shell
[user@localhost ~]$ cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

[user@localhost ~]$ rpm -qa | egrep -i "xvfb|java-1.8|firefox"
xorg-x11-server-Xvfb-1.19.3-11.el7.x86_64
firefox-52.4.0-1.el7.centos.x86_64
java-1.8.0-openjdk-1.8.0.151-1.b12.el7_4.x86_64
java-1.8.0-openjdk-headless-1.8.0.151-1.b12.el7_4.x86_64
```

Exemplo de suíte de testes:

```html
[user@localhost ~]$ cat testsuite.html
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
  <title>Test Suite</title>
</head>
<body>
<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium"><tbody>
<tr><td><b>Test Suite</b></td></tr>
<tr><td><a href="YOUR-TEST-SCENARIO.html">YOUR-TEST-SCENARIO</a></td></tr>
</tbody></table>
</body>
</html>
```

## Como rodar o selenium-html-runner headless

Agora, a parte mais importante, um exemplo de como executar o selenium-html-runner! Sua experiência pode variar dependendo das combinações de software - versões geckodriver / FF / html-runner.

```shell
xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
```

```shell
[user@localhost ~]$ xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "*firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
Multi-window mode is longer used as an option and will be ignored.
1510061109691   geckodriver     INFO    geckodriver 0.18.0
1510061109708   geckodriver     INFO    Listening on 127.0.0.1:2885
1510061110162   geckodriver::marionette INFO    Starting browser /usr/bin/firefox with args ["-marionette"]
1510061111084   Marionette      INFO    Listening on port 43229
1510061111187   Marionette      WARN    TLS certificate errors will be ignored for this session
Nov 07, 2017 1:25:12 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
2017-11-07 13:25:12.714:INFO::main: Logging initialized @3915ms to org.seleniumhq.jetty9.util.log.StdErrLog
2017-11-07 13:25:12.804:INFO:osjs.Server:main: jetty-9.4.z-SNAPSHOT
2017-11-07 13:25:12.822:INFO:osjsh.ContextHandler:main: Started o.s.j.s.h.ContextHandler@87a85e1{/tests,null,AVAILABLE}
2017-11-07 13:25:12.843:INFO:osjs.AbstractConnector:main: Started ServerConnector@52102734{HTTP/1.1,[http/1.1]}{0.0.0.0:31892}
2017-11-07 13:25:12.843:INFO:osjs.Server:main: Started @4045ms
Nov 07, 2017 1:25:13 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |open | /auth_mellon.php |  |
Nov 07, 2017 1:25:14 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |waitForPageToLoad | 3000 |  |
.
.
.etc

<td>result:</td>
<td>PASS</td>
```

----
url: https://www.selenium.dev/_print/documentation/legacy/developers/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/legacy/developers/).

# Legacy developer documentation

Information of interest to developers of Selenium

* 1: [Crazy Fun Build Tool](#pg-2b6c9c51f27a64725c8c0a31b8b03410)
* 2: [Buck Build Tool](#pg-81809b631ab02f068a62c6d946181953)
* 3: [Adding new drivers to Selenium 2 code](#pg-b298e82c015f8bca9f928bf1f7086bfc)
* 4: [Selenium's Continuous Integration Implementation](#pg-7fbb4509f1f8120b35e7ede7afd2208a)
* 5: [Google Summer of Code 2011](#pg-9de634ad30601b09ab6d4dc220dc4fad)
* 6: [Developer Tips](#pg-954466729b10336f6f769f2013a2c081)
* 7: [Snapshot of Roadmaps for Selenium Releases](#pg-39a7dde85bdbfff147088b41161f32a5)

# 1 - Crazy Fun Build Tool

The original Selenium Build Tool that grew from nothing to be extremely unwieldy, making it both crazy and “fun” to work with.

This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/Crazy-Fun-Build)

WebDriver is a large project: if we tried to push everything into a single monolithic build file it eventually becomes unmanageable. We know this. We’ve tried it. So we broke the single Rakefile into a series of `build.desc` files. Each of these describe a part of the build.

Let’s take a look at a build.desc file. This is part of the [main test build.desc](https://github.com/SeleniumHQ/selenium/blob/master/java/client/test/org/openqa/selenium/build.desc):

```
java_test(name = "single",
  srcs = [
    "SingleTestSuite.java",
  ],
  deps = [
    ":tests",
    "//java/server/src/org/openqa/selenium/server",
    "//java/client/test/org/openqa/selenium/v1:selenium-backed-webdriver-test",
    "//java/client/test/org/openqa/selenium/firefox:test",
  ]  ])
```

```
./go -T
```

Being a brief description of the available targets that you can use.

### Common Attributes

The following attributes are required for all build targets:

| **Attribute Name** | **Type** | **Meaning**                                                                 |
| ------------------ | -------- | --------------------------------------------------------------------------- |
| name               | string   | Used to derive the rake target and (often) the name of the generated binary |

The following attributes are commonly used:

| **Attribute Name** | **Type** | **Meaning**                                |
| ------------------ | -------- | ------------------------------------------ |
| srcs               | array    | The raw source to be build for this target |
| deps               | array    | Prerequisites of this target               |

### java\_library

* **Output:** JAR file named after the “name” attribute if the “srcs” attribute is set.
* **Implicit Targets:** run (if “main” attribute specifiec), project, project-srcs, uber, zip
* **Required Attributes:** “name” and at least one of “srcs” or “deps”.

| **Attribute Name** | **Type** | **Meaning**                                                                         |
| ------------------ | -------- | ----------------------------------------------------------------------------------- |
| deps               | array    | As above                                                                            |
| srcs               | array    | As above                                                                            |
| resources          | array    | Any resources that should be copied into the jar file.                              |
| main               | string   | The full classname of the main class of the jar (used for creating executable jars) |

### java\_test

* **Output:** JAR file named after the “name” attribute if the “srcs” attribute is set.
* **Implicit Targets:** run, project, project-srcs, uber, zip
* **Required Attributes:** “name” and at least one of “srcs” or “deps”.

| **Attribute Name** | **Type** | **Meaning**                                                      |
| ------------------ | -------- | ---------------------------------------------------------------- |
| deps               | array    | As above.                                                        |
| srcs               | array    | As above.                                                        |
| resources          | array    | Any resources that should be copied into the jar file.           |
| main               | string   | The alternative class to use for running these tests.            |
| args               | string   | The argument line to pass to the main class                      |
| sysproperties      | array    | An array of maps containing System properties that should be set |

### js\_deps

* **Output:** Marker file to indicate task is up to date.
* **Implicit Targets:** None
* **Required Attributes:** “name” and “srcs”

| **Attribute Name** | **Type** | **Meaning** |
| ------------------ | -------- | ----------- |
| name               | string   | As above    |
| srcs               | array    | As above    |
| deps               | array    | As above    |

### js\_binary

* **Output:** A monolithic JS file containing all dependencies and sources compiled using the closure compiler without optimizations.
* **Implicit Targets:** None
* **Required Attributes:** At least one of srcs or deps.

| **Attribute Name** | **Type** | **Meaning** |
| ------------------ | -------- | ----------- |
| name               | string   | As above    |
| srcs               | array    | As above    |
| deps               | array    | As above    |

### js\_fragment

* **Output:** Source of an anonymous function representing the exported function, compiled by the closure compiler with all optimizations turned on.
* **Implicit Targets:** None
* **Required Attributes:** name, module, function, deps

| **Attribute Name** | **Type** | **Meaning**                                    |
| ------------------ | -------- | ---------------------------------------------- |
| name               | string   | As above                                       |
| module             | string   | The name of the module containing the function |
| function           | string   | The full name of the function to export        |
| deps               | array    | As above                                       |

### js\_fragment\_header

* **Output:** A C header file with all js\_fragment dependencies declared as constants.
* **Implicit Targets:** None
* **Required Attributes:** name, deps

| **Attribute Name** | **Type** | **Meaning** |
| ------------------ | -------- | ----------- |
| name               | string   | As above    |
| srcs               | array    | As above    |
| deps               | array    | As above    |

### js\_test

* **Output:**
* **Implicit Targets:** `_`BROWSER:run, run
* **Required Attributes:** None.

| **Attribute Name** | **Type** | **Meaning**                                                                                                                                                                                                 |
| ------------------ | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| deps               | array    | As above.                                                                                                                                                                                                   |
| srcs               | array    | As above.                                                                                                                                                                                                   |
| path               | string   | The path at which to expect the test files to be hosted on the test server.                                                                                                                                 |
| browsers           | array    | List of browsers, from rake\_tasks/browsers.rb, to run the tests in. Will only attempt to run tests in those browsers which are available on the system. If absent, defaults to all browsers on the system. |

Assuming browsers = \[‘ff’, ‘chrome’], for target //foo, the implicit targets: //foo\_ff:run and //foo\_chrome:run will be generated, which run the tests in each of those browsers, and the implicit target //foo:run will be generated, which runs the tests in both ff and chrome.

### py\_test

* **Output:** Creates the directory structure required to run the listed python tests.
* **Implicit Targets:** `_`BROWSER:run, run
* **Required Attributes:** name.

| **Attribute Name**       | **Type** | **Meaning**                                                                                                                                                                                                     |
| ------------------------ | -------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| deps                     | array    | Other py\_test rule(s), whose tests should also be run.                                                                                                                                                         |
| common\_tests            | array    | Test file(s) to be run in all browsers. These tests will be passed through a template, with browser-specific substitutions, so that they are laid out properly for each browser in the python output file tree. |
| BROWSER\_specific\_tests | array    | Test file(s) to be run only in browser BROWSER.                                                                                                                                                                 |
| resources                | array    | Resources which should be copied to the python directory structure.                                                                                                                                             |
| browsers                 | array    | List of browsers, from rake\_tasks/browsers.rb, to run the tests in. Will only attempt to run tests in those browsers which are available on the system. If absent, defaults to all browsers on the system.     |

Note: Every py\_test invocation is performed in a new virtualenv.

### rake\_task

* **Output:** A crazy fun build rule that can be referred to “blow the escape” hatch and use ordinary rake targets.
* **Implicit Targets:** None
* **Required Attributes:** name, task\_name, out.

| **Attribute Name** | **Type** | **Meaning**                                          |
| ------------------ | -------- | ---------------------------------------------------- |
| name               | string   | As above                                             |
| task\_name         | string   | The ordinary rake target to call                     |
| out                | string   | The file that is generated, relative to the Rakefile |

### gcc\_library

* **Output:** Shared library file named after the “name” attribute if the “srcs” attribute is set.
* **Implicit Targets:** None.
* **Required Attributes:** “name” and “srcs”.

| **Attribute Name** | **Type** | **Meaning**                                          |
| ------------------ | -------- | ---------------------------------------------------- |
| srcs               | array    | As above                                             |
| arch               | string   | “amd64” for 64-bit builds, “i386” for 32-bit builds. |
| args               | string   | Arguments to the compiler (-I flags, for example).   |
| link\_args         | string   | Arguments to the linker (-l flags, for example)      |

Note: When building a new library for the first time, the build will succeed but copying to pre-built will fail with a similar message:

```
cp build/cpp/amd64/libimetesthandler64.so 
go aborted!
can't convert nil into String
```

Solution: Copy the just-built library to the appropriate prebuilt folder (cpp/prebuilt/arch/).

# 2 - Buck Build Tool

Buck is a build tool from Facebook that we were working with to replace Crazy fun. We have since replaced it with [Bazel](https://bazel.build/).

This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/Buck)\
You can read the documentation for the legacy [Crazy Fun Build tool](https://www.selenium.dev/documentation/legacy/developers/crazy_fun_build/).

## Building Selenium with Buck

The easiest thing to do is to just run “./go”. The build process will download the right version of Buck for you so long as there’s no `.nobuckcheck` file in the root of the project. The download ends up in `buck-out/crazy-fun/HASH/buck.pex` where `HASH` is the value of the current buck version (given in the `.buckversion` file in the root of the project.

If you’d like to build and run our fork of Buck, then:

```
git clone https://github.com/SeleniumHQ/buck.git
cd buck && ant
export PATH=`pwd`/bin:$PATH
cd ~/src/selenium 
buck build chrome firefox htmlunit remote leg-rc
buck test --all
```

# 3 - Adding new drivers to Selenium 2 code

# 4 - Selenium's Continuous Integration Implementation

# 5 - Google Summer of Code 2011

# 6 - Developer Tips

Details on how to execute Selenium Test Suite with Crazy Fun.

This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/Developer-Tips)

## Running an Individual Test

When developing WebDriver, it is common to want to run a single test rather than the entire test suite for a particular driver.

You can run all the tests in a given test class this way:

```
./go test_firefox onlyRun=CombinedInputActionsTest
```

You can also run a single test directly from the command line by typing:

```
./go test_firefox method=foo
```

## Not Halting On Errors Or Failures

The test suite will halt on errors and failures by default. You can disable this behaviour by setting the `haltonerror` or `haltonfailure` environmental variables to `0`.

## Reviewing the Logs For the Tests

When you run the tests, the test results don’t appear on the screen. They are written to the \`./build/test\_logs’ folder. A pair of files are written. Their names are relatively consistent and include the details of the tests which were run. The pair comprise a txt file and an xml file. The xml file contains more information about the runtime environment such as the path, Ant version, etc. These files are overwritten the next time the same test target is executed so you may want to archive results if they’re important to you.

## Using Rake

Rake is very similar to using other build tools such as “make” or “ant”. You can specify a “target” to run by adding it as a parameter, and you can add more than one target at a time. Note that since WebDriver does not rely on ruby being installed and uses JRuby, rake should **not** be involved directly - use the *go* script instead. For example, in order to clean the build and then build and run the HtmlUnitDriver tests:

```
./go clean test_htmlunit
```

The default target that’s used will compile the code and run all the tests. More interesting targets are:

| **Target**     | **Description**                                                                                                                                                     |
| -------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| clean          | Delete the contents of the build directory, removing all compiled artifacts                                                                                         |
| test           | Compile the dependencies of and run all the tests for the HtmlUnitDriver, FirefoxDriver, and InternetExplorerDriver as well as the support library’s tests          |
| firefox        | Compile the FirefoxDriver                                                                                                                                           |
| htmlunit       | Compile the HtmlUnitDriver                                                                                                                                          |
| ie             | Compile the InternetExplorerDriver. This won’t compile the C++ on a non-Windows system, but will always compile the Java, no matter which OS you happen to be using |
| support        | Guess what this does :)                                                                                                                                             |
| test\_htmlunit | Compile the dependencies and then run the tests for the HtmlUnitDriver. The same “test\_x” pattern can be followed for all the compilation targets in this table.   |

### Running a remote Debugger with Java tests

You can run the tests in debug mode and wait for a remote java listener (which one would setup in eclipse or intellij).

```
./go debug=true suspend=true test_firefox
```

## Debugging the Firefox Driver

### Getting output from the Firefox process itself

This is usually useful to debug issues with Firefox starting up. The Java system property `webdriver.firefox.logfile` will instruct the FirefoxDriver to redirect the output to a file:

```
java -Dwebdriver.firefox.logfile=/dev/stdout -cp selenium-2.jar <sometest>
```

### Outputting to the Error Console

A common technique used for debugging of the Firefox driver extension is debug statements. The two following methods can be used from almost any Javascript code inside the extension:

* `Logger.dumpn()` - Logs a string into console (and converts arguments to strings). For example: `Logger.dumpn("Found element: " + node)`.
* `Logger.dump()` - Gets a single argument, an object, and dumps its entire contents: implemented interfaces, data fields, methods, etc.

### Getting output from the error console to a file

To see output generated using the `Logger` utility, one has to open up Firefox’s error console - difficult or simply impossible on remote machines. Fortunately, there’s a way to get the contents of the output dumped to a file:

```
FirefoxProfile p = new FirefoxProfile();
p.setPreference("webdriver.log.file", "/tmp/firefox_console");
WebDriver driver = new FirefoxDriver(p);
...
```

The `webdriver.log.file` preference will instruct the `Logger` to dump all contents of the console to the specified file. webdriver.log.file

### Getting even more output to the command line

When suspecting additional logging from Firefox could be beneficial, one can crank debugging level all the way up:

```
export NSPR_LOG_MODULES=all:3
```

Setting this environment variable will cause Firefox to log additional messages to the console. Use this environment variable together with `webdriver.firefox.logfile` to get a hold of Firefox’s output to the console.

## Debugging the Internet Explorer Driver

In order to get detailed information from IEDriverServer.exe you can run tests with the option devMode=true, this option will set logging level to DEBUG and redirect log output to the file iedriver.log

```
./go test_ie devMode=true
```

## Adding a test

Most of WebDriver’s test cases live under java/client/test/org/openqa/selenium. For example, to demonstrate an issue with clicking on elements, a test case should be added to ClickTest. The test cases already have a driver instance - no need to create one. The test use pages that are served by an in-process server, served from common/src/web. Their URLs are provided by the Pages class, so when adding a page and add it to the Pages class as well.

## Manually interacting with `RemoteWebDriverServer`

We can use a web browser or tools such as telnet to interact with a RemoteWebDriverServer e.g. to debug the JSON protocol. Here’s a simple example of checking the status of a server installed on the local machine

In a web browser

```
http://localhost:8080/wd/hub/status/
```

In telnet

```
telnet localhost 8080

GET /wd/hub/status/ HTTP/1.0
```

On Macs and Unix in general try `curl`

```
curl  http://localhost:8080/wd/hub/status
```

And on linux `wget`

```
wget http://localhost:8080/wd/hub/status
```

In all these cases the RemoteWebDriverServer should respond with

```

{status:0} 
```

# 7 - Snapshot of Roadmaps for Selenium Releases

The list of plans and things to accomplish before a release

## Preparation for Selenium 2

Date unknown This documentation previously located [on the wiki](https://github.com/SeleniumHQ/selenium/wiki/RoadMap/eef12bca5fdc865449ad2d1735ee08e40ba0bd2b)

The following issues need to be resolved before the final release:

| **Issue**                                                    | **Summary**                                             | **HtmlUnitDriver Progress** | **FirefoxDriver Progress** | **InternetExplorerDriver Progress** | **ChromeDriver Progress** |
| ------------------------------------------------------------ | ------------------------------------------------------- | --------------------------- | -------------------------- | ----------------------------------- | ------------------------- |
| [27](http://code.google.com/p/webdriver/issues/detail?id=27) | Handle alerts in Javascript-enabled browsers            | n/a                         | Started                    | Started                             | Not Started               |
| [32](http://code.google.com/p/webdriver/issues/detail?id=32) | User guide                                              | Started                     |                            |                                     |                           |
| [34](http://code.google.com/p/webdriver/issues/detail?id=34) | Support HTTP Basic and Digest Authentication            | Not Started                 |                            |                                     |                           |
| [35](http://code.google.com/p/webdriver/issues/detail?id=35) | [Selenium](http://www.openqa.org/selenium-rc) emulation | Done for Java and C#        |                            |                                     |                           |
| [36](http://code.google.com/p/webdriver/issues/detail?id=36) | Support for drag and drop behaviour                     | n/a                         | Done                       | Done                                | Started                   |
| none                                                         | Example tests                                           | Not Started                 |                            |                                     |                           |

----
url: https://www.selenium.dev/documentation/overview/
----

# Selenium Overview

Is Selenium for you? See an overview of the different project components.

***

##### [Selenium components](/documentation/overview/components/)

##### [A deeper look at Selenium](/documentation/overview/details/)

Selenium is an umbrella project for a range of tools and libraries that enable and support the automation of web browsers.

Last modified February 6, 2024: [Moving overview to 1 (787511bb9e3)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/787511bb9e3059bd44a7eb5647289d70599a620a)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/getting_started/install_library/
----

# Instalando bibliotecas do Selenium

```xml
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/pom.xml#L35-L38)

##### /examples/java/pom.xml

```xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>dev.selenium</groupId>
    <artifactId>selenium-examples</artifactId>
    <version>1.0.0</version>

    <properties>
        <surefire.parallel>1</surefire.parallel>
        <maven.compiler.source>17</maven.compiler.source>
        <maven.compiler.target>17</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <selenium.version>4.41.0</selenium.version>
    </properties>

    <repositories>
        <repository>
            <name>Central Portal Snapshots</name>
            <id>central-portal-snapshots</id>
            <url>https://central.sonatype.com/repository/maven-snapshots/</url>
            <releases>
                <enabled>false</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <dependencies>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-java</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>org.seleniumhq.selenium</groupId>
            <artifactId>selenium-grid</artifactId>
            <version>${selenium.version}</version>
        </dependency>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter-engine</artifactId>
            <version>6.0.2</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>com.titusfortner</groupId>
            <artifactId>selenium-logger</artifactId>
            <version>2.4.0</version>
            <scope>test</scope>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>3.5.5</version>
                <configuration>
                    <properties>
                        <configurationParameters>
                            junit.jupiter.execution.parallel.enabled = true
                            junit.jupiter.execution.parallel.mode.default = concurrent
                            junit.jupiter.execution.parallel.config.strategy = fixed
                            junit.jupiter.execution.parallel.config.fixed.parallelism = ${surefire.parallel}
                            junit.jupiter.execution.parallel.config.fixed.max-pool-size = ${surefire.parallel}
                        </configurationParameters>
                    </properties>
                    <rerunFailingTestsCount>3</rerunFailingTestsCount>
                </configuration>
            </plugin>
        </plugins>
    </build>
</project>
```

### Gradle

Especifique a dependência no `build.gradle` do seu projeto como `testImplementation`:

```gradle

dependencies {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/build.gradle#L13-L14)

##### /examples/java/build.gradle

```gradle
plugins {
    id 'java'
}

group 'dev.selenium'
version '1.0-SNAPSHOT'

repositories {
    mavenCentral()
}

ext['seleniumVersion'] = System.getProperty('selenium.version', '4.41.0')

dependencies {
    testImplementation "org.seleniumhq.selenium:selenium-java:${seleniumVersion}"
    testImplementation "org.seleniumhq.selenium:selenium-grid:${seleniumVersion}"
    testImplementation platform("org.junit:junit-bom:6.0.2")
    testImplementation 'org.junit.jupiter:junit-jupiter-engine'
    testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
    testImplementation 'com.titusfortner:selenium-logger:2.4.0'
}

test {
    useJUnitPlatform()
}
```

A mínima versão suportada do Python para cada versão do Selenium pode ser encontrada em “Supported Python Versions” no [PyPi](https://pypi.org/project/selenium/).

Existe muitas formas diferentes de instalar Selenium.

### Pip

```shell
pip install selenium
```



### Download

Como uma alternativa você pode baixar o [código fonte PyPI](https://pypi.org/project/selenium/#files) (selenium-x.x.x.-py3-none-any.whl) e instalar usando *pip*:

```shell
pip install selenium-x.x.x.-py3-none-any.whl
```



### Exigir em um projeto

Para usar em um projeto, adicione no arquivo `requirements.txt`.

```txt
selenium==4.41.0
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/requirements.txt#L1)

##### /examples/python/requirements.txt

```txt
selenium==4.41.0
pytest==9.0.3
trio==0.31.0
pytest-trio==0.8.0
pytest-rerunfailures==16.1
flake8==7.3.0
requests==2.33.0
tox==4.32.0
pytest-xdist==3.8.0
```

Uma lista com todos os frameworks suportados para cada versão do Selenium pode ser encontrada em [Nuget](https://www.nuget.org/packages/Selenium.WebDriver)

Existe algumas opções para instalar o Selenium.

### Packet Manager

```shell
Install-Package Selenium.WebDriver
```



### .NET CLI

```shell
dotnet add package Selenium.WebDriver
```



### CSProj

No arquivo `csproj` do seu projeto, especifique a dependência como `PackageReference` no `ItemGroup`:

```csproj
      <PackageReference Include="Selenium.WebDriver" Version="4.41.0" />
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/SeleniumDocs.csproj#L14)

##### /examples/dotnet/SeleniumDocs/SeleniumDocs.csproj

```csproj
<Project Sdk="Microsoft.NET.Sdk">

    <PropertyGroup>
        <TargetFramework>net8.0</TargetFramework>
        <GenerateProgramFile>false</GenerateProgramFile>
    </PropertyGroup>

    <ItemGroup>
      <PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.11.1" />
      <PackageReference Include="Microsoft.IdentityModel.Tokens" Version="7.7.1" />
      <PackageReference Include="MSTest.TestAdapter" Version="3.6.0" />
      <PackageReference Include="MSTest.TestFramework" Version="3.6.0" />
      <PackageReference Include="Selenium.Support" Version="4.41.0" />
      <PackageReference Include="Selenium.WebDriver" Version="4.41.0" />
    </ItemGroup>

    <ItemGroup>
      <Folder Include="LocalPackages" />
    </ItemGroup>

</Project>
```

### Considerações adicionais

Outras observações para usar o Visual Studio Code (vscode) e C#

Instale a versão compatível do .NET SDK conforme a seção acima. Instale também as extensões do vscode (Ctrl-Shift-X) para C# e NuGet. Siga as instruções [aqui ](https://docs.microsoft.com/en-us/dotnet/core/tutorials/with-visual-studio-code?pivots=dotnet-5-0)para criar e rodar o seu projeto de “Hello World” no console usando C#.

Você também pode criar um projeto inicial do NUnit usando a linha de comando `dotnet new NUnit`. Certifique-se de que o arquivo `%appdata%\NuGet\nuget.config` esteja configurado corretamente, pois alguns desenvolvedores relataram que ele estará vazio devido a alguns problemas. Se o `nuget.config` estiver vazio ou não estiver configurado corretamente, as compilações .NET falharão para projetos que estiverem usando Selenium. Adicione a seguinte seção ao arquivo `nuget.config` se esse estiver vazio:

```
<configuration>
  <packageSources>
    <add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
    <add key="nuget.org" value="https://www.nuget.org/api/v2/" />   
  </packageSources>
...
```

Para mais informações sobre `nuget.config` [clique aqui](https://docs.microsoft.com/en-us/nuget/reference/nuget-config-file). Você pode ter que customizar `nuget.config` para atender às suas necessidades.

Agora, volte para o vscode, aperte Ctrl-Shift-P, e digite “NuGet Add Package”, e adicione os pacotes necessários para o Selenium como o `Selenium.WebDriver`. Aperte Enter e selecione a versão. Agora você pode usar os exemplos da documentação relacionados ao C# com o vscode.

Você pode ver a minima versão suportada do Ruby para cada versão do Selenium em [rubygems.org](https://rubygems.org/gems/selenium-webdriver/)

O Selenium pode ser instalado de duas formas diferentes.

### Instalação manual

```shell
gem install selenium-webdriver
```



### Adicione para o gemfile do projeto

```gemfile
gem 'selenium-devtools', '= 0.147.0'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/Gemfile#L10)

##### /examples/ruby/Gemfile

```gemfile
# frozen_string_literal: true

source 'https://rubygems.org'

gem 'ffi', '~> 1.15', '>= 1.15.5' if Gem.win_platform? # Windows only
gem 'rake', '~> 13.0'
gem 'rspec', '~> 3.0'
gem 'rubocop', '~> 1.35'
gem 'rubocop-rspec', '~> 3.0'
gem 'selenium-devtools', '= 0.147.0'
gem 'selenium-webdriver', '= 4.43.0'
```

Você pode encontrar a mínima versão suportada do Node para cada versão do Selenium na seção `Node Support Policy` no site [npmjs](https://www.npmjs.com/package/selenium-webdriver)

Selenium é normalmente instalado usando npm.

### Instalação local

```shell
npm install selenium-webdriver
```



### Adicione ao seu projeto

No `package.json` do seu projeto, adicione os requisitos em `dependencies`:

```json
        "mocha": "11.7.5"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/package.json#L14)

##### /examples/javascript/package.json

```json
{
    "name": "javascript-examples",
    "version": "1.0.0",
    "scripts": {
        "test": "npx mocha test/**/*.spec.js --timeout 120000 --parallel --retries 2"
    },
    "author": "The Selenium project",
    "license": "Apache-2.0",
    "dependencies": {
        "assert": "2.1.0",
        "selenium-webdriver": "4.41.0"
    },
    "devDependencies": {
        "mocha": "11.7.5"
    }
}
```

Use as ligações Java para Kotlin.

## Próximo passo

[Programando o seu primeiro script Selenium](https://www.selenium.dev/pt-br/documentation/webdriver/getting_started/first_script/)

Última modificação September 2, 2025: [fixed line number to show case selenium maven dependency (#2450) (845ea50bbac)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/845ea50bbac1131c18ea2735554c1611e5369777)

----
url: https://www.selenium.dev/ja/documentation/legacy/selenium_ide/html_runner/
----

# HTMLランナー

```shell
[user@localhost ~]$ cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

[user@localhost ~]$ rpm -qa | egrep -i "xvfb|java-1.8|firefox"
xorg-x11-server-Xvfb-1.19.3-11.el7.x86_64
firefox-52.4.0-1.el7.centos.x86_64
java-1.8.0-openjdk-1.8.0.151-1.b12.el7_4.x86_64
java-1.8.0-openjdk-headless-1.8.0.151-1.b12.el7_4.x86_64
```

テストスイートの例

```html
[user@localhost ~]$ cat testsuite.html
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
  <title>Test Suite</title>
</head>
<body>
<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium"><tbody>
<tr><td><b>Test Suite</b></td></tr>
<tr><td><a href="YOUR-TEST-SCENARIO.html">YOUR-TEST-SCENARIO</a></td></tr>
</tbody></table>
</body>
</html>
```

## selenium-html-runnerをヘッドレスで実行する方法

さて、最も重要な部分、selenium-html-runnerの実行方法の例！ 経験によってソフトウェアの組み合わせ、- geckodriver / FF / html-runnerリリースによって異なる場合があります。

```shell
xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
```

```shell
[user@localhost ~]$ xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "*firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
Multi-window mode is longer used as an option and will be ignored.
1510061109691   geckodriver     INFO    geckodriver 0.18.0
1510061109708   geckodriver     INFO    Listening on 127.0.0.1:2885
1510061110162   geckodriver::marionette INFO    Starting browser /usr/bin/firefox with args ["-marionette"]
1510061111084   Marionette      INFO    Listening on port 43229
1510061111187   Marionette      WARN    TLS certificate errors will be ignored for this session
Nov 07, 2017 1:25:12 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
2017-11-07 13:25:12.714:INFO::main: Logging initialized @3915ms to org.seleniumhq.jetty9.util.log.StdErrLog
2017-11-07 13:25:12.804:INFO:osjs.Server:main: jetty-9.4.z-SNAPSHOT
2017-11-07 13:25:12.822:INFO:osjsh.ContextHandler:main: Started o.s.j.s.h.ContextHandler@87a85e1{/tests,null,AVAILABLE}
2017-11-07 13:25:12.843:INFO:osjs.AbstractConnector:main: Started ServerConnector@52102734{HTTP/1.1,[http/1.1]}{0.0.0.0:31892}
2017-11-07 13:25:12.843:INFO:osjs.Server:main: Started @4045ms
Nov 07, 2017 1:25:13 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |open | /auth_mellon.php |  |
Nov 07, 2017 1:25:14 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |waitForPageToLoad | 3000 |  |
.
.
.etc

<td>result:</td>
<td>PASS</td>
```

----
url: https://www.selenium.dev/ja/documentation/grid/
----

# Grid

複数のマシンで並行してテストを実行したいですか？ Grid が手助けします。

Selenium Grid を利用して、クライアントからリモートブラウザーインスタンスにコマンドを ルーティングし、リモートマシン上で WebDriver スクリプトを実行することができます。

Grid の目標は、

* 複数のマシンでの並行したテスト実行を、簡単な方法で提供する
* 異なるバージョンのブラウザでのテストを可能にする
* クロスプラットフォームテストを可能にする

興味がありますか？ Grid の仕組みと設定方法が知りたければ以下のセクションを読んでください。

***

##### [Gridを始める](/ja/documentation/grid/getting_started/)

Selenium Gridの導入方法

##### [いつGridを使用すべきか](/ja/documentation/grid/applicability/)

Gridがあなたにとって最適なツールでしょうか？

##### [Selenium Grid のコンポーネント](/ja/documentation/grid/components/)

Grid コンポーネントの使い方について

##### [コンポーネントの構成](/ja/documentation/grid/configuration/)

ここでは、各コンポーネントを、共通の設定とコンポーネント固有の設定で個別に設定する方法を確認できます。

##### [Grid アーキテクチャ](/ja/documentation/grid/architecture/)

##### [高度な機能](/ja/documentation/grid/advanced_features/)

高度な機能のすべての詳細を取得し、それがどのように機能するか、および独自の設定方法を理解するには、次のセクションを参照してください。

最終更新 February 6, 2024: [Grid as 4 in the index (f414b1ef8f2)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/f414b1ef8f2f4d0412a75fe8ca059786be95b0c0)

----
url: https://www.selenium.dev/ja/documentation/test_practices/encouraged/domain_specific_language/
----

# ドメイン固有言語（DSL）

```java
/**
 * Takes a username and password, fills out the fields, and clicks "login".
 * @return An instance of the AccountPage
 */
public AccountPage loginAsUser(String username, String password) {
  WebElement loginField = driver.findElement(By.id("loginField"));
  loginField.clear();
  loginField.sendKeys(username);

  // Fill out the password field. The locator we're using is "By.id", and we should
  // have it defined elsewhere in the class.
  WebElement passwordField = driver.findElement(By.id("password"));
  passwordField.clear();
  passwordField.sendKeys(password);

  // Click the login button, which happens to have the id "submit".
  driver.findElement(By.id("submit")).click();

  // Create and return a new instance of the AccountPage (via the built-in Selenium
  // PageFactory).
  return PageFactory.newInstance(AccountPage.class);
}
```

このメソッドは、テストコードから入力フィールド、ボタン、クリック、さらにはページの概念を完全に抽象化します。 このアプローチを使用すると、テスターはこのメソッドを呼び出すだけで済みます。 これにより、メンテナンスの利点が得られます。 ログインフィールドが変更された場合、テストではなく、このメソッドを変更するだけで済みます。

```java
public void loginTest() {
    loginAsUser("cbrown", "cl0wn3");

    // Now that we're logged in, do some other stuff--since we used a DSL to support
    // our testers, it's as easy as choosing from available methods.
    do.something();
    do.somethingElse();
    Assert.assertTrue("Something should have been done!", something.wasDone());

    // Note that we still haven't referred to a button or web control anywhere in this
    // script...
}
```

繰り返しになります。 主な目標の1つは、 テストが **UIの問題ではなく、手元の問題** に対処できるAPIを作成することです。 UIはユーザーにとって二次的な関心事です。ユーザーはUIを気にせず、ただ仕事をやりたいだけです。 テストスクリプトは、ユーザーがやりたいことと知りたいことの長々としたリストのように読む必要があります。 テストでは、UIがどのようにそれを実行するように要求するかについて、気にするべきではありません。

----
url: https://www.selenium.dev/ja/documentation/webdriver/actions_api/wheel/
----

```java
        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L17-L20)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L11-L14)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L11-L14)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L16-L19)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L18-L21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L29-L33)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L22-L26)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L31-L35)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L22-L26)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L26-L31)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L30-L34)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L42-L46)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L35-L39)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L46-L53)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L34-L38)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L40-L44)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L43-L47)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L57-L61)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L50-L54)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L66-L75)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L48-L52)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L57-L61)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L59-L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

```java
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/actions_api/WheelTest.java#L73-L76)

##### /examples/java/src/test/java/dev/selenium/actions\_api/WheelTest.java

```java
package dev.selenium.actions_api;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.interactions.Actions;
import org.openqa.selenium.interactions.WheelInput;

public class WheelTest extends BaseChromeTest {
    @Test
    public void shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        new Actions(driver)
                .scrollToElement(iframe)
                .perform();

        Assertions.assertTrue(inViewport(iframe));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        int deltaY = footer.getRect().y;
        new Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform();

        Assertions.assertTrue(inViewport(footer));
    }

    @Test
    public void shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html");

        WebElement footer = driver.findElement(By.tagName("footer"));
        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    @Test
    public void shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html");

        WheelInput.ScrollOrigin scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10);
        new Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform();

        WebElement iframe = driver.findElement(By.tagName("iframe"));
        driver.switchTo().frame(iframe);
        WebElement checkbox = driver.findElement(By.name("scroll_checkbox"));
        Assertions.assertTrue(inViewport(checkbox));
    }

    private boolean inViewport(WebElement element) {

        String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                        + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                        + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                        + "window.pageYOffset&&t+o>window.pageXOffset";

        return (boolean) ((JavascriptExecutor) driver).executeScript(script, element);
    }
}
```

```py
    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/actions_api/test_wheel.py#L66-L70)

##### /examples/python/tests/actions\_api/test\_wheel.py

```py
from time import sleep

from selenium.webdriver import ActionChains
from selenium.webdriver.common.by import By
from selenium.webdriver.common.actions.wheel_input import ScrollOrigin


def test_can_scroll_to_element(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    ActionChains(driver)\
        .scroll_to_element(iframe)\
        .perform()

    assert _in_viewport(driver, iframe)


def test_can_scroll_from_viewport_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    delta_y = footer.rect['y']
    ActionChains(driver)\
        .scroll_by_amount(0, delta_y)\
        .perform()

    sleep(0.5)
    assert _in_viewport(driver, footer)


def test_can_scroll_from_element_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    iframe = driver.find_element(By.TAG_NAME, "iframe")
    scroll_origin = ScrollOrigin.from_element(iframe)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_element_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    footer = driver.find_element(By.TAG_NAME, "footer")
    scroll_origin = ScrollOrigin.from_element(footer, 0, -50)
    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def test_can_scroll_from_viewport_with_offset_by_amount(driver):
    driver.get("https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    scroll_origin = ScrollOrigin.from_viewport(10, 10)

    ActionChains(driver)\
        .scroll_from_origin(scroll_origin, 0, 200)\
        .perform()

    sleep(0.5)
    iframe = driver.find_element(By.TAG_NAME, "iframe")
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(By.NAME, "scroll_checkbox")
    assert _in_viewport(driver, checkbox)


def _in_viewport(driver, element):
    script = (
        "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
        "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
        "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
        "window.pageYOffset&&t+o>window.pageXOffset"
    )
    return driver.execute_script(script, element)
```

```cs
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs#L89-L97)

##### /examples/dotnet/SeleniumDocs/ActionsAPI/WheelTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Interactions;

namespace SeleniumDocs.ActionsAPI
{
    [TestClass]
    public class WheelTest : BaseChromeTest
    {
        [TestMethod]
        public void ShouldAllowScrollingToAnElement()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            new Actions(driver)
                .ScrollToElement(iframe)
                .Perform();

            Assert.IsTrue(IsInViewport(iframe));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            int deltaY = footer.Location.Y;
            new Actions(driver)
                .ScrollByAmount(0, deltaY)
                .Perform();

            Assert.IsTrue(IsInViewport(footer));
        }

        [TestMethod]
        public void ShouldScrollFromElementByGivenAmount()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            WheelInputDevice.ScrollOrigin scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = iframe
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromElementByGivenAmountWithOffset()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html";

            IWebElement footer = driver.FindElement(By.TagName("footer"));
            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Element = footer,
                XOffset = 0,
                YOffset = -50
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        [TestMethod]
        public void ShouldAllowScrollingFromViewportByGivenAmountFromOrigin()
        {
            driver.Url =
                "https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html";

            var scrollOrigin = new WheelInputDevice.ScrollOrigin
            {
                Viewport = true,
                XOffset = 10,
                YOffset = 10
            };
            new Actions(driver)
                .ScrollFromOrigin(scrollOrigin, 0, 200)
                .Perform();

            IWebElement iframe = driver.FindElement(By.TagName("iframe"));
            driver.SwitchTo().Frame(iframe);
            IWebElement checkbox = driver.FindElement(By.Name("scroll_checkbox"));
            Assert.IsTrue(IsInViewport(checkbox));
        }

        private bool IsInViewport(IWebElement element)
        {
            String script =
                "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\n"
                + "e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\n"
                + "return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\n"
                + "window.pageYOffset&&t+o>window.pageXOffset";
            IJavaScriptExecutor javascriptDriver = this.driver as IJavaScriptExecutor;

            return (bool)javascriptDriver.ExecuteScript(script, element);
        }
    }
}
```

```rb
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/actions_api/wheel_spec.rb#L63-L66)

##### /examples/ruby/spec/actions\_api/wheel\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Scrolling' do
  let(:driver) { start_session }

  it 'scrolls to element' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    driver.action
          .scroll_to(iframe)
          .perform

    expect(in_viewport?(iframe)).to eq true
  end

  it 'scrolls by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    delta_y = footer.rect.y
    driver.action
          .scroll_by(0, delta_y)
          .perform

    expect(in_viewport?(footer)).to eq true
  end

  it 'scrolls from element by given amount' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    iframe = driver.find_element(tag_name: 'iframe')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(iframe)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls from element by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html')

    footer = driver.find_element(tag_name: 'footer')
    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.element(footer, 0, -50)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end

  it 'scrolls by given amount with offset' do
    driver.get('https://selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html')

    scroll_origin = Selenium::WebDriver::WheelActions::ScrollOrigin.viewport(10, 10)
    driver.action
          .scroll_from(scroll_origin, 0, 200)
          .perform

    iframe = driver.find_element(tag_name: 'iframe')
    driver.switch_to.frame(iframe)
    checkbox = driver.find_element(name: 'scroll_checkbox')
    expect(in_viewport?(checkbox)).to eq true
  end
end

def in_viewport?(element)
  in_viewport = <<~IN_VIEWPORT
    for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;
    e.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;
    return f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>
    window.pageYOffset&&t+o>window.pageXOffset
  IN_VIEWPORT

  driver.execute_script(in_viewport, element)
end
```

```js
    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/actionsApi/wheelTest.spec.js#L75-L77)

##### /examples/javascript/test/actionsApi/wheelTest.spec.js

```js
const { By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert')

describe('Actions API - Wheel Tests', function () {
  let driver

  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  })

  after(async() => await driver.quit())

  it('Scroll to element', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    await driver.actions()
      .scroll(0, 0, 0, 0, iframe)
      .perform()
    assert.ok(await inViewport(iframe))
  })

  it('Scroll by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const footer = await driver.findElement(By.css("footer"))
    const deltaY = (await footer.getRect()).y

    await driver.actions()
      .scroll(0, 0, 0, deltaY)
      .perform()

    await driver.sleep(500)
    assert.ok(await inViewport(footer))
  })

  it('Scroll from an element by a given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(0, 0, 0, 200, iframe)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an element with an offset', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

    const iframe = await driver.findElement(By.css("iframe"))
    const footer = await driver.findElement(By.css("footer"))

    await driver.actions()
      .scroll(0, -50, 0, 200, footer)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  it('Scroll from an offset of origin (element) by given amount', async function () {
    await driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

    const iframe = await driver.findElement(By.css("iframe"))

    await driver.actions()
      .scroll(10, 10, 0, 200)
      .perform()

    await driver.sleep(500)

    await driver.switchTo().frame(iframe)
    const checkbox = await driver.findElement(By.name('scroll_checkbox'))
    assert.ok(await inViewport(checkbox))
  })

  function inViewport(element) {
    return driver.executeScript("for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset", element)
  }
})
```

```kt
        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/actions_api/WheelTest.kt#L75-L78)

##### /examples/kotlin/src/test/kotlin/dev/selenium/actions\_api/WheelTest.kt

```kt
package dev.selenium.actions_api

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.JavascriptExecutor
import org.openqa.selenium.WebElement
import org.openqa.selenium.interactions.Actions
import org.openqa.selenium.interactions.WheelInput

class WheelTest : BaseTest() {
    
    @Test
    fun shouldScrollToElement() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        Actions(driver)
                .scrollToElement(iframe)
                .perform()

        Assertions.assertTrue(inViewport(iframe))
    }
    
    @Test
    fun shouldScrollFromViewportByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val deltaY = footer.getRect().y
        Actions(driver)
                .scrollByAmount(0, deltaY)
                .perform()

        Assertions.assertTrue(inViewport(footer))
    }   
    
    @Test
    fun shouldScrollFromElementByGivenAmount() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val iframe = driver.findElement(By.tagName("iframe"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(iframe)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    @Test
    fun shouldScrollFromElementByGivenAmountWithOffset() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame_out_of_view.html")

        val footer = driver.findElement(By.tagName("footer"))
        val scrollOrigin = WheelInput.ScrollOrigin.fromElement(footer, 0, -50)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin,0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))
        Assertions.assertTrue(inViewport(checkbox))
    }    
    
    @Test
    fun shouldScrollFromViewportByGivenAmountFromOrigin() {
        driver.get("https://www.selenium.dev/selenium/web/scrolling_tests/frame_with_nested_scrolling_frame.html")

        val scrollOrigin = WheelInput.ScrollOrigin.fromViewport(10, 10)
        Actions(driver)
                .scrollFromOrigin(scrollOrigin, 0, 200)
                .perform()

        val iframe = driver.findElement(By.tagName("iframe"))
        driver.switchTo().frame(iframe)
        val checkbox = driver.findElement(By.name("scroll_checkbox"))

        Assertions.assertTrue(inViewport(checkbox))
    }
    
    fun inViewport(element: WebElement): Boolean {
        val script = "for(var e=arguments[0],f=e.offsetTop,t=e.offsetLeft,o=e.offsetWidth,n=e.offsetHeight;\ne.offsetParent;)f+=(e=e.offsetParent).offsetTop,t+=e.offsetLeft;\nreturn f<window.pageYOffset+window.innerHeight&&t<window.pageXOffset+window.innerWidth&&f+n>\nwindow.pageYOffset&&t+o>window.pageXOffset"
        return (driver as JavascriptExecutor).executeScript(script, element) as Boolean 
    }
}
```

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/bidi/script/
----

# WebDriver BiDi Script Features

These features are related to scripts, and are made available via a “script” namespace.

The implementation of these features is being tracked here: [#13992](https://github.com/SeleniumHQ/selenium/issues/13992)

Remember that to use WebDriver BiDi, you must enable it in Options. For more details, see [Enabling BiDi](https://www.selenium.dev/pt-br/documentation/webdriver/bidi/)

## Script Pinning

## Execute Script

## DOM Mutation Handlers

Última modificação October 18, 2024: [add missing pages for BiDi script (71f0aa453d2)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/71f0aa453d297d3ed90300d73ba2a800270d478a)

----
url: https://www.selenium.dev/_print/documentation/overview/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/overview/).

# Selenium Overview

Is Selenium for you? See an overview of the different project components.

* 1: [Selenium components](#pg-9fc83626653ca2a7201cf9d4d67e276e)
* 2: [A deeper look at Selenium](#pg-8ed9bf4bcfc6f829d20d44ad960f1d08)

# 1 - Selenium components

# 2 - A deeper look at Selenium

----
url: https://www.selenium.dev/pt-br/_print/documentation/webdriver/browsers/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/webdriver/browsers/).

# Navegadores suportados

* 1: [Funcionalidade específica do Chrome](#pg-c5aa7dabd73cc823a1fed2b2bd71ec1c)
* 2: [Funcionalidade específica do Edge](#pg-bd45be4ec5d64dfae445d4ec144ab23d)
* 3: [Funcionalidade específica do Firefox](#pg-8e7ca87c4ab14b8c6b640564ce02fd2e)
* 4: [Funcionalidade específica do IE](#pg-9f33c9f013a002bbc32bab35ef2bb7de)
* 5: [Funcionalidade específica do Safari](#pg-e204e4df9fcb83fd01265c7d2ec25f68)

Cada navegador tem capacidades e características únicas.

# 1 - Funcionalidade específica do Chrome

```java
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L36-L37)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L9-L10)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L30-L31)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L51-L55)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_argument("--start-maximized")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L18)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L39)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.args << '--start-maximized'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L17)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L9-L12)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L53)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.binary_location = chrome_bin
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L29)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L49)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.add_argument("--user-data-dir=#{user_data_dir}")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L25)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L41-L44)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
  @DisabledOnOs(OS.WINDOWS)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L64)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_extension(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L40)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L73-L84)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
    it 'add extensions' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L34)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L62-L66)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```py
    options.add_experimental_option("detach", True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L51)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

**Note**: This is already the default behavior in .NET.

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L45)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L29-L32)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L78)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L62)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L82)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L53)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/chromeSpecificCaps.spec.js#L19-L22)

##### /examples/javascript/test/browser/chromeSpecificCaps.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const { Browser, Builder } = require("selenium-webdriver");
const options = new Chrome.Options();



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  xit('Start browser from specified location ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setChromeBinaryPath(`Path to chrome binary`))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Basic Chrome test', async function () {
    const Options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    const options = new Chrome.Options();
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L100-L101)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY`\
Property value: String representing path to log file

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L71)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L86)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service = Selenium::WebDriver::Service.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L67)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L114-L115)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L82)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

`$stdout` and `$stderr` are both valid values

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service = Selenium::WebDriver::Service.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L76)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L129-L130)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY`\
Property value: String representation of `ChromiumDriverLogLevel` enum

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L93)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L87)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L147-L148)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows toggling these features by System Property:\
Property keys: `ChromeDriverService.CHROME_DRIVER_APPEND_LOG_PROPERTY` and `ChromeDriverService.CHROME_DRIVER_READABLE_TIMESTAMP`\
Property value: `"true"` or `"false"`

```py
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L104)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service = Selenium::WebDriver::Service.chrome(args: args)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L97-L98)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L166-L167)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows disabling build checks by System Property:\
Property key: `ChromeDriverService.CHROME_DRIVER_DISABLE_BUILD_CHECK`\
Property value: `"true"` or `"false"`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L115)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            service.DisableBuildCheck = true;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs#L155)

##### /examples/dotnet/SeleniumDocs/Browsers/ChromeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.BiDi;
using OpenQA.Selenium.BiDi.WebExtension;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Chromium;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class ChromeTest
    {
        private ChromeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver?.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new ChromeOptions();
            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new ChromeOptions();

            options.AddArgument("--start-maximized");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            string userDataDir = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName());
            Directory.CreateDirectory(userDataDir);
            var options = new ChromeOptions();
            options.AddArgument($"--user-data-dir={userDataDir}");
            options.AddArgument("--no-sandbox");
            options.AddArgument("--disable-dev-shm-usage");

            options.BinaryLocation = GetChromeLocation();

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public async Task InstallExtension()
        {
            if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
            {
                Assert.Inconclusive("Extension install via BiDi is not supported on Windows");
                return;
            }

            var options = new ChromeOptions();
            options.UseWebSocketUrl = true;
            options.AddArgument("--remote-debugging-pipe");
            options.AddArgument("--enable-unsafe-extension-debugging");

            driver = new ChromeDriver(options);

            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionDir = Path.GetFullPath(Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example"));

            var bidi = await driver.AsBiDiAsync();
            await bidi.WebExtension.InstallAsync(new ExtensionPath(extensionDir));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new ChromeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new ChromeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = ChromeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting ChromeDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new ChromeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new ChromeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }

        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetChromeLocation()
        {
            var options = new ChromeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L108)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L230-L235)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L170-L174)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L119-L124)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L204-L210)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L129-L135)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
    it 'gets and sets network conditions' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L129)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L247)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    logs = driver.get_log("browser")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L186)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver = Selenium::WebDriver.for :chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L141)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    options.setBrowserVersion("stable");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java#L189)

##### /examples/java/src/test/java/dev/selenium/browsers/ChromeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.webextension.ExtensionPath;
import org.openqa.selenium.bidi.webextension.InstallExtensionParameters;
import org.openqa.selenium.bidi.webextension.WebExtension;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.logging.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class ChromeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY);
    System.clearProperty(ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new ChromeDriver(options);
  }

  @Test
  public void arguments() {
    ChromeOptions options = getDefaultChromeOptions();

    options.addArguments("--start-maximized");

    driver = new ChromeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setBinary(getChromeLocation());

    driver = new ChromeDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void extensionOptions() {
    ChromeOptions options = getDefaultChromeOptions();
    options.enableBiDi();
    options.addArguments("--remote-debugging-pipe");
    options.addArguments("--enable-unsafe-extension-debugging");
    driver = new ChromeDriver(options);

    Path path = Paths.get("src/test/resources/extensions/selenium-example");
    WebExtension extension = new WebExtension(driver);
    ExtensionPath extensionPath = new ExtensionPath(path.toString());
    InstallExtensionParameters parameters = new InstallExtensionParameters(extensionPath);
    extension.install(parameters);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    ChromeOptions options = getDefaultChromeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new ChromeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    ChromeOptions options = getDefaultChromeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(ChromeOptions.LOGGING_PREFS, logPrefs);

    driver = new ChromeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogFile(logLocation).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogOutput(System.out).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting ChromeDriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withLogLevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.DEBUG.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        ChromeDriverService.CHROME_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    ChromeDriverService service =
        new ChromeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new ChromeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getChromeLocation() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermission() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new ChromeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((ChromeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((ChromeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
        () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
        () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
        () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
        () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((ChromeDriver) driver).deleteNetworkConditions();
    driver.quit();
  }

  @Test
  public void castFeatures() {
    ChromeDriver driver = new ChromeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    ChromeDriver driver = new ChromeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    driver.set_permissions('camera', 'denied')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_chrome.py#L149)

##### /examples/python/tests/browsers/test\_chrome.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_chrome_options()
    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_args():
    options = get_default_chrome_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(chrome_bin):
    options = get_default_chrome_options()

    options.binary_location = chrome_bin

    driver = webdriver.Chrome(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_chrome_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_chrome_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_chrome_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Chrome(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.ChromeService(log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting ChromeDriver" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.ChromeService(log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert "Starting ChromeDriver" in out

    driver.quit()


def test_log_level(capfd):
    service = webdriver.ChromeService(service_args=['--log-level=DEBUG'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    out, err = capfd.readouterr()
    assert '[DEBUG]' in err

    driver.quit()


def test_log_features(log_path):
    service = webdriver.ChromeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Chrome(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(capfd):
    service = webdriver.ChromeService(service_args=['--disable-build-check'], log_output=subprocess.STDOUT)

    driver = webdriver.Chrome(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    out, err = capfd.readouterr()
    assert expected in err

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Chrome()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Chrome()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Chrome()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Chrome()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/chrome_spec.rb#L149-L150)

##### /examples/ruby/spec/browsers/chrome\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.chrome
      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.chrome

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'sets location of binary' do
      user_data_dir = Dir.mktmpdir('chrome-profile-')
      options = Selenium::WebDriver::Options.chrome
      options.add_argument("--user-data-dir=#{user_data_dir}")
      options.add_argument('--no-sandbox')
      options.add_argument('--disable-dev-shm-usage')

      options.binary = chrome_location

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.chrome

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :chrome, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.chrome

      options.detach = true

      @driver = Selenium::WebDriver.for :chrome, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.chrome

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :chrome, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('chromedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.chrome

      service.log = file_name

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).first).to include('Starting ChromeDriver')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.chrome

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :chrome, service: service
      }.to output(/Starting ChromeDriver/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.chrome
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :chrome, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.chrome(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :chrome, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.chrome log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :chrome, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :chrome
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :chrome
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### DevTools

Veja a secção \[Chrome DevTools] para mais informação em como usar Chrome DevTools

# 2 - Funcionalidade específica do Edge

```java

  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L38-L39)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    options = get_default_edge_options()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L9-L10)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        {
            var options = new EdgeOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L30-L31)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
    let options = new edge.Options();
    driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/openEdgeTest.spec.js#L11-L15)

##### /examples/javascript/test/getting\_started/openEdgeTest.spec.js

```js
const {Browser, Builder} = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');


describe('Open Edge', function () {
  let driver;



  before(async function () {
    let options = new edge.Options();
    driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options)
      .build();
  });

  after(async () => await driver.quit());

  it('Basic Edge test', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
  public void arguments() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L46)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L18)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L39)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.args << '--start-maximized'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L17)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.addArguments('--headless=new'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L12)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```java
  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L54)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L29)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L49)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.binary = edge_location
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L25)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L66)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L40)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L61)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.add_extension(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L34)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L55)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L51)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

**Note**: This is already the default behavior in .NET.

```rb
      options.detach = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L45)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.detachDriver(true))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L32)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```java
  public void excludeSwitches() {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L79)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L62)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L76)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

```rb
      options.exclude_switches << 'disable-popup-blocking'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L53)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```js
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/edgeSpecificCaps.spec.js#L22)

##### /examples/javascript/test/browser/edgeSpecificCaps.spec.js

```js
const {Browser, By, Builder } = require('selenium-webdriver');
const edge = require('selenium-webdriver/edge');
const options = new edge.Options();
const assert = require("assert");



describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addArguments('--headless=new'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('exclude switches', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.excludeSwitches('enable-automation'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Keep browser open - set detach to true ', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.detachDriver(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // As tests runs in ci, quitting the driver instance to avoid any failures
    await driver.quit();
  });

  it('Basic edge test', async function () {
    const Options = new edge.Options();
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(Options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Add Extension', async function () {
    let driver = new Builder()
      .forBrowser(Browser.EDGE)
      .setEdgeOptions(options.addExtensions(['./test/resources/extensions/webextensions-selenium-example.crx']))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    let injected = await driver.findElement(By.id('webextensions-selenium-example'));
    assert.equal(await injected.getText(), `Content injected by webextensions-selenium-example`)
    await driver.quit();
  });
});
```

```java
  @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L101)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY`\
Property value: String representing path to log file

```py
def test_log_to_file(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L71)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L86)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L67)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    File logLocation = getTempFile("logsToConsole", ".log");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L114)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
def test_log_to_stdout(capfd):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L82)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

`$stdout` and `$stderr` are both valid values

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L76)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L127-L128)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY`\
Property value: String representation of `ChromiumDriverLogLevel` enum

```py
def test_log_level(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L93)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '--log-level=DEBUG'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L87)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L143-L144)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows toggling these features by System Property:\
Property keys: `EdgeDriverService.EDGE_DRIVER_APPEND_LOG_PROPERTY` and `EdgeDriverService.EDGE_DRIVER_READABLE_TIMESTAMP`\
Property value: `"true"` or `"false"`

```py
def test_log_features(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L104)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << '--append-log'
      service.args << '--readable-timestamp'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L97-L98)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L161-L162)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

**Note**: Java also allows disabling build checks by System Property:\
Property key: `EdgeDriverService.EDGE_DRIVER_DISABLE_BUILD_CHECK`\
Property value: `"true"` or `"false"`

```py
def test_build_checks(log_path):
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L115)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs#L155)

##### /examples/dotnet/SeleniumDocs/Browsers/EdgeTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chromium;
using OpenQA.Selenium.Edge;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class EdgeTest
    {
        private EdgeDriver driver;
        private string _logLocation;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new EdgeOptions();
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new EdgeOptions();

            options.AddArgument("--start-maximized");
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void SetBrowserLocation()
        {
            var options = new EdgeOptions();

            options.BinaryLocation = GetEdgeLocation();
    
            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void InstallExtension()
        {
            var options = new EdgeOptions();
            var baseDir = AppDomain.CurrentDomain.BaseDirectory;
            var extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.crx");

            options.AddExtension(extensionFilePath);

            driver = new EdgeDriver(options);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";

            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void ExcludeSwitch()
        {
            var options = new EdgeOptions();

            options.AddExcludedArgument("disable-popup-blocking");

            driver = new EdgeDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = EdgeDriverService.CreateDefaultService();

            service.LogPath = GetLogLocation();

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Starting Microsoft Edge WebDriver")));
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            service.LogLevel = ChromiumDriverLogLevel.Debug; 

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("[DEBUG]:")));
        }

        [TestMethod]
        public void ConfigureDriverLogs()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.EnableAppendLog = true;
            service.ReadableTimestamp = true;

            driver = new EdgeDriver(service);

            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            var regex = new Regex(@"\[\d\d-\d\d-\d\d\d\d \d\d:\d\d:\d\d\.\d+\]");
            Assert.IsNotNull(lines.FirstOrDefault(line => regex.Matches(line).Count > 0));
        }

        [TestMethod]
        public void DisableBuildCheck()
        {
            var service = EdgeDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.EnableVerboseLogging = true;

            service.DisableBuildCheck = true;

            driver = new EdgeDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains(expected)));
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private static string GetEdgeLocation()
        {
            var options = new EdgeOptions
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << '--disable-build-check'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L108)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L225-L230)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L170-L174)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L119-L123)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L198-L204)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L129-L135)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L129)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    consoleLogButton.click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L242)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L186)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      sleep 1
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L141)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

```java
    EdgeDriver driver = new EdgeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java#L184)

##### /examples/java/src/test/java/dev/selenium/browsers/EdgeTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.regex.Pattern;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chromium.ChromiumDriverLogLevel;
import org.openqa.selenium.chromium.ChromiumNetworkConditions;
import org.openqa.selenium.edge.EdgeDriver;
import org.openqa.selenium.edge.EdgeDriverService;
import org.openqa.selenium.edge.EdgeOptions;
import org.openqa.selenium.logging.LogEntries;
import org.openqa.selenium.logging.LogEntry;
import org.openqa.selenium.logging.LogType;
import org.openqa.selenium.logging.LoggingPreferences;
import org.openqa.selenium.remote.service.DriverFinder;



public class EdgeTest extends BaseTest {
  @AfterEach
  public void clearProperties() {
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY);
    System.clearProperty(EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY);
  }

  @Test
  public void basicOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    driver = new EdgeDriver(options);
  }

  @Test
  public void arguments() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.addArguments("--start-maximized");

    driver = new EdgeDriver(options);
  }

  @Test
  public void setBrowserLocation() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setBinary(getEdgeLocation());

    driver = new EdgeDriver(options);
  }

  @Test
  public void extensionOptions() {
    EdgeOptions options = getDefaultEdgeOptions();
    Path path = Paths.get("src/test/resources/extensions/webextensions-selenium-example.crx");
    File extensionFilePath = new File(path.toUri());

    options.addExtensions(extensionFilePath);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  @Test
  public void excludeSwitches() {
    EdgeOptions options = getDefaultEdgeOptions();

    options.setExperimentalOption("excludeSwitches", List.of("disable-popup-blocking"));

    driver = new EdgeDriver(options);
  }

  @Test
  public void loggingPreferences() {
    EdgeOptions options = getDefaultEdgeOptions();
    LoggingPreferences logPrefs = new LoggingPreferences();
    logPrefs.enable(LogType.PERFORMANCE, Level.ALL);
    options.setCapability(EdgeOptions.LOGGING_PREFS, logPrefs);

    driver = new EdgeDriver(options);
    driver.get("https://www.selenium.dev");

    LogEntries logEntries = driver.manage().logs().get(LogType.PERFORMANCE);
    Assertions.assertFalse(logEntries.getAll().isEmpty());
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    EdgeDriverService service = new EdgeDriverService.Builder().withLogFile(logLocation).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting Microsoft Edge WebDriver"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    EdgeDriverService service = new EdgeDriverService.Builder().withLogOutput(System.out).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Starting msedgedriver"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withLoglevel(ChromiumDriverLogLevel.DEBUG).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("[DEBUG]:"));
  }

  @Test
  public void configureDriverLogs() throws IOException {
    File logLocation = getTempFile("configureDriverLogs", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY, ChromiumDriverLogLevel.DEBUG.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withAppendLog(true).withReadableTimestamp(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Pattern pattern = Pattern.compile("\\[\\d\\d-\\d\\d-\\d\\d\\d\\d", Pattern.CASE_INSENSITIVE);
    Assertions.assertTrue(pattern.matcher(fileContent).find());
  }

  @Test
  public void disableBuildChecks() throws IOException {
    File logLocation = getTempFile("disableBuildChecks", ".log");
    System.setProperty(EdgeDriverService.EDGE_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        EdgeDriverService.EDGE_DRIVER_LOG_LEVEL_PROPERTY,
        ChromiumDriverLogLevel.WARNING.toString());

    EdgeDriverService service =
        new EdgeDriverService.Builder().withBuildCheckDisabled(true).build();

    driver = new EdgeDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    String expected =
        "[WARNING]: You are using an unsupported command-line switch: --disable-build-check";
    Assertions.assertTrue(fileContent.contains(expected));
  }

  private File getEdgeLocation() {
    EdgeOptions options = getDefaultEdgeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(EdgeDriverService.createDefaultService(), options);
    return new File(finder.getBrowserPath());
  }

  @Test
  public void setPermissions() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev");

    driver.setPermission("camera", "denied");

    // Verify the permission state is 'denied'
    String script = "return navigator.permissions.query({ name: 'camera' })" +
            "    .then(permissionStatus => permissionStatus.state);";
    String permissionState = (String) driver.executeScript(script);

    Assertions.assertEquals("denied", permissionState);
    driver.quit();
  }

  @Test
  public void setNetworkConditions() {
    driver = new EdgeDriver();

    ChromiumNetworkConditions networkConditions = new ChromiumNetworkConditions();
    networkConditions.setOffline(false);
    networkConditions.setLatency(java.time.Duration.ofMillis(20)); // 20 ms of latency
    networkConditions.setDownloadThroughput(2000 * 1024 / 8); // 2000 kbps
    networkConditions.setUploadThroughput(2000 * 1024 / 8);   // 2000 kbps

    ((EdgeDriver) driver).setNetworkConditions(networkConditions);

    driver.get("https://www.selenium.dev");

    // Assert the network conditions are set as expected
    ChromiumNetworkConditions actualConditions = ((EdgeDriver) driver).getNetworkConditions();
    Assertions.assertAll(
            () -> Assertions.assertEquals(networkConditions.getOffline(), actualConditions.getOffline()),
            () -> Assertions.assertEquals(networkConditions.getLatency(), actualConditions.getLatency()),
            () -> Assertions.assertEquals(networkConditions.getDownloadThroughput(), actualConditions.getDownloadThroughput()),
            () -> Assertions.assertEquals(networkConditions.getUploadThroughput(), actualConditions.getUploadThroughput())
    );
    ((EdgeDriver) driver).deleteNetworkConditions();
  }

  @Test
  public void castFeatures() {
    EdgeDriver driver = new EdgeDriver();

    List<Map<String, String>> sinks = driver.getCastSinks();
    if (!sinks.isEmpty()) {
      String sinkName = sinks.get(0).get("name");
      driver.startTabMirroring(sinkName);
      driver.stopCasting(sinkName);
    }

    driver.quit();
  }

  @Test
  public void getBrowserLogs() {
    EdgeDriver driver = new EdgeDriver();
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    WebElement consoleLogButton = driver.findElement(By.id("consoleError"));
    consoleLogButton.click();

    LogEntries logs = driver.manage().logs().get(LogType.BROWSER);

    // Assert that at least one log contains the expected message
    boolean logFound = false;
    for (LogEntry log : logs) {
      if (log.getMessage().contains("I am console error")) {
        logFound = true;
        break;
      }
    }

    Assertions.assertTrue(logFound, "No matching log message found.");
    driver.quit();
  }
}
```

```py
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_edge.py#L149)

##### /examples/python/tests/browsers/test\_edge.py

```py
import os
import re
import subprocess
import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By

def test_basic_options():
    options = get_default_edge_options()

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_args():
    options = get_default_edge_options()

    options.add_argument("--start-maximized")

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_set_browser_location(edge_bin):
    options = get_default_edge_options()

    options.binary_location = edge_bin

    driver = webdriver.Edge(options=options)

    driver.quit()


def test_add_extension():
    options = get_default_edge_options()
    extension_file_path = os.path.abspath("tests/extensions/webextensions-selenium-example.crx")

    options.add_extension(extension_file_path)

    driver = webdriver.Edge(options=options)
    driver.get("https://www.selenium.dev/selenium/web/blank.html")

    driver.quit()


def test_keep_browser_open():
    options = get_default_edge_options()

    options.add_experimental_option("detach", True)

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_exclude_switches():
    options = get_default_edge_options()

    options.add_experimental_option('excludeSwitches', ['disable-popup-blocking'])

    driver = webdriver.Edge(options=options)
    driver.get('http://selenium.dev')

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.EdgeService(log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as fp:
        assert "Starting" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.EdgeService(log_output=subprocess.STDOUT)

    driver = webdriver.Edge(service=service)

    out, err = capfd.readouterr()
    assert "Starting" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.EdgeService(service_args=['--log-level=DEBUG'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert '[DEBUG]' in f.read()

    driver.quit()


def test_log_features(log_path):
    service = webdriver.EdgeService(service_args=['--append-log', '--readable-timestamp'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    with open(log_path, 'r') as f:
        assert re.match(r"\[\d\d-\d\d-\d\d\d\d", f.read())

    driver.quit()


def test_build_checks(log_path):
    service = webdriver.EdgeService(service_args=['--disable-build-check'], log_output=log_path)

    driver = webdriver.Edge(service=service)

    expected = "[WARNING]: You are using an unsupported command-line switch: --disable-build-check"
    with open(log_path, 'r') as f:
        assert expected in f.read()

    driver.quit()


def test_set_network_conditions():
    driver = webdriver.Edge()

    network_conditions = {
        "offline": False,
        "latency": 20,  # 20 ms of latency
        "download_throughput": 2000 * 1024 / 8,  # 2000 kbps
        "upload_throughput": 2000 * 1024 / 8,    # 2000 kbps
    }
    driver.set_network_conditions(**network_conditions)

    driver.get("https://www.selenium.dev")

    # check whether the network conditions are set
    assert driver.get_network_conditions() == network_conditions

    driver.quit()


def test_set_permissions():
    driver = webdriver.Edge()
    driver.get('https://www.selenium.dev')

    driver.set_permissions('camera', 'denied')

    assert get_permission_state(driver, 'camera') == 'denied'
    driver.quit()


def get_permission_state(driver, name):
    """Helper function to query the permission state."""
    script = """
    const callback = arguments[arguments.length - 1];
    navigator.permissions.query({name: arguments[0]}).then(permissionStatus => {
        callback(permissionStatus.state);
    });
    """
    return driver.execute_async_script(script, name)


def test_cast_features():
    driver = webdriver.Edge()

    try:
        sinks = driver.get_sinks()
        if sinks:
            sink_name = sinks[0]['name']
            driver.start_tab_mirroring(sink_name)
            driver.stop_casting(sink_name)
        else:
            pytest.skip("No available Cast sinks to test with.")
    finally:
        driver.quit()


def test_get_browser_logs():
    driver = webdriver.Edge()
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html")
    driver.find_element(By.ID, "consoleError").click()

    logs = driver.get_log("browser")

    # Assert that at least one log contains the expected message
    assert any("I am console error" in log['message'] for log in logs), "No matching log message found."
    driver.quit()


def get_default_edge_options():
    options = webdriver.EdgeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/edge_spec.rb#L149-L150)

##### /examples/ruby/spec/browsers/edge\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Edge' do
  describe 'Options' do
    let(:edge_location) { driver_finder && ENV.fetch('EDGE_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.edge
      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.edge

      options.args << '--start-maximized'

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.edge

      options.binary = edge_location

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'add extensions' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.crx', __dir__)
      options = Selenium::WebDriver::Options.edge

      options.add_extension(extension_file_path)

      @driver = Selenium::WebDriver.for :edge, options: options
      @driver.get('https://www.selenium.dev/selenium/web/blank.html')
      injected = @driver.find_element(:id, 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'keeps browser open' do
      options = Selenium::WebDriver::Options.edge

      options.detach = true

      @driver = Selenium::WebDriver.for :edge, options: options
    end

    it 'excludes switches' do
      options = Selenium::WebDriver::Options.edge

      options.exclude_switches << 'disable-popup-blocking'

      @driver = Selenium::WebDriver.for :edge, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { File.expand_path('msedgedriver.log') }

    after { FileUtils.rm_f(file_name) }

    it 'logs to file' do
      service = Selenium::WebDriver::Service.edge

      service.log = file_name

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).first).to include('Starting')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.edge

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :edge, service: service
      }.to output(/Starting/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.edge
      service.log = file_name

      service.args << '--log-level=DEBUG'

      @driver = Selenium::WebDriver.for :edge, service: service
      expect(File.readlines(file_name).grep(/\[DEBUG\]:/).any?).to eq true
    end

    it 'sets log features' do
      args = ["--log-path=#{file_name}", '--verbose']
      service = Selenium::WebDriver::Service.edge(args: args)

      service.args << '--append-log'
      service.args << '--readable-timestamp'

      @driver = Selenium::WebDriver.for :edge, service: service

      expect(File.readlines(file_name).grep(/\[\d\d-\d\d-\d\d\d\d/).any?).to eq true
    end

    it 'disables build checks' do
      service = Selenium::WebDriver::Service.edge log: file_name, args: ['--verbose']

      service.args << '--disable-build-check'

      @driver = Selenium::WebDriver.for :edge, service: service
      warning = /\[WARNING\]: You are using an unsupported command-line switch: --disable-build-check/
      expect(File.readlines(file_name).grep(warning).any?).to eq true
    end
  end

  describe 'Special Features' do
    it 'casts' do
      @driver = Selenium::WebDriver.for :edge
      sinks = @driver.cast_sinks
      unless sinks.empty?
        device_name = sinks.first['name']
        @driver.start_cast_tab_mirroring(device_name)
        expect { @driver.stop_casting(device_name) }.not_to raise_exception
      end
    end

    it 'gets and sets network conditions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.network_conditions = {offline: false, latency: 100, throughput: 200}
      expect(@driver.network_conditions).to eq(
        'offline' => false,
        'latency' => 100,
        'download_throughput' => 200,
        'upload_throughput' => 200
      )
    end

    it 'gets the browser logs' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      sleep 1
      logs = @driver.logs.get(:browser)

      expect(logs.first.message).to include 'Failed to load resource'
    end

    it 'sets permissions' do
      @driver = Selenium::WebDriver.for :edge
      @driver.navigate.to 'https://www.selenium.dev/selenium/web/'
      @driver.add_permission('camera', 'denied')
      @driver.add_permissions('clipboard-read' => 'denied', 'clipboard-write' => 'prompt')
      expect(permission('camera')).to eq('denied')
      expect(permission('clipboard-read')).to eq('denied')
      expect(permission('clipboard-write')).to eq('prompt')
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.edge(browser_version: 'stable')
    service = Selenium::WebDriver::Service.edge
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['EDGEDRIVER_BIN'] = finder.driver_path
    ENV['EDGE_BIN'] = finder.browser_path
  end

  def permission(name)
    @driver.execute_async_script('callback = arguments[arguments.length - 1];' \
                                 'callback(navigator.permissions.query({name: arguments[0]}));', name)['state']
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

### DevTools

See the \[Chrome DevTools] section for more information about using DevTools in Edge

# 3 - Funcionalidade específica do Firefox

```java
    driver = new FirefoxDriver(options);
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L36-L37)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L10-L11)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
        public void BasicOptions()
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L34-L35)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/openFirefoxTest.spec.js#L10-L13)

##### /examples/javascript/test/getting\_started/openFirefoxTest.spec.js

```js
const {Browser, Builder} = require('selenium-webdriver');
const firefox = require('selenium-webdriver/firefox');


describe('Open Firefox', function () {
  let driver;

  before(async function () {
    let options = new firefox.Options();
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options)
      .build();
  });

  after(async () => await driver.quit());

  it('Basic Firefox test', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options.add_argument("-headless")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L19)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            var options = new FirefoxOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L43)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options.args << '-headless'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L17)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
      .setFirefoxOptions(options.addArguments('--headless'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L12)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L54)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options.binary_location = firefox_bin
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L28)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            var options = new FirefoxOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L53)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options.binary = firefox_location
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L25)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
    driver = new FirefoxDriver(options);
  }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L211-L216)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L160-L168)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```csharp
var options = new FirefoxOptions();
var profile = new FirefoxProfile();
options.Profile = profile;
var driver = new RemoteWebDriver(options);
  
```

```rb
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L139-L141)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```javascript
const { Builder } = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');

const options = new firefox.Options();
let profile = '/path to custom profile';
options.setProfile(profile);
const driver = new Builder()
    .forBrowser('firefox')
    .setFirefoxOptions(options)
    .build();
  
```

```kotlin
val options = FirefoxOptions()
options.profile = FirefoxProfile()
driver = RemoteWebDriver(options)
  
```

```java
        new GeckoDriverService.Builder().withLogFile(logLocation).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L62-L63)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY`\
Property value: String representing path to log file

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L36)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L43)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withLogOutput(System.out).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L76-L77)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L48)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L52)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L90-L91)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY`\
Property value: String representation of `FirefoxDriverLogLevel` enum

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L59)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args += %w[--log debug]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L63)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L106-L107)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_NO_TRUNCATE`\
Property value: `"true"` or `"false"`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L70)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '--log-no-truncate'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L72)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L118-L119)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_PROFILE_ROOT`\
Property value: String representing path to profile root directory

```py
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L81)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args += ['--profile-root', root_directory]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L81)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L133)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.install_addon(addon_path_xpi)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L94)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L137)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      driver.install_addon(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L95)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    let id = await driver.installAddon(xpiPath);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L25)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L148)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.uninstall_addon(id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L106)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```cs
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L152)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      driver.uninstall_addon(extension_id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L106)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    await driver.uninstallAddon(id);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L26)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L160)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.install_addon(addon_path_dir, temporary=True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L115)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```cs
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L165)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```rb
      driver.install_addon(extension_dir_path, true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L115)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    let id = await driver.installAddon(xpiPath, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L41)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L181)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.save_full_page_screenshot("full_page_screenshot.png")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L139)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L125)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
    // Verify the context is back to "content"
    Assertions.assertEquals(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L197-L198)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L151-L152)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      driver.context = 'content'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L132)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

**Note**: As of Firefox 138, geckodriver needs to be started with the argument `--allow-system-access` to switch the context to `CHROME`.

# 4 - Funcionalidade específica do IE

```java
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#38-L41)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

```py
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L11-L14)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L35-L38)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

```rb
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L17-L20)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#46-L47)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

```py
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L21-L22)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L44-L45)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L24-L25)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
let driver = await new Builder()
.forBrowser('internet explorer')
.setIEOptions(options)
.build();
```

```kotlin
<p><a href=/documentation/about/contributing/#moving-examples>
<span class="selenium-badge-code" data-bs-toggle="tooltip" data-bs-placement="right"
      title="One or more of these examples need to be implemented in the examples directory; click for details in the contribution guide">Move Code</span></a></p>


val options = InternetExplorerOptions()
val driver = InternetExplorerDriver(options)
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.waitForUploadDialogUpTo(Duration.ofSeconds(2));
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L28-L29)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.FileUploadDialogTimeout = TimeSpan.FromMilliseconds(2000);
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.file_upload_dialog_timeout = 2000
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L29)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().fileUploadDialogTimeout(2000);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.waitForUploadDialogUpTo(Duration.ofSeconds(2))
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.destructivelyEnsureCleanSession();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ensure_clean_session = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L38-L39)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.EnsureCleanSession = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ensure_clean_session = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L35)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().ensureCleanSession(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.destructivelyEnsureCleanSession()
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.ignoreZoomSettings();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L48-L49)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.IgnoreZoomLevel = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ignore_zoom_level = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L41)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().ignoreZoomSetting(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.ignoreZoomSettings()
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.introduceFlakinessByIgnoringSecurityDomains();
WebDriver driver = new RemoteWebDriver(options);
  
```

```py
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L58-L59)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
var options = new InternetExplorerOptions();
options.IntroduceInstabilityByIgnoringProtectedModeSettings = true;
var driver = new RemoteWebDriver(options);
  
```

```rb
      @options.ignore_protected_mode_settings = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L47)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options().introduceFlakinessByIgnoringProtectedModeSettings(true);
let driver = await Builder()
          .setIeOptions(options)
          .build(); 
  
```

```kotlin
val options = InternetExplorerOptions()
options.introduceFlakinessByIgnoringSecurityDomains()
val driver = RemoteWebDriver(options)
  
```

```java
InternetExplorerOptions options = new InternetExplorerOptions();
options.setCapability("silent", true);
WebDriver driver = new InternetExplorerDriver(options);
  
```

```py
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L68-L69)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
InternetExplorerOptions options = new InternetExplorerOptions();
options.AddAdditionalInternetExplorerOption("silent", true);
IWebDriver driver = new InternetExplorerDriver(options);
  
```

```rb
      @options.silent = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L53)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const {Builder,By, Capabilities} = require('selenium-webdriver');
let caps = Capabilities.ie();
caps.set('silent', true);

(async function example() {
    let driver = await new Builder()
        .forBrowser('internet explorer')
        .withCapabilities(caps)
        .build();
    try {
        await driver.get('http://www.google.com/ncr');
    }
    finally {
        await driver.quit();
    }
})();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.setCapability("silent", true)
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  
```

```java
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;

public class ieTest {
    public static void main(String[] args) {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.useCreateProcessApiToLaunchIe();
        options.addCommandSwitches("-k");
        InternetExplorerDriver driver = new InternetExplorerDriver(options);
        try {
            driver.get("https://google.com/ncr");
            Capabilities caps = driver.getCapabilities();
            System.out.println(caps);
        } finally {
            driver.quit();
        }
    }
}
  
```

```py
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L76-L79)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;

namespace ieTest {
 class Program {
  static void Main(string[] args) {
   InternetExplorerOptions options = new InternetExplorerOptions();
   options.ForceCreateProcessApi = true;
   options.BrowserCommandLineArguments = "-k";
   IWebDriver driver = new InternetExplorerDriver(options);
   driver.Url = "https://google.com/ncr";
  }
 }
}
  
```

```rb
      @options.add_argument('-k')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L58)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options();
options.addBrowserCommandSwitches('-k');
options.addBrowserCommandSwitches('-private');
options.forceCreateProcessApi(true);

driver = await env.builder()
          .setIeOptions(options)
          .build();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.useCreateProcessApiToLaunchIe()
    options.addCommandSwitches("-k")
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  
```

```java
import org.openqa.selenium.Capabilities;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerOptions;

public class ieTest {
    public static void main(String[] args) {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.useCreateProcessApiToLaunchIe();
        InternetExplorerDriver driver = new InternetExplorerDriver(options);
        try {
            driver.get("https://google.com/ncr");
            Capabilities caps = driver.getCapabilities();
            System.out.println(caps);
        } finally {
            driver.quit();
        }
    }
}
  
```

```py
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L87-L90)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```csharp
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.IE;

namespace ieTest {
 class Program {
  static void Main(string[] args) {
   InternetExplorerOptions options = new InternetExplorerOptions();
   options.ForceCreateProcessApi = true;
   IWebDriver driver = new InternetExplorerDriver(options);
   driver.Url = "https://google.com/ncr";
  }
 }
}
  
```

```rb
      @options.force_create_process_api = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L63)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```javascript
const ie = require('selenium-webdriver/ie');
let options = new ie.Options();
options.forceCreateProcessApi(true);

driver = await env.builder()
          .setIeOptions(options)
          .build();
  
```

```kotlin
import org.openqa.selenium.Capabilities
import org.openqa.selenium.ie.InternetExplorerDriver
import org.openqa.selenium.ie.InternetExplorerOptions

fun main() {
    val options = InternetExplorerOptions()
    options.useCreateProcessApiToLaunchIe()
    val driver = InternetExplorerDriver(options)
    try {
        driver.get("https://google.com/ncr")
        val caps = driver.getCapabilities()
        println(caps)
    } finally {
        driver.quit()
    }
}
  
```

```java
                .withLogFile(getLogLocation())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L53)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY`\
Property value: String representing path to log file

```py
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L97-L99)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L82)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
                .withLogOutput(System.out)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L67)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L109-L111)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L91)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L82)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `InternetExplorerDriverService.IE_DRIVER_LOGLEVEL_PROPERTY`\
Property value: String representation of `InternetExplorerDriverLogLevel.DEBUG.toString()` enum

```py
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L121-123)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
            if (_tempPath == null || !File.Exists(_tempPath))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L85)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '-log-level=WARN'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L102)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

```java
                .withExtractPath(getTempDirectory())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java#L94)

##### /examples/java/src/test/java/dev/selenium/browsers/InternetExplorerTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.ie.InternetExplorerDriver;
import org.openqa.selenium.ie.InternetExplorerDriverLogLevel;
import org.openqa.selenium.ie.InternetExplorerDriverService;
import org.openqa.selenium.ie.InternetExplorerOptions;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;

@EnabledOnOs(OS.WINDOWS)
public class InternetExplorerTest {
    public InternetExplorerDriver driver;
    private File logLocation;
    private File tempDirectory;

    @AfterEach
    public void quit() {
        if (logLocation != null && logLocation.exists()) {
            logLocation.delete();
        }
        if (tempDirectory  != null && tempDirectory.exists()) {
            tempDirectory.delete();
        }

        driver.quit();
    }

    @Test
    public void basicOptionsWin10() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        options.attachToEdgeChrome();
        options.withEdgeExecutablePath(getEdgeLocation());
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void basicOptionsWin11() {
        InternetExplorerOptions options = new InternetExplorerOptions();
        driver = new InternetExplorerDriver(options);
    }

    @Test
    public void logsToFile() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogFile(getLogLocation())
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsToConsole() throws IOException {
        System.setOut(new PrintStream(getLogLocation()));

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogOutput(System.out)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Started InternetExplorerDriver server"));
    }

    @Test
    public void logsWithLevel() throws IOException {
        System.setProperty(InternetExplorerDriverService.IE_DRIVER_LOGFILE_PROPERTY,
                getLogLocation().getAbsolutePath());

        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withLogLevel(InternetExplorerDriverLogLevel.WARN)
                .build();

        driver = new InternetExplorerDriver(service);

        String fileContent = new String(Files.readAllBytes(getLogLocation().toPath()));
        Assertions.assertTrue(fileContent.contains("Invalid capability setting: timeouts is type null"));
    }

    @Test
    public void supportingFilesLocation() throws IOException {
        InternetExplorerDriverService service = new InternetExplorerDriverService.Builder()
                .withExtractPath(getTempDirectory())
                .build();

        driver = new InternetExplorerDriver(service);
        Assertions.assertTrue(new File(getTempDirectory() + "/IEDriver.tmp").exists());
    }

    private File getLogLocation() throws IOException {
        if (logLocation == null || !logLocation.exists()) {
            logLocation = File.createTempFile("iedriver-", ".log");
        }

        return logLocation;
    }

    private File getTempDirectory() throws IOException {
        if (tempDirectory == null || !tempDirectory.exists()) {
            tempDirectory = Files.createTempDirectory("supporting-").toFile();
        }

        return tempDirectory;
    }

    private String getEdgeLocation() {
        return System.getenv("EDGE_BIN");
    }
}
```

\*\*Note\*\*: Java also allows setting log level by System Property:\ Property key: \`InternetExplorerDriverService.IE\_DRIVER\_EXTRACT\_PATH\_PROPERTY\`\ Property value: String representing path to supporting files directory

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_internet_explorer.py#L133-135)

##### /examples/python/tests/browsers/test\_internet\_explorer.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win10(edge_bin):
    options = webdriver.IeOptions()
    options.attach_to_edge_chrome = True
    options.edge_executable_path = edge_bin
    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_basic_options_win11():
    options = webdriver.IeOptions()
    driver = webdriver.Ie(options=options)

    driver.quit()

@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_file_upload_timeout():
    options = webdriver.IeOptions()
    options.file_upload_timeout = 2000

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ensure_clean_session():
    options = webdriver.IeOptions()
    options.ensure_clean_session = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_zoom_level():
    options = webdriver.IeOptions()
    options.ignore_zoom_level = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_ignore_protected_mode_settings():
    options = webdriver.IeOptions()
    options.ignore_protected_mode_settings = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_silent():
    service = webdriver.IeService(service_args=["--silent"])
    driver = webdriver.Ie(service=service)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_cmd_options():
    options = webdriver.IeOptions()
    options.add_argument("-private")

    driver = webdriver.Ie(options=options)

    driver.quit()

# Skipping this as it fails on Windows because the value of registry setting in 
# HKEY_CURRENT_USER\Software\Microsoft\Internet Explorer\Main\TabProcGrowth must be '0' 
@pytest.mark.skip
def test_force_create_process_api():
    options = webdriver.IeOptions()
    options.force_create_process_api = True

    driver = webdriver.Ie(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_file(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="INFO")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Starting WebDriver server" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_to_stdout(capfd):
    service = webdriver.IeService(log_output=subprocess.STDOUT)

    driver = webdriver.Ie(service=service)

    out, err = capfd.readouterr()
    assert "Started InternetExplorerDriver server" in out

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_log_level(log_path):
    service = webdriver.IeService(log_output=log_path, log_level="WARN")

    driver = webdriver.Ie(service=service)

    with open(log_path, "r") as fp:
        assert "Started InternetExplorerDriver server (32-bit)" in fp.readline()

    driver.quit()


@pytest.mark.skipif(sys.platform != "win32", reason="requires Windows")
def test_supporting_files(temp_dir):
    service = webdriver.IeService(service_args=["–extract-path=" + temp_dir])

    driver = webdriver.Ie(service=service)

    driver.quit()
```

```cs
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs#L98)

##### /examples/dotnet/SeleniumDocs/Browsers/InternetExplorerTest.cs

```cs
using System;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.IE;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("WINDOWS")]
    public class InternetExplorerTest
    {
        private InternetExplorerDriver _driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (_logLocation != null && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            _driver.Quit();
        }

        [TestMethod]
        public void BasicOptionsWin10()
        {
            var options = new InternetExplorerOptions();
            options.AttachToEdgeChrome = true;
            options.EdgeExecutablePath = GetEdgeLocation();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void BasicOptionsWin11()
        {
            var options = new InternetExplorerOptions();
            _driver = new InternetExplorerDriver(options);
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();
            service.LogFile = GetLogLocation();

            service.LoggingLevel = InternetExplorerDriverLogLevel.Warn;

            _driver = new InternetExplorerDriver(service);
            _driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Invalid capability setting: timeouts is type null")));
        }

        [TestMethod]
        public void SupportingFilesLocation()
        {
            var service = InternetExplorerDriverService.CreateDefaultService();

            service.LibraryExtractionPath = GetTempDirectory();

            _driver = new InternetExplorerDriver(service);
            Assert.IsTrue(File.Exists(GetTempDirectory() + "/IEDriver.tmp"));
        }

        private string GetLogLocation()
        {
            if (_logLocation == null || !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (_tempPath == null || !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private string GetEdgeLocation()
        {
            return Environment.GetEnvironmentVariable("EDGE_BIN");
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args << "–extract-path=#{root_directory}"
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/internet_explorer_spec.rb#L112)

##### /examples/ruby/spec/browsers/internet\_explorer\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Internet Explorer', skip: 'the connection fails on the windows pipeline' do
  describe 'Options' do
    let(:edge_location) { ENV.fetch('EDGE_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    before do
      @options = Selenium::WebDriver::IE::Options.new
      @options.attach_to_edge_chrome = true
      @options.edge_executable_path = edge_location
    end

    it 'basic options Win10' do
      options = Selenium::WebDriver::IE::Options.new
      options.attach_to_edge_chrome = true
      options.edge_executable_path = edge_location
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'basic options Win11' do
      options = Selenium::WebDriver::Options.ie
      @driver = Selenium::WebDriver.for :ie, options: options
    end

    it 'sets the file upload dialog timeout' do
      @options.file_upload_dialog_timeout = 2000
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ensures a clean session' do
      @options.ensure_clean_session = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the zoom setting' do
      @options.ignore_zoom_level = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'ignores the protected mode settings' do
      @options.ignore_protected_mode_settings = true
      driver = Selenium::WebDriver.for(:ie, options: @options)
      driver.quit
    end

    it 'adds the silent option' do
      @options.silent = true
      expect(@options.silent).to be_truthy
    end

    it 'sets the command line options' do
      @options.add_argument('-k')
      Selenium::WebDriver.for(:ie, options: @options)
    end

    it 'launches ie with the create process api' do
      @options.force_create_process_api = true
      Selenium::WebDriver.for(:ie, options: @options)
      expect(@options.instance_variable_get(:@options)['force_create_process_api'])
        .to eq({force_create_process_api: true})
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('iedriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.remove_entry root_directory
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.ie

      service.log = file_name

      @driver = Selenium::WebDriver.for :ie, service: service
      expect(File.readlines(file_name).first).to include('Started InternetExplorerDriver server')
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.ie

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Started InternetExplorerDriver server/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.ie
      service.log = $stdout

      service.args << '-log-level=WARN'

      expect {
        @driver = Selenium::WebDriver.for :ie, service: service
      }.to output(/Invalid capability setting: timeouts is type null/).to_stdout_from_any_process
    end

    it 'sets location for supporting files' do
      service = Selenium::WebDriver::Service.ie

      service.args << "–extract-path=#{root_directory}"

      @driver = Selenium::WebDriver.for :ie, service: service
    end
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

# 5 - Funcionalidade específica do Safari

Estas capacidades e características são específicas ao navegador Apple Safari.

Ao invés dos drivers para Chromium e Firefox, o safaridriver faz parte to sistema Operativo. Para activar a automação no Safari, execute o seguinte comando no terminal:

```shell
safaridriver --enable
```

```java
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#24-L25)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

```py
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L9-L10)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

```cs
            var options = new SafariOptions();
            driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/SafariTest.cs#L22-L23)

##### /examples/dotnet/SeleniumDocs/Browsers/SafariTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium.Safari;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Browsers
{
    [TestClassCustom]
    [EnabledOnOs("OSX")]
    public class SafariTest
    {
        private SafariDriver driver;

        [TestCleanup]
        public void QuitDriver()
        {
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new SafariOptions();
            driver = new SafariDriver(options);
        }
    }
}
```

```rb
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L8-L9)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

```js
    let driver = new Builder()
      .forBrowser(Browser.SAFARI)
      .setSafariOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/safariSpecificCap.spec.js#L8-L11)

##### /examples/javascript/test/browser/safariSpecificCap.spec.js

```js
const safari = require('selenium-webdriver/safari');
const {Browser, Builder} = require("selenium-webdriver");
const options = new safari.Options();
const process  =  require('node:process');

describe('Should be able to Test Command line arguments', function () {
  (process.platform === 'darwin' ? it : it.skip)('safari caps', async function () {
    let driver = new Builder()
      .forBrowser(Browser.SAFARI)
      .setSafariOptions(options)
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
val options = SafariOptions()
val driver = SafariDriver(options)
```

```java
                .withLogging(true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `SafariDriverService.SAFARI_DRIVER_LOGGING`\
Property value: `"true"` or `"false"`

[Selenium v4.26](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.26.0)

```py
    service = webdriver.SafariService(enable_logging=True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L17)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L20)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

```java
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/SafariTest.java#L39-L40)

##### /examples/java/src/test/java/dev/selenium/browsers/SafariTest.java

```java
package dev.selenium.browsers;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.EnabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.safari.SafariDriver;
import org.openqa.selenium.safari.SafariDriverService;
import org.openqa.selenium.safari.SafariOptions;

@EnabledOnOs(OS.MAC)
public class SafariTest {
    public SafariDriver driver;

    @AfterEach
    public void quit() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void basicOptions() {
        SafariOptions options = new SafariOptions();
        driver = new SafariDriver(options);
    }

    @Test
    public void enableLogs() {
        SafariDriverService service = new SafariDriverService.Builder()
                .withLogging(true)
                .build();

        driver = new SafariDriver(service);
    }
    
    public void safariTechnologyPreview() {
        SafariOptions options = new SafariOptions();
        options.setUseTechnologyPreview(true);
        driver = new SafariDriver(options);
    }
}
```

```py
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_safari.py#L25-L30)

##### /examples/python/tests/browsers/test\_safari.py

```py
import sys

import pytest
from selenium import webdriver


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_basic_options():
    options = webdriver.SafariOptions()
    driver = webdriver.Safari(options=options)

    driver.quit()


@pytest.mark.skipif(sys.platform != "darwin", reason="requires Mac")
def test_enable_logging():
    service = webdriver.SafariService(enable_logging=True)

    driver = webdriver.Safari(service=service)

    driver.quit()

@pytest.mark.skip(reason="Not installed on Mac GitHub Actions Runner Image")
def test_technology_preview():
    options = webdriver.SafariOptions()
    options.use_technology_preview = True
    service = webdriver.SafariService(
        executable_path='/Applications/Safari Technology Preview.app/Contents/MacOS/safaridriver'
    )
    driver = webdriver.Safari(options=options, service=service)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/safari_spec.rb#L38-L39)

##### /examples/ruby/spec/browsers/safari\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

# rubocop:disable RSpec/MultipleDescribes
RSpec.describe 'Safari', exclusive: {platform: :macosx} do
  describe 'Options' do
    it 'basic options' do
      options = Selenium::WebDriver::Options.safari
      @driver = Selenium::WebDriver.for :safari, options: options
    end
  end

  describe 'Service' do
    let(:directory) { "#{Dir.home}/Library/Logs/com.apple.WebDriver/*" }

    it 'enables logs' do
      original_count = Dir[directory].length
      service = Selenium::WebDriver::Service.safari

      service.args << '--diagnose'

      @driver = Selenium::WebDriver.for :safari, service: service
      expect(Dir[directory].length - original_count).to eq 1
    end

    it 'does not set log output' do
      service = Selenium::WebDriver::Service.safari

      expect {
        service.log = $stdout
      }.to raise_error(Selenium::WebDriver::Error::WebDriverError, /Safari Service does not support setting log output/)
    end
  end
end

RSpec.describe 'Safari Technology Preview', skip: 'This test is being skipped as GitHub Actions ' \
                                                  'have no support for Safari Technology Preview' do
  it 'sets the technology preview' do
    Selenium::WebDriver::Safari.technology_preview!
    local_driver = Selenium::WebDriver.for :safari
    expect(local_driver.capabilities.browser_name).to eq 'Safari Technology Preview'
  end
end
# rubocop:enable RSpec/MultipleDescribes
```

----
url: https://www.selenium.dev/_print/documentation/webdriver/support_features/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/webdriver/support_features/).

# Support features

Support classes provide optional higher level features.

* 1: [Waiting with Expected Conditions](#pg-6f16eaed237be9f8159a6b7b3d252058)
* 2: [Command Listeners](#pg-6283ba9cc77167f902a533def2b3c7a3)
* 3: [Working With Colors](#pg-a5a106dfcb422512ed3a6935e075c70b)
* 4: [Working with select list elements](#pg-fb05399c78e11e458add7495298425db)
* 5: [ThreadGuard](#pg-1957de864eed614666e4ca6a358f0eeb)

The core libraries of Selenium try to be low level and non-opinionated. The Support classes in each language provide opinionated wrappers for common interactions that may be used to simplify some behaviors.

# 1 - Waiting with Expected Conditions

```py
    wait = WebDriverWait(driver, timeout=2)
    wait.until(EC.visibility_of_element_located((By.ID, "revealed")))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_expected_conditions.py#L14-L15)

##### /examples/python/tests/support/test\_expected\_conditions.py

```py
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

# Expected Conditions API Documentation:
# https://www.selenium.dev/selenium/docs/api/py/webdriver_support/selenium.webdriver.support.expected_conditions.html


def test_expected_condition(driver):
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html")
    revealed = driver.find_element(By.ID, "revealed")
    driver.find_element(By.ID, "reveal").click()

    wait = WebDriverWait(driver, timeout=2)
    wait.until(EC.visibility_of_element_located((By.ID, "revealed")))

    revealed.send_keys("Displayed")
    assert revealed.get_property("value") == "Displayed"
```

# 3 - Working With Colors

```java
import org.openqa.selenium.support.Color;
  
```

```python
from selenium.webdriver.support.color import Color
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```ruby
include Selenium::WebDriver::Support
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```kotlin
import org.openqa.selenium.support.Color
```

```java
private final Color HEX_COLOUR = Color.fromString("#2F7ED8");
private final Color RGB_COLOUR = Color.fromString("rgb(255, 255, 255)");
private final Color RGB_COLOUR = Color.fromString("rgb(40%, 20%, 40%)");
private final Color RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)");
private final Color RGBA_COLOUR = Color.fromString("rgba(40%, 20%, 40%, 0.5)");
private final Color HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)");
private final Color HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)");
  
```

```python
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```ruby
HEX_COLOUR = Color.from_string('#2F7ED8')
RGB_COLOUR = Color.from_string('rgb(255, 255, 255)')
RGB_COLOUR = Color.from_string('rgb(40%, 20%, 40%)')
RGBA_COLOUR = Color.from_string('rgba(255, 255, 255, 0.5)')
RGBA_COLOUR = Color.from_string('rgba(40%, 20%, 40%, 0.5)')
HSL_COLOUR = Color.from_string('hsl(100, 0%, 50%)')
HSLA_COLOUR = Color.from_string('hsla(100, 0%, 50%, 0.5)')
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```kotlin
private val HEX_COLOUR = Color.fromString("#2F7ED8")
private val RGB_COLOUR = Color.fromString("rgb(255, 255, 255)")
private val RGB_COLOUR_PERCENT = Color.fromString("rgb(40%, 20%, 40%)")
private val RGBA_COLOUR = Color.fromString("rgba(255, 255, 255, 0.5)")
private val RGBA_COLOUR_PERCENT = Color.fromString("rgba(40%, 20%, 40%, 0.5)")
private val HSL_COLOUR = Color.fromString("hsl(100, 0%, 50%)")
private val HSLA_COLOUR = Color.fromString("hsla(100, 0%, 50%, 0.5)")
  
```

```java
private final Color BLACK = Color.fromString("black");
private final Color CHOCOLATE = Color.fromString("chocolate");
private final Color HOTPINK = Color.fromString("hotpink");
  
```

```python
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```ruby
BLACK = Color.from_string('black')
CHOCOLATE = Color.from_string('chocolate')
HOTPINK = Color.from_string('hotpink')
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```kotlin
private val BLACK = Color.fromString("black")
private val CHOCOLATE = Color.fromString("chocolate")
private val HOTPINK = Color.fromString("hotpink")
  
```

```java
private final Color TRANSPARENT = Color.fromString("transparent");
  
```

```python
TRANSPARENT = Color.from_string('transparent')
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```ruby
TRANSPARENT = Color.from_string('transparent')
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```kotlin
private val TRANSPARENT = Color.fromString("transparent")
  
```

```java
Color loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"));

Color loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"));
  
```

```python
login_button_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('color'))

login_button_background_colour = Color.from_string(driver.find_element(By.ID,'login').value_of_css_property('background-color'))
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```ruby
login_button_colour = Color.from_string(driver.find_element(id: 'login').css_value('color'))

login_button_background_colour = Color.from_string(driver.find_element(id: 'login').css_value('background-color'))
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```kotlin
val loginButtonColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("color"))

val loginButtonBackgroundColour = Color.fromString(driver.findElement(By.id("login")).getCssValue("background-color"))
  
```

```java
assert loginButtonBackgroundColour.equals(HOTPINK);
  
```

```python
assert login_button_background_colour == HOTPINK
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```ruby
assert(login_button_background_colour == HOTPINK)
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```kotlin
assert(loginButtonBackgroundColour.equals(HOTPINK))
  
```

```java
assert loginButtonBackgroundColour.asHex().equals("#ff69b4");
assert loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)");
assert loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)");
  
```

```python
assert login_button_background_colour.hex == '#ff69b4'
assert login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)'
assert login_button_background_colour.rgb == 'rgb(255, 105, 180)'
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```ruby
assert(login_button_background_colour.hex == '#ff69b4')
assert(login_button_background_colour.rgba == 'rgba(255, 105, 180, 1)')
assert(login_button_background_colour.rgb == 'rgb(255, 105, 180)')
  
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```kotlin
assert(loginButtonBackgroundColour.asHex().equals("#ff69b4"))
assert(loginButtonBackgroundColour.asRgba().equals("rgba(255, 105, 180, 1)"))
assert(loginButtonBackgroundColour.asRgb().equals("rgb(255, 105, 180)"))
  
```

Colours are no longer a problem.

# 4 - Working with select list elements

```html
<select name="selectomatic">
    <option selected="selected" id="non_multi_option" value="one">One</option>
    <option value="two">Two</option>
    <option value="four">Four</option>
    <option value="still learning how to count, apparently">Still learning how to count, apparently</option>
</select>
```

### Multiple select

This select list allows selecting and deselecting more than one option at a time. This only applies to `<select>` elements with the `multiple` attribute.

```html
<select name="multi" id="multi" multiple="multiple">
    <option selected="selected" value="eggs">Eggs</option>
    <option value="ham">Ham</option>
    <option selected="selected" value="sausages">Sausages</option>
    <option value="onion gravy">Onion gravy</option>
</select>
```

```java
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L23-L24)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L9-L10)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L23-L24)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L13-L14)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js

  it('Select an option', async function () {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L18-L19)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L20-L21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        List<WebElement> optionList = select.getOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L51)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    option_list = select.options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L37)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            IList<IWebElement> optionList = select.Options;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L52)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    option_list = select.options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L40)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L45)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val optionList = select.getOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L48)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L54)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    selected_option_list = select.all_selected_options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L40)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L56)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    selected_option_list = select.selected_options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L43)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L51)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val selectedOptionList = select.getAllSelectedOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L51)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByVisibleText("Four");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L30)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_visible_text('Four')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L16)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByText("Four");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L30)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:text, 'Four')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L20)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L25)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByVisibleText("Four")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L27)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByValue("two");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L33)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_value('two')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L19)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByValue("two");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L33)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:value, 'two')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L23)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await fourElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L28)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByValue("two")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L30)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByIndex(3);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L36)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_index(3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L22)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByIndex(3);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L36)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:index, 3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L26)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await twoElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L31)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByIndex(3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L33)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

### Disabled options

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

Options with a `disabled` attribute may not be selected.

```html
    <select name="single_disabled">
      <option id="sinlge_disabled_1" value="enabled">Enabled</option>
      <option id="sinlge_disabled_2" value="disabled" disabled="disabled">Disabled</option>
    </select>
```

*
*
*
*
*
*

```java
        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L77-L79)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L60-L61)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L77)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L62-L64)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L73-L76)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L74-L76)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.deselectByValue("eggs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L66)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.deselect_by_value('eggs')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L49)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.DeselectByValue("eggs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L65)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.deselect_by(:value, 'eggs')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L52)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await gravyElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L63)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.deselectByValue("eggs")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

# 5 - ThreadGuard

This class is only available in the Java Binding

ThreadGuard checks that a driver is called only from the same thread that created it. Threading issues especially when running tests in Parallel may have mysterious and hard to diagnose errors. Using this wrapper prevents this category of errors and will raise an exception when it happens.

The following example simulate a clash of threads:

```java
public class DriverClash {
  //thread main (id 1) created this driver
  private WebDriver protectedDriver = ThreadGuard.protect(new ChromeDriver()); 

  static {
    System.setProperty("webdriver.chrome.driver", "<Set path to your Chromedriver>");
  }
  
  //Thread-1 (id 24) is calling the same driver causing the clash to happen
  Runnable r1 = () -> {protectedDriver.get("https://selenium.dev");};
  Thread thr1 = new Thread(r1);
   
  void runThreads(){
    thr1.start();
  }

  public static void main(String[] args) {
    new DriverClash().runThreads();
  }
}
```

The result shown below:

```text
Exception in thread "Thread-1" org.openqa.selenium.WebDriverException:
Thread safety error; this instance of WebDriver was constructed
on thread main (id 1)and is being accessed by thread Thread-1 (id 24)
This is not permitted and *will* cause undefined behaviour
```

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/browsers/firefox/
----

# Funcionalidade específica do Firefox

```java
    driver = new FirefoxDriver(options);
  }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L36-L37)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L10-L11)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
        public void BasicOptions()
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L34-L35)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L10-L11)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/openFirefoxTest.spec.js#L10-L13)

##### /examples/javascript/test/getting\_started/openFirefoxTest.spec.js

```js
const {Browser, Builder} = require('selenium-webdriver');
const firefox = require('selenium-webdriver/firefox');


describe('Open Firefox', function () {
  let driver;

  before(async function () {
    let options = new firefox.Options();
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options)
      .build();
  });

  after(async () => await driver.quit());

  it('Basic Firefox test', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options.add_argument("-headless")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L19)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            var options = new FirefoxOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L43)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options.args << '-headless'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L17)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
      .setFirefoxOptions(options.addArguments('--headless'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L12)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L54)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    options.binary_location = firefox_bin
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L28)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            var options = new FirefoxOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L53)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      options.binary = firefox_location
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L25)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
    driver = new FirefoxDriver(options);
  }
}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L211-L216)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L160-L168)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```csharp
var options = new FirefoxOptions();
var profile = new FirefoxProfile();
options.Profile = profile;
var driver = new RemoteWebDriver(options);
  
```

```rb
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L139-L141)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```javascript
const { Builder } = require("selenium-webdriver");
const firefox = require('selenium-webdriver/firefox');

const options = new firefox.Options();
let profile = '/path to custom profile';
options.setProfile(profile);
const driver = new Builder()
    .forBrowser('firefox')
    .setFirefoxOptions(options)
    .build();
  
```

```kotlin
val options = FirefoxOptions()
options.profile = FirefoxProfile()
driver = RemoteWebDriver(options)
  
```

```java
        new GeckoDriverService.Builder().withLogFile(logLocation).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L62-L63)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting file output by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY`\
Property value: String representing path to log file

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L36)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = file_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L43)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withLogOutput(System.out).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L76-L77)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting console output by System Property;\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY`\
Property value: `DriverService.LOG_STDOUT` or `DriverService.LOG_STDERR`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L48)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.log = $stdout
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L52)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L90-L91)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY`\
Property value: String representation of `FirefoxDriverLogLevel` enum

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L59)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args += %w[--log debug]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L63)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L106-L107)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_LOG_NO_TRUNCATE`\
Property value: `"true"` or `"false"`

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L70)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.10](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.10.0)

```rb
      service.args << '--log-no-truncate'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L72)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L118-L119)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

**Note**: Java also allows setting log level by System Property:\
Property key: `GeckoDriverService.GECKO_DRIVER_PROFILE_ROOT`\
Property value: String representing path to profile root directory

```py
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L81)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
      service.args += ['--profile-root', root_directory]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L81)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L133)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.install_addon(addon_path_xpi)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L94)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

```cs
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L137)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      driver.install_addon(extension_file_path)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L95)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    let id = await driver.installAddon(xpiPath);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L25)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L148)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.uninstall_addon(id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L106)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```cs
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L152)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

```rb
      driver.uninstall_addon(extension_id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L106)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    await driver.uninstallAddon(id);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L26)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L160)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.install_addon(addon_path_dir, temporary=True)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L115)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```cs
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs#L165)

##### /examples/dotnet/SeleniumDocs/Browsers/FirefoxTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Internal.Logging;

namespace SeleniumDocs.Browsers
{
    [TestClass]
    public class FirefoxTest
    {
        private FirefoxDriver driver;
        private string _logLocation;
        private string _tempPath;

        [TestCleanup]
        public void Cleanup()
        {
            if (!String.IsNullOrEmpty(_logLocation) && File.Exists(_logLocation))
            {
                File.Delete(_logLocation);
            }
            if (_tempPath != null && File.Exists(_tempPath))
            {
                File.Delete(_tempPath);
            }
            driver.Quit();
        }

        [TestMethod]
        public void BasicOptions()
        {
            var options = new FirefoxOptions();
            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void Arguments()
        {
            var options = new FirefoxOptions();

            options.AddArgument("-headless");

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void SetBinary()
        {
            var options = new FirefoxOptions();

            options.BinaryLocation = GetFirefoxLocation();

            driver = new FirefoxDriver(options);
        }

        [TestMethod]
        public void LogsToFile()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("geckodriver	INFO	Listening on")));
        }

        [TestMethod]
        public void LogsToConsole()
        {
            TestLogHandler testLogHandler = new TestLogHandler();
            ResetGlobalLog();
            try
            {
                Log.SetLevel(LogEventLevel.Trace).Handlers.Add(testLogHandler);
                var service = FirefoxDriverService.CreateDefaultService();
                driver = new FirefoxDriver(service);
                Assert.IsTrue(testLogHandler.Events.Count >= 1);
                Assert.IsTrue(testLogHandler.Events.Any(e => e.Message.Contains("geckodriver")));
            }
            finally
            {
                ResetGlobalLog();
            }
        }

        [TestMethod]
        public void LogsLevel()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogPath = GetLogLocation();
            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNotNull(lines.FirstOrDefault(line => line.Contains("Marionette\tDEBUG")));
        }

        [TestMethod]
        public void StopsTruncatingLogs()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.LogTruncate = false;

            service.LogLevel = FirefoxDriverLogLevel.Debug;

            driver = new FirefoxDriver(service);
            driver.Quit(); // Close the Service log file before reading
            var lines = File.ReadLines(GetLogLocation());
            Assert.IsNull(lines.FirstOrDefault(line => line.Contains(" ... ")));
        }

        [TestMethod]
        public void SetProfileLocation()
        {
            var service = FirefoxDriverService.CreateDefaultService();
            service.ProfileRoot = GetTempDirectory();

            driver = new FirefoxDriver(service);

            string profile = (string)driver.Capabilities.GetCapability("moz:profile");
            string[] directories = profile.Split("/");
            var dirName = directories.Last();
            Assert.AreEqual(GetTempDirectory() + dirName, profile);
        }

        [TestMethod]
        public void InstallAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");

            driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }

        [TestMethod]
        public void UnInstallAddon()
        {
            driver = new FirefoxDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionFilePath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example.xpi");
            string extensionId = driver.InstallAddOnFromFile(Path.GetFullPath(extensionFilePath));

            driver.UninstallAddOn(extensionId);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            Assert.AreEqual(driver.FindElements(By.Id("webextensions-selenium-example")).Count, 0);
        }

        [TestMethod]
        public void InstallUnsignedAddon()
        {
            SetWaitingDriver();
            string baseDir = AppDomain.CurrentDomain.BaseDirectory;
            string extensionDirPath = Path.Combine(baseDir, "../../../Extensions/webextensions-selenium-example/");

            driver.InstallAddOnFromDirectory(Path.GetFullPath(extensionDirPath), true);

            driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
            IWebElement injected = driver.FindElement(By.Id("webextensions-selenium-example"));
            Assert.AreEqual("Content injected by webextensions-selenium-example", injected.Text);
        }
        
        private string GetLogLocation()
        {
            if (string.IsNullOrEmpty(_logLocation) && !File.Exists(_logLocation))
            {
                _logLocation = Path.GetTempFileName();
            }

            return _logLocation;
        }

        private string GetTempDirectory()
        {
            if (string.IsNullOrEmpty(_tempPath) && !File.Exists(_tempPath))
            {
                _tempPath = Path.GetTempPath();
            }

            return _tempPath;
        }

        private void SetWaitingDriver()
        {
            driver = new FirefoxDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(2);
        }

        private static string GetFirefoxLocation()
        {
            var options = new FirefoxOptions()
            {
                BrowserVersion = "stable"
            };
            return new DriverFinder(options).GetBrowserPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private void ResetGlobalLog()
        {
            Log.SetLevel(LogEventLevel.Info);
            Log.Handlers.Clear().Handlers.Add(new TextWriterHandler(Console.Error));
        }
    }
}

class TestLogHandler : ILogHandler
{
    public ILogHandler Clone()
    {
        return this;
    }

    public void Handle(LogEvent logEvent)
    {
        Events.Add(logEvent);
    }

    public IList<LogEvent> Events { get; internal set; } = new List<LogEvent>();
}
```

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

```rb
      driver.install_addon(extension_dir_path, true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L115)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```js
    let id = await driver.installAddon(xpiPath, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js#L41)

##### /examples/javascript/test/browser/firefoxSpecificFunctionalities.spec.js

```js
const {Browser, By, Builder} = require('selenium-webdriver');
const Firefox = require('selenium-webdriver/firefox');
const options = new Firefox.Options();
const path = require('path');
const assert = require("assert");


describe('Should be able to Test Command line arguments', function () {
  it('headless', async function () {
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .setFirefoxOptions(options.addArguments('--headless'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to add extension', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example.xpi')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });

  it('Should be able to install unsigned addon', async function () {

    const xpiPath = path.resolve('./test/resources/extensions/selenium-example')
    let driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    let id = await driver.installAddon(xpiPath, true);
    await driver.uninstallAddon(id);


    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    const ele = await driver.findElements(By.id("webextensions-selenium-example"));
    assert.equal(ele.length, 0);
    await driver.quit();
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L181)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    driver.save_full_page_screenshot("full_page_screenshot.png")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L139)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L125)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

```java
    // Verify the context is back to "content"
    Assertions.assertEquals(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java#L197-L198)

##### /examples/java/src/test/java/dev/selenium/browsers/FirefoxTest.java

```java
package dev.selenium.browsers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.condition.DisabledOnOs;
import org.junit.jupiter.api.condition.OS;
import org.openqa.selenium.By;
import org.openqa.selenium.OutputType;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.firefox.*;
import org.openqa.selenium.remote.service.DriverFinder;

public class FirefoxTest extends BaseTest {
  private FirefoxDriver driver;

  @AfterEach
  public void clearProperties() {
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY);
    System.clearProperty(GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY);
    if (driver != null) {
      driver.quit();
    }
  }

  @Test
  public void basicOptions() {
    FirefoxOptions options = new FirefoxOptions();
    driver = new FirefoxDriver(options);
  }

  @Test
  public void arguments() {
    FirefoxOptions options = new FirefoxOptions();

    options.addArguments("-headless");

    driver = new FirefoxDriver(options);
  }

  @Test
  @DisabledOnOs(OS.WINDOWS)
  public void setBrowserLocation() {
    FirefoxOptions options = new FirefoxOptions();

    options.setBinary(getFirefoxLocation());

    driver = new FirefoxDriver(options);
  }

  @Test
  public void logsToFile() throws IOException {
    File logLocation = getTempFile("logsToFile", ".log");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogFile(logLocation).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsToConsole() throws IOException {
    File logLocation = getTempFile("logsToConsole", ".log");
    System.setOut(new PrintStream(logLocation));

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogOutput(System.out).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("geckodriver	INFO	Listening on"));
  }

  @Test
  public void logsWithLevel() throws IOException {
    File logLocation = getTempFile("logsWithLevel", ".log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withLogLevel(FirefoxDriverLogLevel.DEBUG).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertTrue(fileContent.contains("Marionette\tDEBUG"));
  }

  @Test
  public void stopsTruncatingLogs() throws IOException {
    File logLocation = getTempFile("geckodriver-", "log");
    System.setProperty(GeckoDriverService.GECKO_DRIVER_LOG_PROPERTY, logLocation.getAbsolutePath());
    System.setProperty(
        GeckoDriverService.GECKO_DRIVER_LOG_LEVEL_PROPERTY, FirefoxDriverLogLevel.DEBUG.toString());

    FirefoxDriverService service =
        new GeckoDriverService.Builder().withTruncatedLogs(false).build();

    driver = new FirefoxDriver(service);

    String fileContent = new String(Files.readAllBytes(logLocation.toPath()));
    Assertions.assertFalse(fileContent.contains(" ... "));
  }

  @Test
  public void setProfileLocation() {
    File profileDirectory = getTempDirectory("profile-");
    FirefoxDriverService service =
        new GeckoDriverService.Builder().withProfileRoot(profileDirectory).build();

    driver = new FirefoxDriver(service);

    String location = (String) driver.getCapabilities().getCapability("moz:profile");
    Assertions.assertTrue(location.contains(profileDirectory.getAbsolutePath()));
  }


  @Test
  public void installAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");

    driver.installExtension(xpiPath);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = driver.findElement(By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }


  @Test
  public void uninstallAddon() {
    driver = startFirefoxDriver();
    Path xpiPath = Paths.get("src/test/resources/extensions/selenium-example.xpi");
    String id = driver.installExtension(xpiPath);

    driver.uninstallExtension(id);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    Assertions.assertEquals(driver.findElements(By.id("webextensions-selenium-example")).size(), 0);
  }


  @Test
  public void installUnsignedAddonPath() {
    driver = startFirefoxDriver();
    Path path = Paths.get("src/test/resources/extensions/selenium-example");

    driver.installExtension(path, true);

    driver.get("https://www.selenium.dev/selenium/web/blank.html");
    WebElement injected = getLocatedElement(driver, By.id("webextensions-selenium-example"));
    Assertions.assertEquals(
        "Content injected by webextensions-selenium-example", injected.getText());
  }

  private Path getFirefoxLocation() {
    FirefoxOptions options = new FirefoxOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(GeckoDriverService.createDefaultService(), options);
    return Path.of(finder.getBrowserPath());
  }

  @Test
  public void fullPageScreenshot() throws Exception {
    driver = startFirefoxDriver();

    driver.get("https://www.selenium.dev");

    File screenshot = driver.getFullPageScreenshotAs(OutputType.FILE);

    File targetFile = new File("full_page_screenshot.png");
    Files.move(screenshot.toPath(), targetFile.toPath());

    // Verify the screenshot file exists
    Assertions.assertTrue(targetFile.exists(), "The full page screenshot file should exist");
    Files.deleteIfExists(targetFile.toPath());
  }

  @Test
  public void setContext() {
    driver = startFirefoxDriver(new FirefoxOptions().addArguments("-remote-allow-system-access"));

    driver.setContext(FirefoxCommandContext.CHROME);
    driver.executeScript("console.log('Inside Chrome context');");

    // Verify the context is back to "content"
    Assertions.assertEquals(
            FirefoxCommandContext.CHROME, driver.getContext(),
            "The context should be 'chrome'"
    );
  }

  @Test
  public void firefoxProfile() {
    FirefoxProfile profile = new FirefoxProfile();
    FirefoxOptions options = new FirefoxOptions();
    profile.setPreference("javascript.enabled", "False");
    options.setProfile(profile);

    driver = new FirefoxDriver(options);
  }
}
```

```py
    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/browsers/test_firefox.py#L151-L152)

##### /examples/python/tests/browsers/test\_firefox.py

```py
import os
import subprocess
import sys

import pytest
from selenium import webdriver


def test_basic_options():
    options = webdriver.FirefoxOptions()
    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_arguments():
    options = webdriver.FirefoxOptions()

    options.add_argument("-headless")

    driver = webdriver.Firefox(options=options)
    driver.quit()


def test_set_browser_location(firefox_bin):
    options = webdriver.FirefoxOptions()

    options.binary_location = firefox_bin

    driver = webdriver.Firefox(options=options)

    driver.quit()


def test_log_to_file(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)
    driver.get("https://www.selenium.dev")

    with open(log_path, 'r') as fp:
        assert "geckodriver	INFO	Listening on" in fp.readline()

    driver.quit()


def test_log_to_stdout(capfd):
    service = webdriver.FirefoxService(log_output=subprocess.STDOUT)

    driver = webdriver.Firefox(service=service)

    out, err = capfd.readouterr()
    assert "geckodriver	INFO	Listening on" in out

    driver.quit()


def test_log_level(log_path):
    service = webdriver.FirefoxService(log_output=log_path, service_args=['--log', 'debug'])

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert '\tDEBUG' in f.read()

    driver.quit()


def test_log_truncation(log_path):
    service = webdriver.FirefoxService(service_args=['--log-no-truncate', '--log', 'debug'], log_output=log_path)

    driver = webdriver.Firefox(service=service)

    with open(log_path, 'r') as f:
        assert ' ... ' not in f.read()

    driver.quit()


def test_profile_location(temp_dir):
    service = webdriver.FirefoxService(service_args=['--profile-root', temp_dir])

    driver = webdriver.Firefox(service=service)
    profile_name = driver.capabilities.get('moz:profile').replace('\\', '/').split('/')[-1]

    assert profile_name in os.listdir(temp_dir)

    driver.quit()


def test_install_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    driver.install_addon(addon_path_xpi)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_uninstall_addon(firefox_driver, addon_path_xpi):
    driver = firefox_driver

    id = driver.install_addon(addon_path_xpi)
    driver.uninstall_addon(id)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    assert len(driver.find_elements(webdriver.common.by.By.ID, "webextensions-selenium-example")) == 0


def test_install_unsigned_addon_directory(firefox_driver, addon_path_dir):
    driver = firefox_driver

    driver.install_addon(addon_path_dir, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_install_unsigned_addon_directory_slash(firefox_driver, addon_path_dir_slash):
    driver = firefox_driver

    driver.install_addon(addon_path_dir_slash, temporary=True)

    driver.get("https://www.selenium.dev/selenium/web/blank.html")
    injected = driver.find_element(webdriver.common.by.By.ID, "webextensions-selenium-example")

    assert injected.text == "Content injected by webextensions-selenium-example"


def test_full_page_screenshot(firefox_driver):
    driver = firefox_driver

    driver.get("https://www.selenium.dev")

    driver.save_full_page_screenshot("full_page_screenshot.png")

    assert os.path.exists("full_page_screenshot.png")

    driver.quit()


def test_set_context():
    options = webdriver.FirefoxOptions()
    options.add_argument("-remote-allow-system-access")
    driver = webdriver.Firefox(options=options)

    with driver.context(driver.CONTEXT_CHROME):
        driver.execute_script("console.log('Inside Chrome context');")

    # Check if the context is back to content
    assert driver.execute("GET_CONTEXT")["value"] == "content"
    driver.quit()


def test_firefox_profile():
    from selenium.webdriver.firefox.options import Options
    from selenium.webdriver.firefox.firefox_profile import FirefoxProfile

    options = Options()
    firefox_profile = FirefoxProfile()
    firefox_profile.set_preference("javascript.enabled", False)
    options.profile = firefox_profile

    driver = webdriver.Firefox(options=options)

    driver.quit()
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      driver.context = 'content'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/browsers/firefox_spec.rb#L132)

##### /examples/ruby/spec/browsers/firefox\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Firefox' do
  describe 'Options' do
    let(:firefox_location) { driver_finder && ENV.fetch('FIREFOX_BIN', nil) }

    it 'basic options' do
      options = Selenium::WebDriver::Options.firefox
      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'add arguments' do
      options = Selenium::WebDriver::Options.firefox

      options.args << '-headless'

      @driver = Selenium::WebDriver.for :firefox, options: options
    end

    it 'sets location of binary' do
      options = Selenium::WebDriver::Options.firefox

      options.binary = firefox_location

      @driver = Selenium::WebDriver.for :firefox, options: options
    end
  end

  describe 'Service' do
    let(:file_name) { Tempfile.new('geckodriver').path }
    let(:root_directory) { Dir.mktmpdir }

    after do
      FileUtils.rm_f(file_name)
      FileUtils.rm_rf(root_directory)
    end

    it 'logs to file' do
      service = Selenium::WebDriver::Service.firefox

      service.log = file_name

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).first).to include("geckodriver\tINFO\tListening on")
    end

    it 'logs to console' do
      service = Selenium::WebDriver::Service.firefox

      service.log = $stdout

      expect {
        @driver = Selenium::WebDriver.for :firefox, service: service
      }.to output(/geckodriver	INFO	Listening on/).to_stdout_from_any_process
    end

    it 'sets log level' do
      service = Selenium::WebDriver::Service.firefox
      service.log = file_name

      service.args += %w[--log debug]

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/Marionette	DEBUG/).any?).to eq true
    end

    it 'stops truncating log lines' do
      service = Selenium::WebDriver::Service.firefox(log: file_name, args: %w[--log debug])

      service.args << '--log-no-truncate'

      @driver = Selenium::WebDriver.for :firefox, service: service
      expect(File.readlines(file_name).grep(/ \.\.\. /).any?).to eq false
    end

    it 'sets default profile location' do
      service = Selenium::WebDriver::Service.firefox

      service.args += ['--profile-root', root_directory]

      @driver = Selenium::WebDriver.for :firefox, service: service
      profile_location = Dir.new(@driver.capabilities['moz:profile'])
      expect(profile_location.path.gsub('\\', '/')).to include(root_directory)
    end
  end

  describe 'Features' do
    let(:driver) { start_firefox }

    it 'installs addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)

      driver.install_addon(extension_file_path)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'uninstalls addon' do
      extension_file_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example.xpi', __dir__)
      extension_id = driver.install_addon(extension_file_path)

      driver.uninstall_addon(extension_id)

      driver.get 'https://www.selenium.dev/selenium/web/blank.html'
      expect(driver.find_elements(id: 'webextensions-selenium-example')).to be_empty
    end

    it 'installs unsigned addon' do
      extension_dir_path = File.expand_path('../spec_support/extensions/webextensions-selenium-example/', __dir__)

      driver.install_addon(extension_dir_path, true)

      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      injected = driver.find_element(id: 'webextensions-selenium-example')
      expect(injected.text).to eq 'Content injected by webextensions-selenium-example'
    end

    it 'takes full page screenshot' do
      driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
      Dir.mktmpdir('screenshot_test') do |dir|
        screenshot = driver.save_full_page_screenshot(File.join(dir, 'screenshot.png'))

        expect(screenshot).to be_a File
      end
    end

    it 'sets the context' do
      driver.context = 'content'
      expect(driver.context).to eq 'content'
    end
  end

  describe 'Profile' do
    it 'creates a new profile' do
      profile = Selenium::WebDriver::Firefox::Profile.new
      profile['browser.download.dir'] = '/tmp/webdriver-downloads'
      options = Selenium::WebDriver::Firefox::Options.new(profile: profile)
      expect(options.profile).to eq(profile)
    end
  end

  def driver_finder
    options = Selenium::WebDriver::Options.firefox(browser_version: 'stable')
    service = Selenium::WebDriver::Service.firefox
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['GECKODRIVER_BIN'] = finder.driver_path
    ENV['FIREFOX_BIN'] = finder.browser_path
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

**Note**: As of Firefox 138, geckodriver needs to be started with the argument `--allow-system-access` to switch the context to `CHROME`.

----
url: https://www.selenium.dev/documentation/webdriver/interactions/cookies/
----

# Working with cookies

```java

    WebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L30-L32)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L5-L9)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L32-L34)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L9-L11)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L18)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")

        // Adds the cookie into current browser context
        driver.manage().addCookie(Cookie("key", "value"))
    } finally {
        driver.quit()
    }
}
  
```

```java
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L38-L42)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L13-L20)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L40-L44)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L17-L21)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L35-L38)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("foo", "bar"))

        // Get cookie details with named cookie 'foo'
        val cookie = driver.manage().getCookieNamed("foo")
        println(cookie)
    } finally {
        driver.quit()
    }
}  
  
```

```java
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L52-L66)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L24-L32)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L51-L64)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L26-L31)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L49-L51)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        driver.manage().addCookie(Cookie("test2", "cookie2"))

        // Get All available cookies
        val cookies = driver.manage().cookies
        println(cookies)
    } finally {
        driver.quit()
    }
}  
  
```

```java
        }
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L74-L77)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L35-L43)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L70-L73)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L40-L43)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L61-L62)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        val cookie1 = Cookie("test2", "cookie2")
        driver.manage().addCookie(cookie1)

        // delete a cookie with name 'test1'
        driver.manage().deleteCookieNamed("test1")
        
        // delete cookie by passing cookie object of current browsing context.
        driver.manage().deleteCookie(cookie1)
    } finally {
        driver.quit()
    }
}  
  
```

```java
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L100-L105)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L47-L55)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L92-L97)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L49-L54)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L77-L78)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        driver.manage().addCookie(Cookie("test2", "cookie2"))

        // deletes all cookies
        driver.manage().deleteAllCookies()
    } finally {
        driver.quit()
    }
}  
  
```

```java

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L112-L121)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L59-L71)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SameSiteCookie {
  class SameSiteCookie {
    static void Main(string[] args) {
      IWebDriver driver = new ChromeDriver();
      try {
        driver.Navigate().GoToUrl("http://www.example.com");

        var cookie1Dictionary = new System.Collections.Generic.Dictionary<string, object>() {
          { "name", "test1" }, { "value", "cookie1" }, { "sameSite", "Strict" } };
        var cookie1 = Cookie.FromDictionary(cookie1Dictionary);

        var cookie2Dictionary = new System.Collections.Generic.Dictionary<string, object>() {
          { "name", "test2" }, { "value", "cookie2" }, { "sameSite", "Lax" } };
        var cookie2 = Cookie.FromDictionary(cookie2Dictionary);

        driver.Manage().Cookies.AddCookie(cookie1);
        driver.Manage().Cookies.AddCookie(cookie2);

        System.Console.WriteLine(cookie1.SameSite);
        System.Console.WriteLine(cookie2.SameSite);
      } finally {
        driver.Quit();
      }
    }
  }
}
  
```

```ruby
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://www.example.com'
  # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
  driver.manage.add_cookie(name: "foo", value: "bar", same_site: "Strict")
  driver.manage.add_cookie(name: "foo1", value: "bar", same_site: "Lax")
  puts driver.manage.cookie_named('foo')
  puts driver.manage.cookie_named('foo1')
ensure
  driver.quit
end
  
```

```js
  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L24-L26)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("http://www.example.com")
        val cookie = Cookie.Builder("key", "value").sameSite("Strict").build()
        val cookie1 = Cookie.Builder("key", "value").sameSite("Lax").build()
        driver.manage().addCookie(cookie)
        driver.manage().addCookie(cookie1)
        println(cookie.getSameSite())
        println(cookie1.getSameSite())
    } finally {
        driver.quit()
    }
}
  
```

----
url: https://www.selenium.dev/documentation/webdriver/elements/information/
----

```java
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L27-L29)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L12-L15)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L18-L22)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    displayed_value = driver.find_element(name: 'email_input').displayed?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L12)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L16-L17)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
 //navigates to url
 driver.get("https://www.selenium.dev/selenium/web/inputs.html")

 //returns true if element is displayed else returns false
 val flag = driver.findElement(By.name("email_input")).isDisplayed()
```

```java
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L32-L34)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L19)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L25-L27)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    enabled_value = driver.find_element(name: 'email_input').enabled?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L17)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L23-L24)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
 //navigates to url
 driver.get("https://www.selenium.dev/selenium/web/inputs.html")

 //returns true if element is enabled else returns false
 val attr = driver.findElement(By.name("button_input")).isEnabled()
  
```

```java
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L37-L39)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L23)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
  from selenium.webdriver.common.by import By
  
  import pytest
  
  
  def test_informarion():
      # Initialize WebDriver
      driver = webdriver.Chrome()
      driver.implicitly_wait(0.5)
  
      driver.get("https://www.selenium.dev/selenium/web/inputs.html")
  
      # isDisplayed
      is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
      assert is_email_visible == True
  
      # isEnabled
      is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
      assert is_enabled_button == True
  
      # isSelected
      is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
      assert is_selected_check == True
  
      # TagName
      tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
      assert tag_name_inp == "input"
  
      # GetRect
      rect = driver.find_element(By.NAME, "range_input").rect
      assert rect["x"] == 10
  
      # CSS Value
      css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
          "font-size"
      )
      assert css_value == "13.3333px"
  
      # GetText
      text = driver.find_element(By.TAG_NAME, "h1").text
      assert text == "Testing Inputs"
  
      # FetchAttributes
      email_txt = driver.find_element(By.NAME, "email_input")
      value_info = email_txt.get_attribute("value")
      assert value_info == "admin@localhost"
  
```

```cs
            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L30-L32)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    selected_value = driver.find_element(name: 'email_input').selected?
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L22)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L30-L31)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
 //navigates to url
 driver.get("https://www.selenium.dev/selenium/web/inputs.html")

 //returns true if element is checked else returns false
 val attr =  driver.findElement(By.name("checkbox_input")).isSelected()
  
```

```java
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L42-L44)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L27)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L35-L37)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    tag_name = driver.find_element(name: 'email_input').tag_name
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L27)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L37-L38)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
 //navigates to url
 driver.get("https://www.selenium.dev/selenium/web/inputs.html")

 //returns TagName of the element
 val attr =  driver.findElement(By.name("email_input")).getTagName()
  
```

```java
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L47-L50)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    rect = driver.find_element(By.NAME, "range_input").rect
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L31)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L40-L43)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    size = driver.find_element(name: 'email_input').size
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L32)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    let object = await driver.findElement(By.name('range_input')).getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L45)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to url
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

// Returns height, width, x and y coordinates referenced element
val res = driver.findElement(By.name("range_input")).rect

// Rectangle class provides getX,getY, getWidth, getHeight methods
println(res.getX())
  
```

```java
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L52-L54)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L35-L37)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L49-L50)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L38)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true
  
  require 'spec_helper'
  
  RSpec.describe 'Element Information' do
    let(:driver) { start_session }
    let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }
  
    before { driver.get(url) }
  
    it 'checks if an element is displayed' do
      displayed_value = driver.find_element(name: 'email_input').displayed?
      expect(displayed_value).to be_truthy
    end
  
    it 'checks if an element is enabled' do
      enabled_value = driver.find_element(name: 'email_input').enabled?
      expect(enabled_value).to be_truthy
    end
  
    it 'checks if an element is selected' do
      selected_value = driver.find_element(name: 'email_input').selected?
      expect(selected_value).to be_falsey
    end
  
    it 'gets the tag name of an element' do
      tag_name = driver.find_element(name: 'email_input').tag_name
      expect(tag_name).not_to be_empty
    end
  
    it 'gets the size and position of an element' do
      size = driver.find_element(name: 'email_input').size
      expect(size.width).to be_positive
      expect(size.height).to be_positive
    end
  
    it 'gets the css value of an element' do
      css_value = driver.find_element(name: 'email_input').css_value('background-color')
      expect(css_value).not_to be_empty
    end
  
    it 'gets the text of an element' do
      text = driver.find_element(xpath: '//h1').text
      expect(text).to eq('Testing Inputs')
    end
  
    it 'gets the attribute value of an element' do
      attribute_value = driver.find_element(name: 'number_input').attribute('value')
      expect(attribute_value).not_to be_empty
    end
  end
  
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
      // Returns background color of the element
      let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L76-L78)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
  const assert = require("assert");
  
  describe('Element Information Test', function () {
    let driver;
    
    before(async function () {
      driver = await new Builder().forBrowser('chrome').build();
    });
    
    beforeEach(async ()=> {
      await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
    })
    
    it('Check if element is displayed', async function () {
      // Resolves Promise and returns boolean value
      let result =  await driver.findElement(By.name("email_input")).isDisplayed();
      
      assert.equal(result,true);
    });
    
    it('Check if button is enabled', async function () {
      // Resolves Promise and returns boolean value
      let element =  await driver.findElement(By.name("button_input")).isEnabled();
    
      assert.equal(element, true);
    });
    
    it('Check if checkbox is selected', async function () {
      // Returns true if element ins checked else returns false
      let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
    
      assert.equal(isSelected, true);
    });
    
    it('Should return the tagname', async function () {
      // Returns TagName of the element
      let value = await driver.findElement(By.name('email_input')).getTagName();
    
      assert.equal(value, "input");
    });
    
    it('Should be able to fetch element size and position ', async function () {
      // Returns height, width, x and y position of the element
      let object = await driver.findElement(By.name('range_input')).getRect();
      
      assert.ok(object.height!==null)
      assert.ok(object.width!==null)
      assert.ok(object.y!==null)
      assert.ok(object.x!==null)
      
    });
    
    it('Should be able to fetch attributes and properties ', async function () {
      // identify the email text box
      const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
      
      //fetch the attribute "name" associated with the textbox
      const nameAttribute = await emailElement.getAttribute("name");
    
      assert.equal(nameAttribute, "email_input")
    });
    
    after(async () => await driver.quit());
  });
  
  
  describe('Element Information Test', function () {
    let driver;
    
    before(async function () {
      driver = await new Builder().forBrowser('chrome').build();
    });
    
    it('Should return the css specified CSS value', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
      // Returns background color of the element
      let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
      
      assert.equal(value, "rgba(0, 128, 0, 1)");
    });
    
    it('Should return the css specified CSS value', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
      // Returns text of the element
      let text = await driver.findElement(By.id('justanotherLink')).getText();
      
      assert.equal(text, "Just another link.");
    });
    
    after(async () => await driver.quit());
  });
```

```kotlin
// Navigate to Url
driver.get("https://www.selenium.dev/selenium/web/colorPage.html")

// Retrieves the computed style property 'color' of linktext
val cssValue = driver.findElement(By.id("namedColor")).getCssValue("background-color")

  
```

```java
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L58-L60)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    text = driver.find_element(By.TAG_NAME, "h1").text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L41)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L53-L55)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    text = driver.find_element(xpath: '//h1').text
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L43)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L84-L86)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to URL
driver.get("https://www.selenium.dev/selenium/web/linked_image.html")

// retrieves the text of the element
val text = driver.findElement(By.id("justanotherlink")).getText()
  
```

```java
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/elements/InformationTest.java#L64-L68)

##### /examples/java/src/test/java/dev/selenium/elements/InformationTest.java

```java
package dev.selenium.elements;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.Rectangle;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;

public class InformationTest {

    @Test
    public void informationWithElements() {

        WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/inputs.html");

        // isDisplayed
        // Get boolean value for is element display
        boolean isEmailVisible = driver.findElement(By.name("email_input")).isDisplayed();
        assertTrue(isEmailVisible);

        // isEnabled
        // returns true if element is enabled
        boolean isEnabledButton = driver.findElement(By.name("button_input")).isEnabled();
        assertTrue(isEnabledButton);

        // isSelected
        // returns true if element is checked
        boolean isSelectedCheck = driver.findElement(By.name("checkbox_input")).isSelected();
        assertTrue(isSelectedCheck);

        // TagName
        // returns TagName of the element
        String tagNameInp = driver.findElement(By.name("email_input")).getTagName();
        assertEquals("input", tagNameInp);

        // GetRect
        // Returns height, width, x and y coordinates referenced element
        Rectangle res = driver.findElement(By.name("range_input")).getRect();
        // Rectangle class provides getX,getY, getWidth, getHeight methods
        assertEquals(10, res.getX());

        // Retrieves the computed style property 'font-size' of field
        String cssValue = driver.findElement(By.name("color_input")).getCssValue("font-size");
        assertEquals(cssValue, "13.3333px");


        // GetText
        // Retrieves the text of the element
        String text = driver.findElement(By.tagName("h1")).getText();
        assertEquals(text, "Testing Inputs");


        // FetchAttributes
        // identify the email text box
        WebElement emailTxt = driver.findElement(By.name(("email_input")));
        // fetch the value property associated with the textbox
        String valueInfo = emailTxt.getAttribute("value");
        assertEquals(valueInfo, "admin@localhost");

        driver.quit();
    }

}
```

```py
    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/elements/test_information.py#L44-L46)

##### /examples/python/tests/elements/test\_information.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By

import pytest


def test_informarion():
    # Initialize WebDriver
    driver = webdriver.Chrome()
    driver.implicitly_wait(0.5)

    driver.get("https://www.selenium.dev/selenium/web/inputs.html")

    # isDisplayed
    is_email_visible = driver.find_element(By.NAME, "email_input").is_displayed()
    assert is_email_visible == True

    # isEnabled
    is_enabled_button = driver.find_element(By.NAME, "button_input").is_enabled()
    assert is_enabled_button == True

    # isSelected
    is_selected_check = driver.find_element(By.NAME, "checkbox_input").is_selected()
    assert is_selected_check == True

    # TagName
    tag_name_inp = driver.find_element(By.NAME, "email_input").tag_name
    assert tag_name_inp == "input"

    # GetRect
    rect = driver.find_element(By.NAME, "range_input").rect
    assert rect["x"] == 10

    # CSS Value
    css_value = driver.find_element(By.NAME, "color_input").value_of_css_property(
        "font-size"
    )
    assert css_value == "13.3333px"

    # GetText
    text = driver.find_element(By.TAG_NAME, "h1").text
    assert text == "Testing Inputs"

    # FetchAttributes
    email_txt = driver.find_element(By.NAME, "email_input")
    value_info = email_txt.get_attribute("value")
    assert value_info == "admin@localhost"
```

```cs
            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Elements/InformationTest.cs#L58-L62)

##### /examples/dotnet/SeleniumDocs/Elements/InformationTest.cs

```cs
using System;
using System.Drawing;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;


namespace SeleniumDocs.Elements
{
    [TestClass]
    public class InformationTest 
    {
        [TestMethod]
        public void TestInformationCommands(){
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/inputs.html";
            // isDisplayed        
            // Get boolean value for is element display
            bool isEmailVisible = driver.FindElement(By.Name("email_input")).Displayed;
            Assert.AreEqual(isEmailVisible, true);

            // isEnabled
            // returns true if element is enabled else returns false
            bool isEnabledButton = driver.FindElement(By.Name("button_input")).Enabled;
            Assert.AreEqual(isEnabledButton, true);

            // isSelected
            // returns true if element is checked else returns false
            bool isSelectedCheck = driver.FindElement(By.Name("checkbox_input")).Selected;
            Assert.AreEqual(isSelectedCheck, true);

            // TagName
            // returns TagName of the element
            string tagNameInp = driver.FindElement(By.Name("email_input")).TagName;
            Assert.AreEqual(tagNameInp, "input");

            // Get Location and Size
            // Get Location
            IWebElement rangeElement = driver.FindElement(By.Name("range_input"));
            Point point = rangeElement.Location;
            Assert.IsNotNull(point.X);
            // Get Size
            int height=rangeElement.Size.Height;
            Assert.IsNotNull(height);

            // Retrieves the computed style property 'font-size' of field
            string cssValue = driver.FindElement(By.Name("color_input")).GetCssValue("font-size");
            Assert.AreEqual(cssValue, "13.3333px");

            // GetText
            // Retrieves the text of the element
            string text = driver.FindElement(By.TagName("h1")).Text;
            Assert.AreEqual(text, "Testing Inputs");

            // FetchAttributes
            // identify the email text box
            IWebElement emailTxt = driver.FindElement(By.Name("email_input"));
            // fetch the value property associated with the textbox
            string valueInfo = emailTxt.GetAttribute("value");
            Assert.AreEqual(valueInfo, "admin@localhost");
            
            //Quit the driver
            driver.Quit();
        }
    }
}
```

```rb
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/elements/information_spec.rb#L48)

##### /examples/ruby/spec/elements/information\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Element Information' do
  let(:driver) { start_session }
  let(:url) { 'https://www.selenium.dev/selenium/web/inputs.html' }

  before { driver.get(url) }

  it 'checks if an element is displayed' do
    displayed_value = driver.find_element(name: 'email_input').displayed?
    expect(displayed_value).to be_truthy
  end

  it 'checks if an element is enabled' do
    enabled_value = driver.find_element(name: 'email_input').enabled?
    expect(enabled_value).to be_truthy
  end

  it 'checks if an element is selected' do
    selected_value = driver.find_element(name: 'email_input').selected?
    expect(selected_value).to be_falsey
  end

  it 'gets the tag name of an element' do
    tag_name = driver.find_element(name: 'email_input').tag_name
    expect(tag_name).not_to be_empty
  end

  it 'gets the size and position of an element' do
    size = driver.find_element(name: 'email_input').size
    expect(size.width).to be_positive
    expect(size.height).to be_positive
  end

  it 'gets the css value of an element' do
    css_value = driver.find_element(name: 'email_input').css_value('background-color')
    expect(css_value).not_to be_empty
  end

  it 'gets the text of an element' do
    text = driver.find_element(xpath: '//h1').text
    expect(text).to eq('Testing Inputs')
  end

  it 'gets the attribute value of an element' do
    attribute_value = driver.find_element(name: 'number_input').attribute('value')
    expect(attribute_value).not_to be_empty
  end
end
```

```js
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/elements/information.spec.js#L55-L59)

##### /examples/javascript/test/elements/information.spec.js

```js
const {By, Builder} = require('selenium-webdriver');
const assert = require("assert");

describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  beforeEach(async ()=> {
    await driver.get('https://www.selenium.dev/selenium/web/inputs.html');
  })
  
  it('Check if element is displayed', async function () {
    // Resolves Promise and returns boolean value
    let result =  await driver.findElement(By.name("email_input")).isDisplayed();
    
    assert.equal(result,true);
  });
  
  it('Check if button is enabled', async function () {
    // Resolves Promise and returns boolean value
    let element =  await driver.findElement(By.name("button_input")).isEnabled();
  
    assert.equal(element, true);
  });
  
  it('Check if checkbox is selected', async function () {
    // Returns true if element ins checked else returns false
    let isSelected = await driver.findElement(By.name("checkbox_input")).isSelected();
  
    assert.equal(isSelected, true);
  });
  
  it('Should return the tagname', async function () {
    // Returns TagName of the element
    let value = await driver.findElement(By.name('email_input')).getTagName();
  
    assert.equal(value, "input");
  });
  
  it('Should be able to fetch element size and position ', async function () {
    // Returns height, width, x and y position of the element
    let object = await driver.findElement(By.name('range_input')).getRect();
    
    assert.ok(object.height!==null)
    assert.ok(object.width!==null)
    assert.ok(object.y!==null)
    assert.ok(object.x!==null)
    
  });
  
  it('Should be able to fetch attributes and properties ', async function () {
    // identify the email text box
    const emailElement = await driver.findElement(By.xpath('//input[@name="email_input"]'));
    
    //fetch the attribute "name" associated with the textbox
    const nameAttribute = await emailElement.getAttribute("name");
  
    assert.equal(nameAttribute, "email_input")
  });
  
  after(async () => await driver.quit());
});


describe('Element Information Test', function () {
  let driver;
  
  before(async function () {
    driver = await new Builder().forBrowser('chrome').build();
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/colorPage.html');
    // Returns background color of the element
    let value = await driver.findElement(By.id('namedColor')).getCssValue('background-color');
    
    assert.equal(value, "rgba(0, 128, 0, 1)");
  });
  
  it('Should return the css specified CSS value', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/linked_image.html');
    // Returns text of the element
    let text = await driver.findElement(By.id('justanotherLink')).getText();
    
    assert.equal(text, "Just another link.");
  });
  
  after(async () => await driver.quit());
});
```

```kotlin
// Navigate to URL
driver.get("https://www.selenium.dev/selenium/web/inputs.html")

//fetch the value property associated with the textbox
val attr = driver.findElement(By.name("email_input")).getAttribute("value")
  
```

Last modified April 17, 2026: [Update code block references in documentation (#2613) (5d614fcd479)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/5d614fcd479d384003f8e4dd949f6a9f4cada711)

----
url: https://www.selenium.dev/pt-br/documentation/test_practices/discouraged/file_downloads/
----

# Downloads de arquivo

Embora seja possível iniciar um download clicando em um link com um navegador sob o controle do Selenium, a API não expõe o progresso do download, tornando-o menos do que ideal para testar arquivos baixados. Isso ocorre porque o download de arquivos não é considerado um aspecto importante de emular a interação do usuário com a plataforma da web. Em vez disso, encontre o link usando Selenium (e todos os cookies necessários) e passe este cookie para uma biblioteca de solicitação HTTP como [curl](https://curl.se/).

O [driver HtmlUnit](https://github.com/SeleniumHQ/htmlunit-driver) pode baixar anexos acessando-os como fluxos de entrada, implementando o [AttachmentHandler](https://htmlunit.sourceforge.io/apidocs/com/gargoylesoftware/htmlunit/attachment/AttachmentHandler.html). O AttachmentHandler pode ser adicionado ao WebClient [HtmlUnit](https://htmlunit.sourceforge.io/).

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/bidi/w3c/input/
----

# Browsing Context

```java
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ActionsTest.java#L41-L44)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ActionsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Input;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.interactions.Actions;

class ActionsTest extends BaseTest {
    private Input input;

    private String windowHandle;

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        windowHandle = driver.getWindowHandle();
        input = new Input(driver);
    }

    @Test
    void canPerformInputActions() {
        driver.get("https://www.selenium.dev/selenium/web/formSelectionPage.html");

        List<WebElement> options = driver.findElements(By.tagName("option"));

        Actions actions = new Actions(driver);
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());

        WebElement showButton = driver.findElement(By.name("showselected"));
        showButton.click();

        WebElement resultElement = driver.findElement(By.id("result"));
        Assertions.assertTrue(resultElement.getText().contains("roquefort parmigiano cheddar"));
        }

    @Test
    void canPerformReleaseAction() {
        driver.get("https://www.selenium.dev/selenium/web/bidi/release_action.html");

        WebElement inputTextBox = driver.findElement(By.id("keys"));

        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);

        List<Map<String, Object>> events =
                (List<Map<String, Object>>)
                        ((JavascriptExecutor) driver).executeScript("return allEvents.events");
        Assertions.assertEquals("KeyB", events.get(0).get("code"));
        Assertions.assertEquals("KeyA", events.get(1).get("code"));
        }
    }
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/input.spec.js#L27-L29)

##### /examples/javascript/test/bidirectional/input.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, Key, Builder} = require("selenium-webdriver")
const Input = require('selenium-webdriver/bidi/input')

describe('Input module', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can perform input action', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/formSelectionPage.html')

    let options = await driver.findElements(By.tagName('option'))

    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)

    let showButton = await driver.findElement(By.name('showselected'))
    showButton.click()

    let resultElement = await driver.findElement(By.id('result'))
    await resultElement.getText().then(function (text) {
      assert(text.includes('oquefort parmigiano cheddar'), `text is: ${text}`)
    })
  })

  it('can execute release in browsing context', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/bidi/release_action.html')

    let inputTextBox = await driver.findElement(By.id('keys'))

    await driver.executeScript('arguments[0].focus()', inputTextBox)

    const actions = driver.actions().keyDown('a').keyDown('b').getSequences()

    await input.perform(browsingContextId, actions)

    await driver.executeScript('resetEvents()')

    await input.release(browsingContextId)

    const events = await driver.executeScript('return allEvents.events')

    assert.strictEqual(events[0].code, 'KeyB')
    assert.strictEqual(events[1].code, 'KeyA')
  })
})
```

```java
        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/ActionsTest.java#L59-L65)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/ActionsTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.Keys;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.bidi.module.Input;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.interactions.Actions;

class ActionsTest extends BaseTest {
    private Input input;

    private String windowHandle;

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
        windowHandle = driver.getWindowHandle();
        input = new Input(driver);
    }

    @Test
    void canPerformInputActions() {
        driver.get("https://www.selenium.dev/selenium/web/formSelectionPage.html");

        List<WebElement> options = driver.findElements(By.tagName("option"));

        Actions actions = new Actions(driver);
        Actions selectThreeOptions =
                actions.click(options.get(1)).keyDown(Keys.SHIFT).click(options.get(3)).keyUp(Keys.SHIFT);

        input.perform(windowHandle, selectThreeOptions.getSequences());

        WebElement showButton = driver.findElement(By.name("showselected"));
        showButton.click();

        WebElement resultElement = driver.findElement(By.id("result"));
        Assertions.assertTrue(resultElement.getText().contains("roquefort parmigiano cheddar"));
        }

    @Test
    void canPerformReleaseAction() {
        driver.get("https://www.selenium.dev/selenium/web/bidi/release_action.html");

        WebElement inputTextBox = driver.findElement(By.id("keys"));

        Actions sendLowercase =
                new Actions(driver).keyDown(inputTextBox, "a").keyDown(inputTextBox, "b");

        input.perform(windowHandle, sendLowercase.getSequences());
        ((JavascriptExecutor) driver).executeScript("resetEvents()");

        input.release(windowHandle);

        List<Map<String, Object>> events =
                (List<Map<String, Object>>)
                        ((JavascriptExecutor) driver).executeScript("return allEvents.events");
        Assertions.assertEquals("KeyB", events.get(0).get("code"));
        Assertions.assertEquals("KeyA", events.get(1).get("code"));
        }
    }
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Selenium v4.17](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.17.0)

```js
    await input.release(browsingContextId)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/input.spec.js#L55)

##### /examples/javascript/test/bidirectional/input.spec.js

```js
const assert = require("assert")
const firefox = require('selenium-webdriver/firefox')
const {By, Key, Builder} = require("selenium-webdriver")
const Input = require('selenium-webdriver/bidi/input')

describe('Input module', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('can perform input action', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/formSelectionPage.html')

    let options = await driver.findElements(By.tagName('option'))

    const actions = driver.actions().click(options[1]).keyDown(Key.SHIFT).click(options[3]).keyUp(Key.SHIFT).getSequences()

    await input.perform(browsingContextId, actions)

    let showButton = await driver.findElement(By.name('showselected'))
    showButton.click()

    let resultElement = await driver.findElement(By.id('result'))
    await resultElement.getText().then(function (text) {
      assert(text.includes('oquefort parmigiano cheddar'), `text is: ${text}`)
    })
  })

  it('can execute release in browsing context', async function () {
    const browsingContextId = await driver.getWindowHandle()
    const input = await Input(driver)
    await driver.get('https://www.selenium.dev/selenium/web/bidi/release_action.html')

    let inputTextBox = await driver.findElement(By.id('keys'))

    await driver.executeScript('arguments[0].focus()', inputTextBox)

    const actions = driver.actions().keyDown('a').keyDown('b').getSequences()

    await input.perform(browsingContextId, actions)

    await driver.executeScript('resetEvents()')

    await input.release(browsingContextId)

    const events = await driver.executeScript('return allEvents.events')

    assert.strictEqual(events[0].code, 'KeyB')
    assert.strictEqual(events[1].code, 'KeyA')
  })
})
```

----
url: https://www.selenium.dev/ja/documentation/test_practices/encouraged/test_independency/
----

# テストの独立性

各テストを独自のユニットとして記述します。 他のテストに依存しない方法でテストを記述してください。

公開後にモジュールとしてWebサイトに表示されるカスタムコンテンツを作成できるコンテンツ管理システム（CMS）があり、CMSとアプリケーション間の同期に時間がかかる場合があるとします。

モジュールをテストする間違った方法は、1つのテストでコンテンツが作成および公開され、別のテストでモジュールをチェックすることです。 コンテンツは公開後、他のテストですぐに利用できない可能性があるため、この方法はふさわしくありません。

代わりに、影響を受けるテスト内でオン/オフできるスタブコンテンツを作成し、それをモジュールの検証に使用できます。 ただし、コンテンツの作成については、別のテストを行うことができます。

----
url: https://www.selenium.dev/pt-br/_print/documentation/legacy/selenium_ide/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/pt-br/documentation/legacy/selenium_ide/).

# Selenium IDE Legado

* 1: [HTML runner](#pg-32119150ec982f9d853272754ecb1138)

```html
<tr>
    <td>Command</td>
    <td>target (locator)</td>
    <td>Value</td>
</tr>
```

|            |              |       |
| ---------- | ------------ | ----- |
| verifyText | //div//a\[2] | Login |

Os parâmetros nem sempre são necessários, depende do comando. Em alguns casos ambos são necessários, em outros um parâmetro é necessário, e ainda em outros, o comando pode não ter nenhum parâmetro. Aqui estão mais alguns exemplos:

|                   |             |                         |
| ----------------- | ----------- | ----------------------- |
| goBackAndWait     |             |                         |
| verifyTextPresent |             | Welcome to My Home Page |
| type              | id=phone    | (555) 666-7066          |
| type              | id=address1 | ${myVariableAddress}    |

```html
<table>
    <tr><td>open</td><td>/download/</td><td></td></tr>
    <tr><td>assertTitle</td><td></td><td>Downloads</td></tr>
    <tr><td>verifyText</td><td>//h2</td><td>Downloads</td></tr>
</table>
```

Renderizado como uma tabela em um navegador, seria assim:

|             |            |           |
| ----------- | ---------- | --------- |
| open        | /download/ |           |
| assertTitle |            | Downloads |
| verifyText  | //h2       | Downloads |

A sintaxe HTML Selenese pode ser usada para escrever e executar testes sem exigir conhecimento de uma linguagem de programação. Com um conhecimento básico de Selenese e Selenium-IDE você pode produzir e executar casos de teste rapidamente.

## Suítes de Teste

Uma suíte de testes é uma coleção de testes. Frequentemente, você executará todos os testes em uma suite de teste como um trabalho em lote contínuo.

Ao usar a Selenium-IDE, as suítes de testes também podem ser definidas usando um arquivo HTML simples. A sintaxe novamente é simples. Uma tabela HTML define uma lista de testes onde cada linha define o caminho do sistema de arquivos para cada teste. Um exemplo diz tudo.

```html
<html>
<head>
<title>Test Suite Function Tests - Priority 1</title>
</head>
<body>
<table>
  <tr><td><b>Suite Of Tests</b></td></tr>
  <tr><td><a href="./Login.html">Login</a></td></tr>
  <tr><td><a href="./SearchValues.html">Test Searching for Values</a></td></tr>
  <tr><td><a href="./SaveValues.html">Test Save</a></td></tr>
</table>
</body>
</html>
```

| Command     | Target     | Value        |
| ----------- | ---------- | ------------ |
| open        | /download/ |              |
| assertTitle |            | Downloads    |
| verifyText  | //h2       | Downloads    |
| assertTable | 1.2.1      | Selenium IDE |
| verifyTable | 1.2.2      | June 3, 2008 |
| verifyTable | 1.2.3      | 1.0 beta 2   |

O exemplo acima primeiro abre uma página e, em seguida, faz uma asserção para saber se a página correta é carregada comparando o título com o valor esperado. Só se passar, o seguinte comando será executado e verificará se o texto está presente na localização esperada. O caso de teste, então, faz uma asserção para saber se a primeira coluna na segunda linha da primeira tabela contém o valor esperado, e somente se este for aprovado as células restantes nessa linha serão “verificadas”.

### **verifyTextPresent**

O comando `verifyTextPresent` é usado para verificar se existe um texto específico em algum lugar na página. Leva um único argumento - o texto a ser verificado. Por exemplo:

| Command           | Target             | Value |
| ----------------- | ------------------ | ----- |
| verifyTextPresent | Marketing Analysis |       |

Isso faria com que o Selenium procurasse e verificasse que a string de texto “Marketing Analysis” aparece em algum lugar na página que está sendo testada. Use verifyTextPresent quando você está interessado apenas no próprio texto estar presente na página. Não use isso quando você também precisa testar onde o texto está na página.

### **verifyElementPresent**

Use este comando quando precisar testar a presença de um elemento de UI específico, em vez de seu conteúdo. Esta verificação não verifica o texto, apenas a tag HTML. Um uso comum é verificar a presença de uma imagem.

| Command              | Target      | Value |
| -------------------- | ----------- | ----- |
| verifyElementPresent | //div/p/img |       |

Este comando verifica se uma imagem, especificada pela existência de uma tag HTML `<img>`, está presente na página e aparece após uma tag `<div>` e uma tag `<p>`. O primeiro (e único) parâmetro é um localizador para informar o comando Selenese de como encontrar o elemento. Os localizadores são explicados na próxima seção.

`verifyElementPresent` pode ser usado para verificar a existência de qualquer tag HTML dentro da página. Você pode verificar a existência de links, parágrafos, divisões `<div>`, etc. Aqui estão mais alguns exemplos.

| Command              | Target                        | Value |
| -------------------- | ----------------------------- | ----- |
| verifyElementPresent | //div/p                       |       |
| verifyElementPresent | //div/a                       |       |
| verifyElementPresent | id=Login                      |       |
| verifyElementPresent | link=Go to Marketing Research |       |
| verifyElementPresent | //a\[2]                       |       |
| verifyElementPresent | //head/title                  |       |

Esses exemplos ilustram a variedade de maneiras pelas quais um elemento de UI pode ser testado. Novamente, os localizadores são explicados na próxima seção.

### **verifyText**

Use `verifyText` quando o texto e seu elemento de UI devem ser testados. verifyText deve usar um localizador. Se você escolher um localizador *XPath* ou *DOM*, você pode verificar se um texto específico aparece em um local específico na página em relação a outro componente na página.

| Command    | Target              | Value                                                               |
| ---------- | ------------------- | ------------------------------------------------------------------- |
| verifyText | //table/tr/td/div/p | This is my text and it occurs right after the div inside the table. |

## Localizando elementos

Para muitos comandos do Selenium, um alvo é necessário. Este alvo identifica um elemento no conteúdo do aplicativo da web, e consiste na estratégia de localização seguida pela localização no formato `locatorType = location`. O tipo de localizador pode ser omitido em muitos casos. Os vários tipos de localizadores são explicados abaixo com exemplos para cada um.

### Localizando pelo Identificador

Este é provavelmente o método mais comum de localização de elementos e é o padrão quando nenhum tipo de localizador reconhecido é usado. Com esta estratégia, o primeiro elemento com o valor do atributo id correspondente ao local será usado. E se nenhum elemento tem um atributo *id* correspondente, então o primeiro elemento com um atributo *name* correspondente ao local será usado.

Por exemplo, o código fonte da sua página pode ter atributos id e name do seguinte modo:

```html
  <html>
   <body>
    <form id="loginForm">
     <input name="username" type="text" />
     <input name="password" type="password" />
     <input name="continue" type="submit" value="Login" />
    </form>
   </body>
  <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
    </body>
   <html>
```

* `id=loginForm` (3)

### Localizando pelo *name*

O tipo Localizador de Nome irá localizar o primeiro elemento com um atributo *name* correspondente. Se vários elementos tiverem o mesmo valor para um atributo *name*, então você pode usar filtros para refinar ainda mais sua estratégia de localização. O tipo de filtro padrão é *value* (correspondendo ao atributo *value*).

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
  <html>
   <body>
    <p>Are you sure you want to do this?</p>
    <a href="continue.html">Continue</a> 
    <a href="cancel.html">Cancel</a>
  </body>
  <html>
```

* `link=Continue` (4)
* `link=Cancel` (5)

### Localizando pelo DOM

O Document Object Model representa um documento HTML e pode ser acessado usando JavaScript. Esta estratégia de localização usa um JavaScript que representa um elemento na página, que pode ser simplesmente a localização do elemento usando a notação hierárquica.

Uma vez que apenas os localizadores `dom` começam com “document”, não é necessário incluir o rótulo `dom=` ao especificar um localizador DOM.

```html
   <html>
    <body>
     <form id="loginForm">
      <input name="username" type="text" />
      <input name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

```html
   <html>
    <body>
     <form id="loginForm">
      <input class="required" name="username" type="text" />
      <input class="required passfield" name="password" type="password" />
      <input name="continue" type="submit" value="Login" />
      <input name="continue" type="button" value="Clear" />
     </form>
   </body>
   <html>
```

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | glob:\*Film\*Television\*             |       |

O título real da página acessada clicando no link era “De Anza Film And Television Department - Menu”. Usando um padrão em vez do texto exato, o `verifyTitle` vai passar enquanto as duas palavras “Film” e “Television” aparecerem (nessa ordem) em qualquer lugar no título da página. Por exemplo, se o proprietário da página encurtar o título apenas para “Film & Television Department”, o teste ainda seria aprovado. Usar um padrão para um link e um teste simples de que o link funcionou (como o `verifyTitle` acima faz) pode reduzir bastante a manutenção de tais casos de teste.

#### Padrão de Expressões Regulares

Os padrões de *expressão regular* são os mais poderosos dos três tipos de padrões que o Selenese suporta. Expressões regulares também são suportados pela maioria das linguagens de programação de alto nível, muitos editores de texto e uma série de ferramentas, incluindo utilitários **grep**, **sed** e **awk** da linha de comando Linux / Unix. Em Selenese, padrões de expressão regular permitem que um usuário execute muitas tarefas que iriam ser muito difíceis de outra forma. Por exemplo, suponha que seu teste precise garantir que uma determinada célula da tabela contivesse nada além de um número. `regexp:[0-9]+` é um padrão simples que corresponderá a um número decimal de qualquer comprimento.

Enquanto os padrões de Globbing do Selenese suportam apenas o **\*** e **\[ ]** (classe de caracteres), os padrões de expressão regular Selenese oferecem a mesma ampla gama de caracteres especiais que existem em JavaScript. Abaixo está um subconjunto desses caracteres especiais:

| PATTERN | MATCH                                                                     |
| ------- | ------------------------------------------------------------------------- |
| .       | qualquer caractere isolado                                                |
| \[ ]    | classe de caracteres: qualquer caractere definido dentros dos colchetes   |
| \*      | quantificação: 0 ou mais do caractere anterior (ou grupo)                 |
| +       | quantificação: 1 ou mais do caractere anterior (ou grupo)                 |
| ?       | quantificação: 0 ou 1 do caractere anterior (ou grupo)                    |
| {1,5}   | quantificação: 1 até 5 repetições do caractere anterior (ou grupo)        |
| \|      | alternação: o caractere/grupo na esquerda OU o caractere/grupo na direita |
| ( )     | agrupamento: normalmente usado com alternação e/ou quantificação          |

Os padrões de expressão regular em Selenese precisam ser prefixados com `regexp:` ou `regexpi:`. O primeiro é sensível a maiúsculas e minúsculas; o último não faz distinção entre maiúsculas e minúsculas.

Alguns exemplos ajudarão a esclarecer como os padrões de expressão regular podem ser usados com comandos Selenese. O primeiro usa o que é provavelmente o padrão de expressão regular mais comumente usado - **.\*** (“ponto estrela”). Esta sequência de dois caracteres pode ser traduzida como “0 ou mais ocorrências de qualquer caractere” ou, mais simplesmente, “qualquer coisa ou nada.” É o equivalente do padrão globbing de um caractere **\*** (um único asterisco).

| Command     | Target                                | Value |
| ----------- | ------------------------------------- | ----- |
| click       | link=glob:Film\*Television Department |       |
| verifyTitle | regexp:.\*Film.\*Television.\*        |       |

O exemplo acima é funcionalmente equivalente ao exemplo anterior que usou padrões de globbing para este mesmo teste. As únicas diferenças são o prefixo (**regexp:** em vez de **glob:**) e o padrão “qualquer coisa ou nada” (**.\*** em vez de apenas **\***).

O exemplo mais complexo abaixo testa que a página de clima do Yahoo! para Anchorage, Alasca, contém informações sobre o horário do nascer do sol:

| Command           | Target                                            | Value |
| ----------------- | ------------------------------------------------- | ----- |
| open              | <http://weather.yahoo.com/forecast/USAK0012.html> |       |
| verifyTextPresent | regexp:Sunrise: \*\[0-9]{1,2}:\[0-9]{2} \[ap]m    |       |

Vamos examinar a expressão regular acima em partes:

|              |                                                         |
| ------------ | ------------------------------------------------------- |
| `Sunrise: *` | A string **Sunrise:** seguida por 0 ou mais espaços     |
| `[0-9]{1,2}` | 1 ou 2 dígitos (para a hora do dia)                     |
| `:`          | O caractere **:** (sem caracteres especiais envolvidos) |
| `[0-9]{2}`   | 2 dígitos (para os minutos) seguidos de um espaço       |
| `[ap]m`      | “a” ou “p” seguido por “m” (am ou pm)                   |

#### Padrão Exato

O tipo de padrão **exato** do Selenium é de utilidade marginal. Ele não usa nenhum caractere especial. Então, se você precisasse procurar um caractere de asterisco real (que é especial para globbing e padrões de expressão regular), o padrão **exato** seria uma maneira fazer isso. Por exemplo, se você quiser selecionar um item rotulado “Real\*” em uma lista suspensa, o código a seguir pode funcionar ou não. O asterisco no padrão `glob:Real*` irá corresponder a qualquer coisa ou a nada. Portanto, se houvesse uma opção de seleção anterior rotulada “Números reais”, ser a opção selecionada em vez da opção “Real\*”.

| Command | Target   | Value        |
| ------- | -------- | ------------ |
| select  | //select | glob:Real \* |

A fim de garantir que o item “Real\*” seja selecionado, o prefixo `exact:` pode ser usado para criar um padrão **exato** conforme mostrado abaixo:

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| select  | //select | exact:Real \* |

Mas o mesmo efeito pode ser alcançado escapando o asterisco em um padrão de expressão regular:

| Command | Target   | Value            |
| ------- | -------- | ---------------- |
| select  | //select | regexp:Real \\\* |

| Command | Target            | Value |
| ------- | ----------------- | ----- |
| store   | <paul@mysite.org> |       |

Posteriormente em seu script, você desejará usar o valor armazenado de sua variável. Para acessar o valor de uma variável, coloque a variável em colchetes ({}) e preceda-a com um cifrão como a seguir.

| Command    | Target  | Value         |
| ---------- | ------- | ------------- |
| verifyText | //div/p | \\${userName} |

Um uso comum de variáveis é armazenar a entrada para um campo input.

| Command | Target   | Value         |
| ------- | -------- | ------------- |
| type    | id=login | \\${userName} |

| Command         | Target                                         | Value       |
| --------------- | ---------------------------------------------- | ----------- |
| store           | 10                                             | hits        |
| storeXpathCount | //blockquote                                   | blockquotes |
| storeEval       | storedVars\[‘hits’].storedVars\[‘blockquotes’] | paragraphs  |

Este próximo exemplo ilustra como um snippet de JavaScript pode incluir chamadas para métodos, neste caso, os métodos `toUpperCase` e `toLowerCase`do objeto JavaScript String.

| Command   | Target                            | Value |
| --------- | --------------------------------- | ----- |
| store     | Edith Wharton                     | name  |
| storeEval | storedVars\[’name’].toUpperCase() | uc    |
| storeEval | storedVars\[’name’].toUpperCase() | lc    |

#### Usando JavaScript com parâmetros não-script

JavaScript também pode ser usado para ajudar a gerar valores para parâmetros, mesmo quando o parâmetro não é especificado para ser do tipo **script**. No entanto, neste caso, uma sintaxe especial é necessária - o parâmetro *inteiro* deve ser prefixado por `javascript{` com um `}` final, que envolve o snippet JavaScript, como em `javascript{*yourCodeHere*}`. Abaixo está um exemplo em que o segundo parâmetro do comando `type`

* `value` - é gerado através do código JavaScript usando esta sintaxe especial:

| Command | Target            | Value                                                 |
| ------- | ----------------- | ----------------------------------------------------- |
| store   | league of nations | searchString                                          |
| type    | q                 | javascript{storedVars\[‘searchString’].toUpperCase()} |

## *echo* - O comando de print do Selenese

Selenese tem um comando simples que permite imprimir texto para a saída do seu teste. Isso é útil para fornecer notas de progresso informativas em seu teste que são exibidas no console durante a execução. Essas notas também podem ser usadas para fornecer contexto em seus relatórios de resultados de teste, o que pode ser útil para descobrir onde existe um defeito em uma página, caso seu teste encontre um problema. Finalmente, declarações echo podem ser usadas para imprimir o conteúdo de variáveis Selenium.

| Command | Target                    | Value |
| ------- | ------------------------- | ----- |
| echo    | Testing page footer now.  |       |
| echo    | Username is \\${userName} |       |

## Alertas, Popups e Múltiplas Janelas

Suponha que você esteja testando uma página semelhante a esta.

```html
  <!DOCTYPE HTML>
  <html>
  <head>
    <script type="text/javascript">
      function output(resultText){
        document.getElementById('output').childNodes[0].nodeValue=resultText;
      }

      function show_confirm(){
        var confirmation=confirm("Chose an option.");
        if (confirmation==true){
          output("Confirmed.");
        }
        else{
          output("Rejected!");
        }
      }
      
      function show_alert(){
        alert("I'm blocking!");
        output("Alert is gone.");
      }
      function show_prompt(){
        var response = prompt("What's the best web QA tool?","Selenium");
        output(response);
      }
      function open_window(windowName){
        window.open("newWindow.html",windowName);
      }
      </script>
  </head>
  <body>

    <input type="button" id="btnConfirm" onclick="show_confirm()" value="Show confirm box" />
    <input type="button" id="btnAlert" onclick="show_alert()" value="Show alert" />
    <input type="button" id="btnPrompt" onclick="show_prompt()" value="Show prompt" />
    <a href="newWindow.html" id="lnkNewWindow" target="_blank">New Window Link</a>
    <input type="button" id="btnNewNamelessWindow" onclick="open_window()" value="Open Nameless Window" />
    <input type="button" id="btnNewNamedWindow" onclick="open_window('Mike')" value="Open Named Window" />

    <br />
    <span id="output">
    </span>
  </body>
  </html>
```

O usuário deve responder às caixas de alerta / confirmação, bem como mover o foco para as novas janelas pop-up abertas. Felizmente, o Selenium pode cobrir pop-ups de JavaScript.

Mas antes de começarmos a abordar alertas / confirmações / solicitações em detalhes individuais, é útil compreender a semelhança entre eles. Alertas, caixas de confirmação e todos os prompts têm variações do seguinte

| Command                   | Description                                                              |
| ------------------------- | ------------------------------------------------------------------------ |
| assertFoo(pattern)        | gera erro se o padrão não corresponder ao texto do pop-up                |
| assertFooPresent          | gera erro se o pop-up estiver presente                                   |
| assertFooNotPresent       | gera um erro se algum pop-up não estiver presente                        |
| storeFoo(variable)        | armazena o texto do pop-up em uma variável                               |
| storeFooPresent(variable) | armazena o texto do pop-up em uma variável e retorna verdadeiro ou falso |

Ao executar no Selenium, pop-ups de JavaScript não aparecerão. Isto é porque as chamadas de função são realmente substituídas em tempo de execução pelo próprio JavaScript do Selenium. No entanto, só porque você não pode ver o pop-up, não significa que você não tem que lidar com isso. Para lidar com um pop-up, você deve chamar sua função `assertFoo(padrão)`. Se você falhar em fazer a asserção da presença de um pop-up, seu próximo comando será bloqueado e você obterá um erro semelhante ao seguinte `[error] Error: There was an unexpected Confirmation! [Chose an option.]`

### Alertas

Vamos começar com alertas porque eles são os pop-ups mais simples de lidar. Para começar, abra o exemplo de HTML acima em um navegador e clique no botão “Show alert”. Você vai observar que, depois de fechar o alerta, o texto “Alert is gone.” é exibido na página. Agora execute as mesmas etapas com a gravação da Selenium IDE e verifique que o texto é adicionado após fechar o alerta. Seu teste será parecido com este:

| Command           | Target         | Value |
| ----------------- | -------------- | ----- |
| open              | /              |       |
| click             | btnAlert       |       |
| assertAlert       | I’m blocking!  |       |
| verifyTextPresent | Alert is gone. |       |

Você pode estar pensando: “Isso é estranho, nunca tentei fazer uma asserção nesse alerta.” Mas isso é a Selenium-IDE manipulando e fechando o alerta para você. Se você remover essa etapa e repetir o teste você obterá o seguinte erro `[error] Error: There was an unexpected Alert! [I'm blocking!]`. Você deve incluir uma asserção do alerta para reconhecer sua presença.

Se você apenas deseja verificar que um alerta está presente, mas não sabe ou não se importa o texto que ele contém, você pode usar `assertAlertPresent`. Isso retornará verdadeiro ou falso, sendo que falso faz o teste parar.

### Confirmações

As confirmações se comportam da mesma forma que os alertas, com `assertConfirmation` e `assertConfirmationPresent` oferecendo as mesmas características de suas contrapartes de alerta. No entanto, por padrão, o Selenium selecionará OK quando uma confirmação for exibida. Tente gravar clicando no botão “Show confirm box” na página de amostra, mas clique no botão “Cancel” no pop-up e, em seguida, confirme o texto de saída. Seu teste pode ser semelhante a este:

| Command                        | Target            | Value |
| ------------------------------ | ----------------- | ----- |
| open                           | /                 |       |
| click                          | btnConfirm        |       |
| chooseCancelOnNextConfirmation |                   |       |
| assertConfirmation             | Choose an option. |       |
| verifyTextPresent              | Rejected          |       |

A função `chooseCancelOnNextConfirmation` diz ao Selenium que todas as seguintes confirmações devem retornar falso. Ela pode ser redefinido chamando chooseOkOnNextConfirmation.

Você vai notar que não pode repetir este teste, porque o Selenium reclama que há uma confirmação não tratada. Isso ocorre porque a ordem dos registros de eventos do Selenium-IDE faz com que o clique e chooseCancelOnNextConfirmation sejam colocados na ordem errada (faz sentido se você pensar sobre isso, o Selenium não pode saber que você está cancelando antes de abrir uma confirmação). Simplesmente troque esses dois comandos e seu teste funcionará bem.

### Prompts

Os prompts se comportam da mesma forma que os alertas, com `assertPrompt` e `assertPromptPresent` oferecendo as mesmas características que suas contrapartes de alerta. Por padrão, o Selenium irá esperar você inserir dados quando o prompt for exibido. Tente gravar clicando no botão “Show prompt” na página de amostra e digite “Selenium” no prompt. Seu teste pode ser semelhante a este:

| Command            | Target                       | Value |
| ------------------ | ---------------------------- | ----- |
| open               | /                            |       |
| answerOnNextPrompt | Selenium!                    |       |
| click              | id=btnPrompt                 |       |
| assertPrompt       | What’s the best web QA tool? |       |
| verifyTextPresent  | Selenium!                    |       |

```html
<html>
    <head>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <title>Sample Selenium Test Suite</title>
    </head>
    <body>
        <table cellpadding="1" cellspacing="1" border="1">
            <thead>
                <tr><td>Test Cases for De Anza A-Z Directory Links</td></tr>
            </thead>
        <tbody>
            <tr><td><a href="./a.html">A Links</a></td></tr>
            <tr><td><a href="./b.html">B Links</a></td></tr>
            <tr><td><a href="./c.html">C Links</a></td></tr>
            <tr><td><a href="./d.html">D Links</a></td></tr>
        </tbody>
        </table>
    </body>
</html>
```

***

*error loading test case: no command found*

Você usou **File => Open** para tentar abrir um arquivo de suíte de testes. Use **File => Open Test Suite** em vez disso.

Uma solicitação de aprimoramento foi levantada para melhorar esta mensagem de erro. Veja a [issue 1010](http://code.google.com/p/selenium/issues/detail?id=1010).

***

Este tipo de **erro** pode indicar um problema de tempo, ou seja, o elemento especificado por um localizador em seu comando não foi totalmente carregado quando o comando foi executado. Tente colocar um **pause 5000** antes do comando para determinar se o problema está realmente relacionado ao tempo. Em caso afirmativo, investigue usando um comando **waitFor\*** ou **\*AndWait** apropriado antes do comando com falha.

***

Sempre que sua tentativa de usar a substituição de variável falha, como é o caso para o comando **open** acima, isso indica que você não criou realmente a variável cujo valor você está tentando acessar. Isto é às vezes devido a colocar a variável no campo **Valor** quando deve estar no campo **Destino** ou vice-versa. No exemplo acima, os dois parâmetros para o comando **store** foram erroneamente colocados na ordem inversa do que é necessário. Para qualquer comando Selenese, o primeiro parâmetro obrigatório deve ir no campo **Destino** e o segundo parâmetro obrigatório (se houver) deve ir no campo **Valor**.

***

*error loading test case: \[Exception… “Component returned failure code: 0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND) \[nsIFileInputStream.init]” nresult: “0x80520012 (NS\_ERROR\_FILE\_NOT\_FOUND)” location: “JS frame :: chrome://selenium-ide/content/file-utils.js :: anonymous :: line 48” data: no]*

Um dos casos de teste em seu conjunto de testes não pode ser encontrado. Certifique-se de que o caso de teste está realmente localizado onde o conjunto de testes indica que ele está localizado. Além disso, certifique-se de que seus arquivos de caso de teste tenham a extensão .html em seus nomes de arquivo e no arquivo de suíte de testes onde são referenciados.

Uma solicitação de aprimoramento foi levantada para melhorar esta mensagem de erro. Veja a [issue 1011](http://code.google.com/p/selenium/issues/detail?id=1011).

***

O conteúdo do seu arquivo de extensão não foi lido pela Selenium-IDE. Certifique-se de ter especificado o nome do caminho adequado para o arquivo de extensões via **Options => Options => General** no campo **Selenium Core extensions**. Além disso, a Selenium-IDE deve ser reiniciada após qualquer alteração em um arquivo de extensões *ou* no conteúdo do campo **Selenium Core extensions**.

# 1 - HTML runner

```shell
[user@localhost ~]$ cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

[user@localhost ~]$ rpm -qa | egrep -i "xvfb|java-1.8|firefox"
xorg-x11-server-Xvfb-1.19.3-11.el7.x86_64
firefox-52.4.0-1.el7.centos.x86_64
java-1.8.0-openjdk-1.8.0.151-1.b12.el7_4.x86_64
java-1.8.0-openjdk-headless-1.8.0.151-1.b12.el7_4.x86_64
```

Exemplo de suíte de testes:

```html
[user@localhost ~]$ cat testsuite.html
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
  <title>Test Suite</title>
</head>
<body>
<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium"><tbody>
<tr><td><b>Test Suite</b></td></tr>
<tr><td><a href="YOUR-TEST-SCENARIO.html">YOUR-TEST-SCENARIO</a></td></tr>
</tbody></table>
</body>
</html>
```

## Como rodar o selenium-html-runner headless

Agora, a parte mais importante, um exemplo de como executar o selenium-html-runner! Sua experiência pode variar dependendo das combinações de software - versões geckodriver / FF / html-runner.

```shell
xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
```

```shell
[user@localhost ~]$ xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "*firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
Multi-window mode is longer used as an option and will be ignored.
1510061109691   geckodriver     INFO    geckodriver 0.18.0
1510061109708   geckodriver     INFO    Listening on 127.0.0.1:2885
1510061110162   geckodriver::marionette INFO    Starting browser /usr/bin/firefox with args ["-marionette"]
1510061111084   Marionette      INFO    Listening on port 43229
1510061111187   Marionette      WARN    TLS certificate errors will be ignored for this session
Nov 07, 2017 1:25:12 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
2017-11-07 13:25:12.714:INFO::main: Logging initialized @3915ms to org.seleniumhq.jetty9.util.log.StdErrLog
2017-11-07 13:25:12.804:INFO:osjs.Server:main: jetty-9.4.z-SNAPSHOT
2017-11-07 13:25:12.822:INFO:osjsh.ContextHandler:main: Started o.s.j.s.h.ContextHandler@87a85e1{/tests,null,AVAILABLE}
2017-11-07 13:25:12.843:INFO:osjs.AbstractConnector:main: Started ServerConnector@52102734{HTTP/1.1,[http/1.1]}{0.0.0.0:31892}
2017-11-07 13:25:12.843:INFO:osjs.Server:main: Started @4045ms
Nov 07, 2017 1:25:13 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |open | /auth_mellon.php |  |
Nov 07, 2017 1:25:14 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |waitForPageToLoad | 3000 |  |
.
.
.etc

<td>result:</td>
<td>PASS</td>
```

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/discouraged/http_response_codes/
----

# HTTP响应码

对于Selenium RC中的某些浏览器配置， Selenium充当了浏览器和自动化站点之间的代理. 这意味着可以捕获或操纵通过Selenium传递的所有浏览器流量. `captureNetworkTraffic()` 方法旨在捕获浏览器和自动化站点之间的所有网络流量，包括HTTP响应码.

Selenium WebDriver是一种完全不同的浏览器自动化实现， 它更喜欢表现得像用户一样，这种方式来自于基于WebDriver编写测试的方式. 在自动化功能测试中，检查状态码并不是测试失败的特别重要的细节, 之前的步骤更重要.

浏览器将始终呈现HTTP状态代码，例如404或500错误页面. 遇到这些错误页面时，一种“快速失败”的简单方法是 在每次加载页面后检查页面标题或可信赖点的内容（例如 `<h1>` 标签）. 如果使用的是页面对象模型，则可以将此检查置于类构造函数中或类似于期望的页面加载的位置. 有时，HTTP代码甚至可能出现在浏览器的错误页面中， 您可以使用WebDriver读取此信息并改善调试输出.

检查网页本身的一种理想实践是符合WebDriver的呈现以及用户的视角.

如果您坚持，捕获HTTP状态代码的高级解决方案是复刻Selenium RC的行为去使用代理. WebDriver API提供了为浏览器设置代理的功能， 并且有许多代理可以通过编程方式来操纵发送到Web服务器和从Web服务器接收的请求的内容. 使用代理可以决定如何响应重定向响应代码. 此外，并非每个浏览器都将响应代码提供给WebDriver， 因此选择使用代理可以使您拥有适用于每个浏览器的解决方案.

----
url: https://www.selenium.dev/documentation/webdriver/bidi/w3c/log/
----

# Log

```java
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L33-L39)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```js
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/logInspector.spec.js#L23-37)

##### /examples/javascript/test/bidirectional/logInspector.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const LogInspector = require('selenium-webdriver/bidi/logInspector');
const {Builder} = require("selenium-webdriver");


describe('Log Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test listen to console log', async function () {
    let logEntry = null
    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)

    await inspector.close()
  })

  it('test listen to javascript error log', async function () {
    let logEntry = null
    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')

    await inspector.close()
  })

  it('test retrieve stack trace for a log', async function () {
    let logEntry = null
    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()

    const stackTrace = logEntry.stackTrace
    assert.notEqual(stackTrace, null)
    assert.equal(stackTrace.callFrames.length, 3)

    await inspector.close()
  })

  it('test listen to logs with multiple consumers', async function () {
    let logEntry1 = null
    let logEntry2 = null
    const inspector = await LogInspector(driver)
    await inspector.onJavascriptException(function (log) {
      logEntry1 = log
    })
    await inspector.onJavascriptException(function (log) {
      logEntry2 = log
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    await driver.findElement({id: 'jsException'}).click()

    assert.equal(logEntry1.text, 'Error: Not working')
    assert.equal(logEntry1.type, 'javascript')
    assert.equal(logEntry1.level, 'error')

    assert.equal(logEntry2.text, 'Error: Not working')
    assert.equal(logEntry2.type, 'javascript')
    assert.equal(logEntry2.level, 'error')

    await inspector.close()
  })
})
```

```java
            logInspector.onJavaScriptException(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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L73-L78)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```js
    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')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/bidirectional/logInspector.spec.js#L44-54)

##### /examples/javascript/test/bidirectional/logInspector.spec.js

```js
const assert = require("assert");
const firefox = require('selenium-webdriver/firefox');
const LogInspector = require('selenium-webdriver/bidi/logInspector');
const {Builder} = require("selenium-webdriver");


describe('Log Inspector', function () {
  let driver

  beforeEach(async function () {
    driver = new Builder()
      .forBrowser('firefox')
      .setFirefoxOptions(new firefox.Options().enableBidi())
      .build()
  })

  afterEach(async function () {
    await driver.quit()
  })

  it('test listen to console log', async function () {
    let logEntry = null
    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)

    await inspector.close()
  })

  it('test listen to javascript error log', async function () {
    let logEntry = null
    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')

    await inspector.close()
  })

  it('test retrieve stack trace for a log', async function () {
    let logEntry = null
    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()

    const stackTrace = logEntry.stackTrace
    assert.notEqual(stackTrace, null)
    assert.equal(stackTrace.callFrames.length, 3)

    await inspector.close()
  })

  it('test listen to logs with multiple consumers', async function () {
    let logEntry1 = null
    let logEntry2 = null
    const inspector = await LogInspector(driver)
    await inspector.onJavascriptException(function (log) {
      logEntry1 = log
    })
    await inspector.onJavascriptException(function (log) {
      logEntry2 = log
    })

    await driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')
    await driver.findElement({id: 'jsException'}).click()

    assert.equal(logEntry1.text, 'Error: Not working')
    assert.equal(logEntry1.type, 'javascript')
    assert.equal(logEntry1.level, 'error')

    assert.equal(logEntry2.text, 'Error: Not working')
    assert.equal(logEntry2.type, 'javascript')
    assert.equal(logEntry2.level, 'error')

    await inspector.close()
  })
})
```

```java
            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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidirectional/webdriver_bidi/LogTest.java#L55-L60)

##### /examples/java/src/test/java/dev/selenium/bidirectional/webdriver\_bidi/LogTest.java

```java
package dev.selenium.bidirectional.webdriver_bidi;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.*;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.bidi.module.LogInspector;
import org.openqa.selenium.bidi.log.ConsoleLogEntry;
import org.openqa.selenium.bidi.log.JavascriptLogEntry;
import org.openqa.selenium.bidi.log.LogLevel;
import org.openqa.selenium.bidi.log.StackTrace;
import org.openqa.selenium.firefox.FirefoxDriver;
import org.openqa.selenium.firefox.FirefoxOptions;
import org.openqa.selenium.support.ui.WebDriverWait;

class LogTest extends BaseTest {

    @BeforeEach
    public void setup() {
        FirefoxOptions options = new FirefoxOptions();
        options.setCapability("webSocketUrl", true);
        driver = new FirefoxDriver(options);
    }

    @Test
    void testListenToConsoleLog() throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<ConsoleLogEntry> future = new CompletableFuture<>();
            logInspector.onConsoleEntry(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("consoleLog")).click();

            ConsoleLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Hello, world!", logEntry.getText());

            Assertions.assertEquals(1, logEntry.getArgs().size());
            Assertions.assertEquals("console", logEntry.getType());
            Assertions.assertEquals("log", logEntry.getMethod());
            Assertions.assertNull(logEntry.getStackTrace());
        }
    }

    @Test
    void testListenToJavascriptLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            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());
            Assertions.assertEquals("javascript", logEntry.getType());
            Assertions.assertEquals(LogLevel.ERROR, logEntry.getLevel());
        }
    }

    @Test
    void testListenToJavascriptErrorLog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(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());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }

    @Test
    void testRetrieveStacktraceForALog()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> future = new CompletableFuture<>();
            logInspector.onJavaScriptException(future::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("logWithStacktrace")).click();

            JavascriptLogEntry logEntry = future.get(5, TimeUnit.SECONDS);

            StackTrace stackTrace = logEntry.getStackTrace();
            Assertions.assertNotNull(stackTrace);
            Assertions.assertEquals(4, stackTrace.getCallFrames().size());
        }
    }

    @Test
    void testListenToLogsWithMultipleConsumers()
            throws ExecutionException, InterruptedException, TimeoutException {
        try (LogInspector logInspector = new LogInspector(driver)) {
            CompletableFuture<JavascriptLogEntry> completableFuture1 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture1::complete);

            CompletableFuture<JavascriptLogEntry> completableFuture2 = new CompletableFuture<>();
            logInspector.onJavaScriptLog(completableFuture2::complete);

            driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
            driver.findElement(By.id("jsException")).click();

            JavascriptLogEntry logEntry = completableFuture1.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());

            logEntry = completableFuture2.get(5, TimeUnit.SECONDS);

            Assertions.assertEquals("Error: Not working", logEntry.getText());
            Assertions.assertEquals("javascript", logEntry.getType());
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

Last modified December 16, 2024: [\[java\] Remove a wrong code example and update code lines (#2104) (6b3cccc0e32)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/6b3cccc0e32b97a2a88350983e4b7c73836e0733)

----
url: https://www.selenium.dev/ja/_print/documentation/webdriver/interactions/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/webdriver/interactions/).

# ブラウザのインタラクション

* 1: [ブラウザー ナビゲーション](#pg-115ebc752834eb7cb47ebbe165d533bb)
* 2: [JavaScript アラート、プロンプトおよび確認](#pg-5136738e2bf5002870751a809ee2c406)
* 3: [クッキーの使用](#pg-9152f4ea0db01a07203308fd83d4231a)
* 4: [IFrame と Frame の操作](#pg-7c102d9bcb762afcfb2871a92ce5ec81)
* 5: [Print Page](#pg-7cf25be79af516dc8dccf018e3212b15)
* 6: [ウィンドウとタブの操作](#pg-59166adba602dfc7b75c1507d61b4d44)
* 7: [Virtual Authenticator](#pg-da8af8fd0b38d66f6c09dd58470238b8)

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java#L15)

##### /examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class InteractionsTest extends BaseChromeTest {
    @Test
    public void getTitle() {
        driver.get("https://www.selenium.dev/");
        // get title
        String title = driver.getTitle();
        Assertions.assertEquals(title, "Selenium");
    }

    @Test
    public void getCurrentUrl() {
        driver.get("https://www.selenium.dev/");
        // get current url
        String url = driver.getCurrentUrl();
        Assertions.assertEquals(url, "https://www.selenium.dev/");
    }
}
```

```py
title = driver.title
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_interactions.py#L7)

##### /examples/python/tests/interactions/test\_interactions.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")

title = driver.title
assert title == "Selenium"

url = driver.current_url
assert url == "https://www.selenium.dev/"

driver.quit()
```

```cs
            String title = driver.Title;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs#L37)

##### /examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class InteractionsTest
    {
        [TestMethod]
        public void TestInteractions()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url="https://www.selenium.dev/";
            //GetTitle
            String title = driver.Title;
            Assert.AreEqual(title, "Selenium");

            //GetCurrentURL
            String url = driver.Url;
            Assert.AreEqual(url, "https://www.selenium.dev/");

            //quitting driver
            driver.Quit(); //close all windows
        }
    }
}
```

```rb
  it 'gets the current title' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/browser_spec.rb#L8)

##### /examples/ruby/spec/interactions/browser\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'gets the current title' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_title = driver.title
    expect(current_title).to eq 'Selenium'
  end

  it 'gets the current url' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_url = driver.current_url
    expect(current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    let title = await driver.getTitle();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/interactionsIndex.spec.js#L20)

##### /examples/javascript/test/interactions/interactionsIndex.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Should be able to get title and current url', async function () {
    const url = 'https://www.selenium.dev/';
    await driver.get(url);

    //Get Current title
    let title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Get Current url
    let currentUrl = await driver.getCurrentUrl();
    assert.equal(currentUrl, url);
  });
});
```

```kotlin
driver.title
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java#L26)

##### /examples/java/src/test/java/dev/selenium/interactions/InteractionsTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;

public class InteractionsTest extends BaseChromeTest {
    @Test
    public void getTitle() {
        driver.get("https://www.selenium.dev/");
        // get title
        String title = driver.getTitle();
        Assertions.assertEquals(title, "Selenium");
    }

    @Test
    public void getCurrentUrl() {
        driver.get("https://www.selenium.dev/");
        // get current url
        String url = driver.getCurrentUrl();
        Assertions.assertEquals(url, "https://www.selenium.dev/");
    }
}
```

```py
url = driver.current_url
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_interactions.py#L10)

##### /examples/python/tests/interactions/test\_interactions.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")

title = driver.title
assert title == "Selenium"

url = driver.current_url
assert url == "https://www.selenium.dev/"

driver.quit()
```

```cs
            String url = driver.Url;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs#L41)

##### /examples/dotnet/SeleniumDocs/Interactions/InteractionsTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class InteractionsTest
    {
        [TestMethod]
        public void TestInteractions()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url="https://www.selenium.dev/";
            //GetTitle
            String title = driver.Title;
            Assert.AreEqual(title, "Selenium");

            //GetCurrentURL
            String url = driver.Url;
            Assert.AreEqual(url, "https://www.selenium.dev/");

            //quitting driver
            driver.Quit(); //close all windows
        }
    }
}
```

```rb
  it 'gets the current url' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/browser_spec.rb#L14)

##### /examples/ruby/spec/interactions/browser\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'gets the current title' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_title = driver.title
    expect(current_title).to eq 'Selenium'
  end

  it 'gets the current url' do
    driver.navigate.to 'https://www.selenium.dev/'
    current_url = driver.current_url
    expect(current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    let currentUrl = await driver.getCurrentUrl();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/interactionsIndex.spec.js#L24)

##### /examples/javascript/test/interactions/interactionsIndex.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Should be able to get title and current url', async function () {
    const url = 'https://www.selenium.dev/';
    await driver.get(url);

    //Get Current title
    let title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Get Current url
    let currentUrl = await driver.getCurrentUrl();
    assert.equal(currentUrl, url);
  });
});
```

```kotlin
driver.currentUrl
```

# 1 - ブラウザー ナビゲーション

```java
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L14-L18)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.get("https://www.selenium.dev/selenium/web/index.html")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L6)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Convenient
            driver.Url = "https://selenium.dev";
            //Longer
            driver.Navigate().GoToUrl("https://selenium.dev");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L17-L20)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class NavigationTest
    {
        [TestMethod]
        public void TestNavigationCommands()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            //Convenient
            driver.Url = "https://selenium.dev";
            //Longer
            driver.Navigate().GoToUrl("https://selenium.dev");
            var title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Back
            driver.Navigate().Back();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Forward
            driver.Navigate().Forward();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Refresh
            driver.Navigate().Refresh();
            title = driver.Title;
            Assert.AreEqual("Selenium", title);

            //Quit the browser
            driver.Quit();
        }
    }
}
```

```rb

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L7-L9)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L16-L20)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
//Convenient
driver.get("https://selenium.dev")

//Longer way
driver.navigate().to("https://selenium.dev")
  
```

```java
        //Back
        driver.navigate().back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L22-L23)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.back()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L11)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Back
             driver.Navigate().Back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L24-L25)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
    driver.navigate.to 'https://www.selenium.dev/'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L15)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Back
    await driver.navigate().back();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L24-L25)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().back() 
```

```java
        //Forward
        driver.navigate().forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L27-L28)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.forward()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L15)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Forward
             driver.Navigate().Forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L29-L30)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L23)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Forward
    await driver.navigate().forward();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L29-L30)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().forward()
```

```java
        //Refresh
        driver.navigate().refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java#L32-L33)

##### /examples/java/src/test/java/dev/selenium/interactions/NavigationTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class NavigationTest {
    @Test
    public void navigateBrowser() {
        
        WebDriver driver = new ChromeDriver();
      
        //Convenient
        driver.get("https://selenium.dev");
            
        //Longer way
        driver.navigate().to("https://selenium.dev");
        String title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Back
        driver.navigate().back();
        title = driver.getTitle();
        assertEquals(title, "Selenium");
        
        //Forward
        driver.navigate().forward();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        //Refresh
        driver.navigate().refresh();
        title = driver.getTitle();
        assertEquals(title, "Selenium");

        driver.quit();
    }
}
```

```py
driver.refresh()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_navigation.py#L19)

##### /examples/python/tests/interactions/test\_navigation.py

```py
from selenium import webdriver

driver = webdriver.Chrome()

driver.get("https://www.selenium.dev")
driver.get("https://www.selenium.dev/selenium/web/index.html")

title = driver.title
assert title == "Index of Available Pages"

driver.back()
title = driver.title
assert title == "Selenium"

driver.forward()
title = driver.title
assert title == "Index of Available Pages"

driver.refresh()
title = driver.title
assert title == "Index of Available Pages"

driver.quit()
```

```cs
            //Refresh
             driver.Navigate().Refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs#L34-L35)

##### /examples/dotnet/SeleniumDocs/Interactions/NavigationTest.cs

```cs
using System;
 using Microsoft.VisualStudio.TestTools.UnitTesting;
 using OpenQA.Selenium;
 using OpenQA.Selenium.Chrome;
 
 namespace SeleniumDocumentation.SeleniumInteractions
 {
     [TestClass]
     public class NavigationTest
     {
         [TestMethod]
         public void TestNavigationCommands()
         {
             IWebDriver driver = new ChromeDriver();
             driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
 
             //Convenient
             driver.Url = "https://selenium.dev";
             //Longer
             driver.Navigate().GoToUrl("https://selenium.dev");
             var title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Back
             driver.Navigate().Back();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Forward
             driver.Navigate().Forward();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Refresh
             driver.Navigate().Refresh();
             title = driver.Title;
             Assert.AreEqual("Selenium", title);
 
             //Quit the browser
             driver.Quit();
         }
     }
 }
 
```

```rb
  it 'refreshes the page' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/navigation_spec.rb#L29)

##### /examples/ruby/spec/interactions/navigation\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Browser' do
  let(:driver) { start_session }

  it 'navigates to a page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.get 'https://www.selenium.dev/'
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates back' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end

  it 'navigates forward' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.to 'https://www.selenium.dev/selenium/web/inputs.html'
    driver.navigate.back
    driver.navigate.forward
    expect(driver.current_url).to eq 'https://www.selenium.dev/selenium/web/inputs.html'
  end

  it 'refreshes the page' do
    driver.navigate.to 'https://www.selenium.dev/'
    driver.navigate.refresh
    expect(driver.current_url).to eq 'https://www.selenium.dev/'
  end
end
```

```js
    //Refresh
    await driver.navigate().refresh();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/navigation.spec.js#L34-L35)

##### /examples/javascript/test/interactions/navigation.spec.js

```js
const {Builder } = require('selenium-webdriver');
const assert = require("node:assert");

describe('Interactions - Navigation', function () {
  let driver;

  before(async function () {
    driver = new Builder()
      .forBrowser('chrome')
      .build();
  });

  after(async () => await driver.quit());

  it('Browser navigation test', async function () {
    //Convenient
    await driver.get('https://www.selenium.dev');

    //Longer way
    await driver.navigate().to("https://www.selenium.dev/selenium/web/index.html");
    let title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Back
    await driver.navigate().back();
    title = await driver.getTitle();
    assert.equal(title, "Selenium");

    //Forward
    await driver.navigate().forward();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");

    //Refresh
    await driver.navigate().refresh();
    title = await driver.getTitle();
    assert.equal(title, "Index of Available Pages");
  });
});
```

```kotlin
driver.navigate().refresh()
```

# 2 - JavaScript アラート、プロンプトおよび確認

```java

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L36-L41)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L12-L18)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See an example alert")).Click();

//Wait for the alert to be displayed and store it in a variable
IAlert alert = wait.Until(ExpectedConditions.AlertIsPresent());

//Store the alert text in a variable
string text = alert.Text;

//Press the OK button
alert.Accept();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L15-L22)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L19-L21)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See an example alert")).click()

//Wait for the alert to be displayed and store it in a variable
val alert = wait.until(ExpectedConditions.alertIsPresent())

//Store the alert text in a variable
val text = alert.getText()

//Press the OK button
alert.accept()
  
```

```java
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L131-L138)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L26-L32)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See a sample confirm")).Click();

//Wait for the alert to be displayed
wait.Until(ExpectedConditions.AlertIsPresent());

//Store the alert in a variable
IAlert alert = driver.SwitchTo().Alert();

//Store the alert in a variable for reuse
string text = alert.Text;

//Press the Cancel button
alert.Dismiss();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L28-L35)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L30-L32)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See a sample confirm")).click()

//Wait for the alert to be displayed
wait.until(ExpectedConditions.alertIsPresent())

//Store the alert in a variable
val alert = driver.switchTo().alert()

//Store the alert in a variable for reuse
val text = alert.text

//Press the Cancel button
alert.dismiss()
  
```

```java
        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java#L79-L84)

##### /examples/java/src/test/java/dev/selenium/interactions/AlertsTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Alert;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.support.ui.ExpectedConditions;
import org.openqa.selenium.support.ui.WebDriverWait;

import java.time.Duration;

import static org.junit.jupiter.api.Assertions.assertEquals;

public class AlertsTest extends BaseTest {

    @BeforeEach
    public void createSession() {
        driver = new ChromeDriver();
        wait = new WebDriverWait(driver, Duration.ofSeconds(10));
    }

    @Test
    public void alertInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("cheese", alert.getText());
        alert.accept();

    }

    @Test
    public void alertEmptyInformationTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("empty-alert")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("", alert.getText());
        alert.accept();

    }

    @Test
    public void promptDisplayAndInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("prompt")).click();

        //Wait for the alert to be displayed and store it in a variable
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());

        alert.sendKeys("Selenium");
        alert.accept();

    }

    @Test
    public void promptDefaultInputTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("prompt-with-default")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Enter something", alert.getText());
        alert.accept();
    }

    @Test
    public void multiplePromptInputsTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("double-prompt")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert1 = driver.switchTo().alert();
        Assertions.assertEquals("First", alert1.getText());

        alert1.sendKeys("first");
        alert1.accept();


        Alert alert2 = driver.switchTo().alert();
        Assertions.assertEquals("Second", alert2.getText());
        alert2.sendKeys("second");
        alert2.accept();

    }

    @Test
    public void slowAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        driver.findElement(By.id("slow-alert")).click();

        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Slow", alert.getText());

        alert.accept();

    }


    @Test
    public void confirmationAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");

        driver.findElement(By.id("confirm")).click();

        wait.until(ExpectedConditions.alertIsPresent());
        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("Are you sure?", alert.getText());

        alert.accept();
        Assertions.assertTrue(driver.getCurrentUrl().endsWith("simpleTest.html"));

    }


    @Test
    public void iframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void nestedIframeAlertTest() {
        driver.get("https://www.selenium.dev/selenium/web/alerts.html#");
        WebElement iframe1 = driver.findElement(By.name("iframeWithIframe"));
        driver.switchTo().frame(iframe1);

        WebElement iframe2 = driver.findElement(By.name("iframeWithAlert"));
        driver.switchTo().frame(iframe2);

        driver.findElement(By.id("alertInFrame")).click();


        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        Assertions.assertEquals("framed cheese", alert.getText());

        alert.accept();

    }

    @Test
    public void testForAlerts() {

        ChromeOptions chromeOptions = getDefaultChromeOptions();
        chromeOptions.addArguments("disable-search-engine-choice-screen");
        WebDriver driver = new ChromeDriver(chromeOptions);

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        driver.get("https://www.selenium.dev/documentation/webdriver/interactions/alerts/");

        JavascriptExecutor js = (JavascriptExecutor) driver;
        js.executeScript("alert('Sample Alert');");
        WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        Alert alert = driver.switchTo().alert();
        assertEquals("Sample Alert", alert.getText());
        alert.accept();

        js.executeScript("confirm('Are you sure?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());

        alert = driver.switchTo().alert();
        assertEquals("Are you sure?", alert.getText());
        alert.dismiss();

        js.executeScript("prompt('What is your name?');");
        wait = new WebDriverWait(driver, Duration.ofSeconds(30));
        wait.until(ExpectedConditions.alertIsPresent());
        alert = driver.switchTo().alert();
        assertEquals("What is your name?", alert.getText());
        alert.sendKeys("Selenium");
        alert.accept();
        driver.quit();
    }
}
```

```py
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_alerts.py#L40-L47)

##### /examples/python/tests/interactions/test\_alerts.py

```py
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait

global url
url = "https://www.selenium.dev/documentation/webdriver/interactions/alerts/"


def test_alert_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See an example alert")
    element.click()

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.accept()
    assert text == "Sample alert"

    driver.quit()

def test_confirm_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample confirm")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    text = alert.text
    alert.dismiss()
    assert text == "Are you sure?"

    driver.quit()

def test_prompt_popup():
    driver = webdriver.Chrome()
    driver.get(url)
    element = driver.find_element(By.LINK_TEXT, "See a sample prompt")
    driver.execute_script("arguments[0].click();", element)

    wait = WebDriverWait(driver, timeout=2)
    alert = wait.until(lambda d : d.switch_to.alert)
    alert.send_keys("Selenium")
    text = alert.text
    alert.accept()
    assert text == "What is your tool of choice?"
    
    driver.quit()
```

```csharp
//Click the link to activate the alert
driver.FindElement(By.LinkText("See a sample prompt")).Click();

//Wait for the alert to be displayed and store it in a variable
IAlert alert = wait.Until(ExpectedConditions.AlertIsPresent());

//Type your message
alert.SendKeys("Selenium");

//Press the OK button
alert.Accept();
  
```

```rb
    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/alerts_spec.rb#L41-L48)

##### /examples/ruby/spec/interactions/alerts\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Alerts' do
  let(:driver) { start_session }

  before do
    driver.navigate.to 'https://selenium.dev'
  end

  it 'interacts with an alert' do
    driver.execute_script 'alert("Hello, World!")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a confirm' do
    driver.execute_script 'confirm("Are you sure?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Get the text of the alert
    alert.text

    # Press on Cancel button
    alert.dismiss
  end

  it 'interacts with a prompt' do
    driver.execute_script 'prompt("What is your name?")'

    # Store the alert reference in a variable
    alert = driver.switch_to.alert

    # Type a message
    alert.send_keys('selenium')

    # Press on Ok button
    alert.accept
  end
end
```

```js
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/alert.spec.js#L42-L45)

##### /examples/javascript/test/interactions/alert.spec.js

```js

const { By, Builder, until } = require('selenium-webdriver');
const assert = require("node:assert");


describe('Interactions - Alerts', function () {
    let driver;

    before(async function () {
        driver = await new Builder().forBrowser('chrome').build();
    });

    after(async () => await driver.quit());

    it('Should be able to getText from alert and accept', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("alert")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.accept();
        // Verify
        assert.equal(alertText, "cheese");
    });

    it('Should be able to getText from alert and dismiss', async function () {
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("confirm")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        let alertText = await alert.getText();
        await alert.dismiss();
        // Verify
        assert.equal(alertText, "Are you sure?");
    });

    it('Should be able to enter text in alert prompt', async function () {
        let text = 'Selenium';
        await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
        await driver.findElement(By.id("prompt")).click();
        await driver.wait(until.alertIsPresent());
        let alert = await driver.switchTo().alert();
        //Type your message
        await alert.sendKeys(text);
        await alert.accept();

        let enteredText = await driver.findElement(By.id('text'));
        assert.equal(await enteredText.getText(), text);
    });
});
```

```kotlin
//Click the link to activate the alert
driver.findElement(By.linkText("See a sample prompt")).click()

//Wait for the alert to be displayed and store it in a variable
val alert = wait.until(ExpectedConditions.alertIsPresent())

//Type your message
alert.sendKeys("Selenium")

//Press the OK button
alert.accept()
  
```

# 3 - クッキーの使用

```java

    WebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L30-L32)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L5-L9)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L32-L34)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L9-L11)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L18)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

  const {Browser, Builder} = require("selenium-webdriver");
  const assert = require('assert')
  
  
  describe('Cookies', function() {
    let driver;
  
    before(async function() {
      driver = new Builder()
        .forBrowser(Browser.CHROME)
        .build();
    });
  
    after(async () => await driver.quit());
  
    it('Create a cookie', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // set a cookie on the current domain
      await driver.manage().addCookie({ name: 'key', value: 'value' });
    });
  
    it('Create cookies with sameSite', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
      await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
      await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
    });
  
    it('Read cookie', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // set a cookie on the current domain
      await driver.manage().addCookie({ name: 'foo', value: 'bar' });
  
      // Get cookie details with named cookie 'foo'
      await driver.manage().getCookie('foo').then(function(cookie) {
        assert.equal(cookie.value, 'bar');
      });
    });
  
    it('Read all cookies', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // Add few cookies
      await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
      await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
  
      // Get all Available cookies
      await driver.manage().getCookies().then(function(cookies) {
        assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
      });
    });
  
    it('Delete a cookie', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // Add few cookies
      await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
      await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
  
      // Delete a cookie with name 'test1'
      await driver.manage().deleteCookie('test1');
  
      // Get all Available cookies
      await driver.manage().getCookies().then(function(cookies) {
        assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
      });
    });
  
    it('Delete all cookies', async function() {
      await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  
      // Add few cookies
      await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
      await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
  
      // Delete all cookies
      await driver.manage().deleteAllCookies();
    });
  });
  
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")

        // Adds the cookie into current browser context
        driver.manage().addCookie(Cookie("key", "value"))
    } finally {
        driver.quit()
    }
}  
  
```

```java
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L38-L42)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L13-L20)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L40-L44)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L17-L21)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L35-L38)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("foo", "bar"))

        // Get cookie details with named cookie 'foo'
        val cookie = driver.manage().getCookieNamed("foo")
        println(cookie)
    } finally {
        driver.quit()
    }
}  
  
```

```java
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L52-L66)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L24-L32)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L51-L64)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L26-L31)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L49-L51)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        driver.manage().addCookie(Cookie("test2", "cookie2"))

        // Get All available cookies
        val cookies = driver.manage().cookies
        println(cookies)
    } finally {
        driver.quit()
    }
}  
  
```

```java
        }
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L74-L77)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L35-L43)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L70-L73)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L40-L43)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L61-L62)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        val cookie1 = Cookie("test2", "cookie2")
        driver.manage().addCookie(cookie1)

        // delete a cookie with name 'test1'
        driver.manage().deleteCookieNamed("test1")

        // delete cookie by passing cookie object of current browsing context.
        driver.manage().deleteCookie(cookie1)
    } finally {
        driver.quit()
    }
}  
  
```

```java
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L100-L105)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L47-L55)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```cs
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs#L92-L97)

##### /examples/dotnet/SeleniumDocs/Interactions/CookiesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Interactions{

[TestClass]
public class CookiesTest{
     
    WebDriver driver = new ChromeDriver();

     [TestMethod]
      public void addCookie(){
         driver.Url="https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("key", "value"));
         driver.Quit();
     }
     
     [TestMethod]
     public void getNamedCookie(){  
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookie into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("foo", "bar"));
         // Get cookie details with named cookie 'foo'
         Cookie cookie = driver.Manage().Cookies.GetCookieNamed("foo");
         Assert.AreEqual(cookie.Value, "bar");
         driver.Quit();
     }

     [TestMethod]
     public void getAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Get cookies
         var cookies = driver.Manage().Cookies.AllCookies;
         foreach (var cookie in cookies){
             if (cookie.Name.Equals("test1")){
                 Assert.AreEqual("cookie1", cookie.Value);
             }
             if (cookie.Name.Equals("test2")){
                 Assert.AreEqual("cookie2", cookie.Value);
             }
         }
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteCookieNamed(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         // delete cookie named
         driver.Manage().Cookies.DeleteCookieNamed("test1");
         driver.Quit();
     }

     [TestMethod]
     public void deleteCookieObject(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         Cookie cookie = new Cookie("test2", "cookie2");
         driver.Manage().Cookies.AddCookie(cookie);
         /*
      Selenium CSharp bindings also provides a way to delete
      cookie by passing cookie object of current browsing context
      */
         driver.Manage().Cookies.DeleteCookie(cookie);
         driver.Quit();
     }
     
     [TestMethod]
     public void deleteAllCookies(){
         driver.Url = "https://www.selenium.dev/selenium/web/blank.html";
         // Add cookies into current browser context
         driver.Manage().Cookies.AddCookie(new Cookie("test1", "cookie1"));
         driver.Manage().Cookies.AddCookie(new Cookie("test2", "cookie2"));
         // Delete All cookies
         driver.Manage().Cookies.DeleteAllCookies();
         driver.Quit();
     }
    }
}
```

```rb
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/cookies_spec.rb#L49-L54)

##### /examples/ruby/spec/interactions/cookies\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Cookies' do
  let(:driver) { start_session }

  it 'adds a cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'key', value: 'value')
    # Verify cookie was added
    expect(driver.manage.cookie_named('key')[:value]).to eq('value')
  end

  it 'gets a named cookie' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookie into current browser context
    driver.manage.add_cookie(name: 'foo', value: 'bar')
    # Get cookie details with named cookie 'foo'
    cookie = driver.manage.cookie_named('foo')
    expect(cookie[:value]).to eq('bar')
  end

  it 'gets all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Get cookies
    cookies = driver.manage.all_cookies
    # Verify both cookies exist with correct values
    test1_cookie = cookies.find { |c| c[:name] == 'test1' }
    test2_cookie = cookies.find { |c| c[:name] == 'test2' }
    expect(test1_cookie[:value]).to eq('cookie1')
    expect(test2_cookie[:value]).to eq('cookie2')
  end

  it 'deletes a cookie by name' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    # Delete cookie named
    driver.manage.delete_cookie('test1')
    # Verify cookie is deleted
    expect { driver.manage.cookie_named('test1') }.to raise_error(Selenium::WebDriver::Error::NoSuchCookieError)
  end

  it 'deletes all cookies' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/blank.html'
    # Add cookies into current browser context
    driver.manage.add_cookie(name: 'test1', value: 'cookie1')
    driver.manage.add_cookie(name: 'test2', value: 'cookie2')
    # Delete All cookies
    driver.manage.delete_all_cookies
    # Verify all cookies are deleted
    expect(driver.manage.all_cookies.size).to eq(0)
  end
end
```

```js
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L77-L78)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("https://example.com")
        driver.manage().addCookie(Cookie("test1", "cookie1"))
        driver.manage().addCookie(Cookie("test2", "cookie2"))

        // deletes all cookies
        driver.manage().deleteAllCookies()
    } finally {
        driver.quit()
    }
}  
  
```

```java

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java#L112-L121)

##### /examples/java/src/test/java/dev/selenium/interactions/CookiesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;

import java.util.Set;

public class CookiesTest {

    WebDriver driver = new ChromeDriver();

    @AfterEach
    final void closeBrowser() {
        if (driver != null) {
            driver.quit();
        }
    }

    @Test
    public void addCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("key", "value"));
    }

    @Test
    public void getNamedCookie() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookie into current browser context
        driver.manage().addCookie(new Cookie("foo", "bar"));
        // Get cookie details with named cookie 'foo'
        Cookie cookie = driver.manage().getCookieNamed("foo");
        Assertions.assertEquals(cookie.getValue(), "bar");
    }


    @Test
    public void getAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Get cookies
        Set<Cookie> cookies = driver.manage().getCookies();
        for (Cookie cookie : cookies) {
            if (cookie.getName().equals("test1")) {
                Assertions.assertEquals(cookie.getValue(), "cookie1");
            }

            if (cookie.getName().equals("test2")) {
                Assertions.assertEquals(cookie.getValue(), "cookie2");
            }
        }
    }


    @Test
    public void deleteCookieNamed() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        // delete cookie named
        driver.manage().deleteCookieNamed("test1");
    }

    @Test
    public void deleteCookieObject() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        Cookie cookie = new Cookie("test2", "cookie2");
        driver.manage().addCookie(cookie);
	        /*
	        Selenium Java bindings also provides a way to delete
	        cookie by passing cookie object of current browsing context
	        */
        driver.manage().deleteCookie(cookie);
    }


    @Test
    public void deleteAllCookies() {
        driver.get("https://www.selenium.dev/selenium/web/blank.html");
        // Add cookies into current browser context
        driver.manage().addCookie(new Cookie("test1", "cookie1"));
        driver.manage().addCookie(new Cookie("test2", "cookie2"));
        // Delete All cookies
        driver.manage().deleteAllCookies();
    }

    @Test
    public void sameSiteCookie() {
        driver.get("http://www.example.com");

        Cookie cookie = new Cookie.Builder("key", "value").sameSite("Strict").build();
        Cookie cookie1 = new Cookie.Builder("key", "value").sameSite("Lax").build();

        driver.manage().addCookie(cookie);
        driver.manage().addCookie(cookie1);

        System.out.println(cookie.getSameSite());
        System.out.println(cookie1.getSameSite());
    }
}
```

```py
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_cookies.py#L59-L71)

##### /examples/python/tests/interactions/test\_cookies.py

```py
from selenium import webdriver


def test_add_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "key", "value": "value"})


def test_get_named_cookie():
    driver = webdriver.Chrome()
    driver.get("http://www.example.com")

    # Adds the cookie into current browser context
    driver.add_cookie({"name": "foo", "value": "bar"})

    # Get cookie details with named cookie 'foo'
    print(driver.get_cookie("foo"))


def test_get_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Get all available cookies
    print(driver.get_cookies())

def test_delete_cookie():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete cookie with name 'test1'
    driver.delete_cookie("test1")


def test_delete_all_cookies():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    driver.add_cookie({"name": "test1", "value": "cookie1"})
    driver.add_cookie({"name": "test2", "value": "cookie2"})

    # Delete all cookies
    driver.delete_all_cookies()


def test_same_side_cookie_attr():
    driver = webdriver.Chrome()

    driver.get("http://www.example.com")

    # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
    driver.add_cookie({"name": "foo", "value": "value", "sameSite": "Strict"})
    driver.add_cookie({"name": "foo1", "value": "value", "sameSite": "Lax"})

    cookie1 = driver.get_cookie("foo")
    cookie2 = driver.get_cookie("foo1")

    print(cookie1)
    print(cookie2)
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SameSiteCookie {
  class SameSiteCookie {
    static void Main(string[] args) {
      IWebDriver driver = new ChromeDriver();
      try {
        driver.Navigate().GoToUrl("http://www.example.com");

        var cookie1Dictionary = new System.Collections.Generic.Dictionary<string, object>() {
          { "name", "test1" }, { "value", "cookie1" }, { "sameSite", "Strict" } };
        var cookie1 = Cookie.FromDictionary(cookie1Dictionary);

        var cookie2Dictionary = new System.Collections.Generic.Dictionary<string, object>() {
          { "name", "test2" }, { "value", "cookie2" }, { "sameSite", "Lax" } };
        var cookie2 = Cookie.FromDictionary(cookie2Dictionary);

        driver.Manage().Cookies.AddCookie(cookie1);
        driver.Manage().Cookies.AddCookie(cookie2);

        System.Console.WriteLine(cookie1.SameSite);
        System.Console.WriteLine(cookie2.SameSite);
      } finally {
        driver.Quit();
      }
    }
  }
}
  
```

```ruby
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://www.example.com'
  # Adds the cookie into current browser context with sameSite 'Strict' (or) 'Lax'
  driver.manage.add_cookie(name: "foo", value: "bar", same_site: "Strict")
  driver.manage.add_cookie(name: "foo1", value: "bar", same_site: "Lax")
  puts driver.manage.cookie_named('foo')
  puts driver.manage.cookie_named('foo1')
ensure
  driver.quit
end
  
```

```js
  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/cookies.spec.js#L24-L26)

##### /examples/javascript/test/interactions/cookies.spec.js

```js

const {Browser, Builder} = require("selenium-webdriver");
const assert = require('assert')


describe('Cookies', function() {
  let driver;

  before(async function() {
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .build();
  });

  after(async () => await driver.quit());

  it('Create a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'key', value: 'value' });
  });

  it('Create cookies with sameSite', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain with sameSite 'Strict' (or) 'Lax'
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Strict' });
    await driver.manage().addCookie({ name: 'key', value: 'value', sameSite: 'Lax' });
  });

  it('Read cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // set a cookie on the current domain
    await driver.manage().addCookie({ name: 'foo', value: 'bar' });

    // Get cookie details with named cookie 'foo'
    await driver.manage().getCookie('foo').then(function(cookie) {
      assert.equal(cookie.value, 'bar');
    });
  });

  it('Read all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 2);
    });
  });

  it('Delete a cookie', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete a cookie with name 'test1'
    await driver.manage().deleteCookie('test1');

    // Get all Available cookies
    await driver.manage().getCookies().then(function(cookies) {
      assert.equal(cookies.filter(cookie => cookie.name.startsWith('test')).length, 1);
    });
  });

  it('Delete all cookies', async function() {
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');

    // Add few cookies
    await driver.manage().addCookie({ name: 'test1', value: 'cookie1' });
    await driver.manage().addCookie({ name: 'test2', value: 'cookie2' });

    // Delete all cookies
    await driver.manage().deleteAllCookies();
  });
});
```

```kotlin
import org.openqa.selenium.Cookie
import org.openqa.selenium.chrome.ChromeDriver

fun main() {
    val driver = ChromeDriver()
    try {
        driver.get("http://www.example.com")
        val cookie = Cookie.Builder("key", "value").sameSite("Strict").build()
        val cookie1 = Cookie.Builder("key", "value").sameSite("Lax").build()
        driver.manage().addCookie(cookie)
        driver.manage().addCookie(cookie1)
        println(cookie.getSameSite())
        println(cookie1.getSameSite())
    } finally {
        driver.quit()
    }
} 
  
```

# 4 - IFrame と Frame の操作

Frameは、同じドメイン上の複数のドキュメントからサイトレイアウトを構築する非推奨の手段となりました。 HTML5以前のWebアプリを使用している場合を除き、frameを使用することはほとんどありません。 iFrameは、まったく異なるドメインからのドキュメントの挿入を許可し、今でも一般的に使用されています。

FrameまたはiFrameを使用する必要がある場合、Webdriverを使用して同じ方法で作業できます。 iFrame内のボタンがある場合を考えてみましょう。ブラウザー開発ツールを使用して要素を検査すると、次のように表示される場合があります。

```html
<div id="modal">
  <iframe id="buttonframe" name="myframe"  src="https://seleniumhq.github.io">
   <button>Click here</button>
 </iframe>
</div>
```

```java
//This won't work
driver.findElement(By.tagName("button")).click();
  
```

```python
    # This Wont work
driver.find_element(By.TAG_NAME, 'button').click()
  
```

```csharp
//This won't work
driver.FindElement(By.TagName("button")).Click();
  
```

```ruby
    # This won't work
driver.find_element(:tag_name,'button').click
  
```

```javascript
// This won't work
await driver.findElement(By.css('button')).click();
  
```

```kotlin
//This won't work
driver.findElement(By.tagName("button")).click()
  
```

```java
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L38-L46)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L24-L32)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L38-L46)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L26-L36)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Store the web element
const iframe = driver.findElement(By.css('#modal > iframe'));

// Switch to the frame
await driver.switchTo().frame(iframe);

// Now we can click the button
await driver.findElement(By.css('button')).click();
  
```

```kotlin
//Store the web element
val iframe = driver.findElement(By.cssSelector("#modal>iframe"))

//Switch to the frame
driver.switchTo().frame(iframe)

//Now we can click the button
driver.findElement(By.tagName("button")).click()
  
```

```java
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L50-L58)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L34-L42)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L50-L58)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L36-L43)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Using the ID
await driver.switchTo().frame('buttonframe');

// Or using the name instead
await driver.switchTo().frame('myframe');

// Now we can click the button
await driver.findElement(By.css('button')).click();
  
```

```kotlin
//Using the ID
driver.switchTo().frame("buttonframe")

//Or using the name instead
driver.switchTo().frame("myframe")

//Now we can click the button
driver.findElement(By.tagName("button")).click()
  
```

```java
         //switch To IFrame using index
         driver.switchTo().frame(0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L62-L63)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```py
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_frames.py#L45-L46)

##### /examples/python/tests/interactions/test\_frames.py

```py
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.

from selenium import webdriver
from selenium.webdriver.common.by import By

#set chrome and launch web page
driver = webdriver.Chrome()
driver.get("https://www.selenium.dev/selenium/web/iframes.html")

# --- Switch to iframe using WebElement ---
iframe = driver.find_element(By.ID, "iframe1")
driver.switch_to.frame(iframe)
assert "We Leave From Here" in driver.page_source

email_element = driver.find_element(By.ID, "email")
email_element.send_keys("admin@selenium.dev")
email_element.clear()
driver.switch_to.default_content()

# --- Switch to iframe using name or ID ---
iframe1=driver.find_element(By.NAME, "iframe1-name")  # (This line doesn't switch, just locates)
driver.switch_to.frame(iframe1)
assert "We Leave From Here" in driver.page_source

email = driver.find_element(By.ID, "email")
email.send_keys("admin@selenium.dev")
email.clear()
driver.switch_to.default_content()

# --- Switch to iframe using index ---
driver.switch_to.frame(0)
assert "We Leave From Here" in driver.page_source

# --- Final page content check ---
driver.switch_to.default_content()
assert "This page has iframes" in driver.page_source

#quit the driver
driver.quit()

#demo code for conference
```

```cs
            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L62-L63)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L46-L47)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Switches to the second frame
await driver.switchTo().frame(1);
```

```kotlin
// Switches to the second frame
driver.switchTo().frame(1)
```

```java
         //leave frame
         driver.switchTo().defaultContent();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/FramesTest.java#L66-L67)

##### /examples/java/src/test/java/dev/selenium/interactions/FramesTest.java

```java
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.

package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import static org.junit.jupiter.api.Assertions.assertEquals;

public class FramesTest{

    @Test
    public void informationWithElements() {
    	
    	 WebDriver driver = new ChromeDriver();
         driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        
         // Navigate to Url
         driver.get("https://www.selenium.dev/selenium/web/iframes.html");
        
         
         //switch To IFrame using Web Element
         WebElement iframe = driver.findElement(By.id("iframe1"));
         //Switch to the frame
         driver.switchTo().frame(iframe);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         //Now we can type text into email field
         WebElement emailE = driver.findElement(By.id("email"));
         emailE.sendKeys("admin@selenium.dev");
         emailE.clear();
         driver.switchTo().defaultContent();
       
         
         //switch To IFrame using name or id
         WebElement iframe1=driver.findElement(By.name("iframe1-name"));
         //Switch to the frame
         driver.switchTo().frame(iframe1);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         WebElement email = driver.findElement(By.id("email"));
         //Now we can type text into email field
         email.sendKeys("admin@selenium.dev");
         email.clear();
         driver.switchTo().defaultContent();
     
         
         //switch To IFrame using index
         driver.switchTo().frame(0);
         assertEquals(true, driver.getPageSource().contains("We Leave From Here"));
         
         //leave frame
         driver.switchTo().defaultContent();
         assertEquals(true, driver.getPageSource().contains("This page has iframes"));
         
         //quit the browser
         driver.quit();
    }

}
```

```python
    # switch back to default content
driver.switch_to.default_content()
  
```

```cs
            //leave frame
            driver.SwitchTo().DefaultContent();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs#L66-L67)

##### /examples/dotnet/SeleniumDocs/Interactions/FramesTest.cs

```cs
// Licensed to the Software Freedom Conservancy (SFC) under one
// or more contributor license agreements.  See the NOTICE file
// distributed with this work for additional information
// regarding copyright ownership.  The SFC licenses this file
// to you under the Apache License, Version 2.0 (the
// "License"); you may not use this file except in compliance
// with the License.  You may obtain a copy of the License at
//
//   http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing,
// software distributed under the License is distributed on an
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
// KIND, either express or implied.  See the License for the
// specific language governing permissions and limitations
// under the License.


using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using System.Collections.Generic;

namespace SeleniumDocs.Interactions
{
  [TestClass]
    public class FramesTest
    {
        [TestMethod]
        public void TestFrames()
        {
            WebDriver driver = new ChromeDriver();
            driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

            // Navigate to Url
            driver.Url= "https://www.selenium.dev/selenium/web/iframes.html";
            //switch To IFrame using Web Element
            IWebElement iframe = driver.FindElement(By.Id("iframe1"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            //Now we can type text into email field
            IWebElement emailE = driver.FindElement(By.Id("email"));
            emailE.SendKeys("admin@selenium.dev");
            emailE.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using name or id
            IWebElement iframe1=driver.FindElement(By.Name("iframe1-name"));
            //Switch to the frame
            driver.SwitchTo().Frame(iframe1);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));
            IWebElement email = driver.FindElement(By.Id("email"));
            //Now we can type text into email field
            email.SendKeys("admin@selenium.dev");
            email.Clear();
            driver.SwitchTo().DefaultContent();


            //switch To IFrame using index
            driver.SwitchTo().Frame(0);
            Assert.AreEqual(true, driver.PageSource.Contains("We Leave From Here"));

            //leave frame
            driver.SwitchTo().DefaultContent();
            Assert.AreEqual(true, driver.PageSource.Contains("This page has iframes"));

            //quit the browser
            driver.Quit();
        }
    }
}
```

```rb
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/frames_spec.rb#L49-L50)

##### /examples/ruby/spec/interactions/frames\_spec.rb

```rb
# Licensed to the Software Freedom Conservancy (SFC) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The SFC licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#   http://www.apache.org/licenses/LICENSE-2.0
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied.  See the License for the
# specific language governing permissions and limitations
# under the License.
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Frames' do
  let(:driver) { start_session }

  it 'performs iframe switching operations' do
    driver.navigate.to 'https://www.selenium.dev/selenium/web/iframes.html'
    # --- Switch to iframe using WebElement ---
    iframe = driver.find_element(:id, 'iframe1')
    driver.switch_to.frame(iframe)
    expect(driver.page_source).to include('We Leave From Here')

    email_element = driver.find_element(:id, 'email')
    email_element.send_keys('admin@selenium.dev')
    email_element.clear
    driver.switch_to.default_content

    # --- Switch to iframe using name or ID ---
    iframe1 = driver.find_element(:name, 'iframe1-name')
    driver.switch_to.frame(iframe1)
    expect(driver.page_source).to include('We Leave From Here')

    email = driver.find_element(:id, 'email')
    email.send_keys('admin@selenium.dev')
    email.clear
    driver.switch_to.default_content

    # --- Switch to iframe using index ---
    driver.switch_to.frame(0)
    expect(driver.page_source).to include('We Leave From Here')
    # --- Final page content check ---
    driver.switch_to.default_content
    expect(driver.page_source).to include('This page has iframes')
  end
end
```

```javascript
// Return to the top level
await driver.switchTo().defaultContent();
  
```

```kotlin
// Return to the top level
driver.switchTo().defaultContent()
  
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L14-L17)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L12-L19)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L12-L14)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L23-L26)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L22-L29)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L18-L20)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L32-L35)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L32-L38)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L24-L26)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L41-L48)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L51-L57)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L30-L35)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L53-L57)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L61-L68)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L42-L45)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L63-L66)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L41-L48)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L49-L51)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L72-L75)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L71-L78)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L55-L57)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java#L27-L31)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.Pdf;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.PrintsPage;
import dev.selenium.BaseTest;

public class PrintsPageTest extends BaseTest{

    @BeforeEach
    public void setup() {
        ChromeOptions options = getDefaultChromeOptions();
        options.setCapability("webSocketUrl", true);
        driver = new ChromeDriver(options);
    }

    @Test
    public void PrintWithPrintsPageTest() 
    {
        driver.get("https://www.selenium.dev/");
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }

    @Test
    public void PrintWithBrowsingContextTest() 
    {
        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);
        Assertions.assertTrue(printPage.length() > 0);
    }
}
```

**BrowsingContext()**

```java
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        PrintOptions printOptions = new PrintOptions();
        String printPage = browsingContext.print(printOptions);
        Assertions.assertTrue(printPage.length() > 0);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java#L37-L41)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.Pdf;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.PrintsPage;
import dev.selenium.BaseTest;

public class PrintsPageTest extends BaseTest{

    @BeforeEach
    public void setup() {
        ChromeOptions options = getDefaultChromeOptions();
        options.setCapability("webSocketUrl", true);
        driver = new ChromeDriver(options);
    }

    @Test
    public void PrintWithPrintsPageTest() 
    {
        driver.get("https://www.selenium.dev/");
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }

    @Test
    public void PrintWithBrowsingContextTest() 
    {
        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);
        Assertions.assertTrue(printPage.length() > 0);
    }
}
```

```cs
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L81-L88)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

**print\_page()**

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    pdf = driver.print_page(print_options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_prints_page.py#L12-L14)

##### /examples/python/tests/interactions/test\_prints\_page.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_prints_page(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    pdf = driver.print_page(print_options)
    assert len(pdf) > 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

# 6 - ウィンドウとタブの操作

```java
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L16-L20)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L16-L18)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L17-L21)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
driver.window_handle
```

```javascript
await driver.getWindowHandle();
```

```kotlin
driver.windowHandle
```

```java
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L22-L29)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L22-L32)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L23-L30)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
    #Store the ID of the original window
original_window = driver.window_handle

    #Check we don't have other windows open already
assert(driver.window_handles.length == 1, 'Expected one window')

    #Click the link which opens in a new window
driver.find_element(link: 'new window').click

    #Wait for the new window or tab
wait.until { driver.window_handles.length == 2 }

    #Loop through until we find a new window handle
driver.window_handles.each do |handle|
    if handle != original_window
        driver.switch_to.window handle
        break
    end
end

    #Wait for the new tab to finish loading content
wait.until { driver.title == 'Selenium documentation'}
  
```

```javascript
//Store the ID of the original window
const originalWindow = await driver.getWindowHandle();

//Check we don't have other windows open already
assert((await driver.getAllWindowHandles()).length === 1);

//Click the link which opens in a new window
await driver.findElement(By.linkText('new window')).click();

//Wait for the new window or tab
await driver.wait(
    async () => (await driver.getAllWindowHandles()).length === 2,
    10000
  );

//Loop through until we find a new window handle
const windows = await driver.getAllWindowHandles();
windows.forEach(async handle => {
  if (handle !== originalWindow) {
    await driver.switchTo().window(handle);
  }
});

//Wait for the new tab to finish loading content
await driver.wait(until.titleIs('Selenium documentation'), 10000);
  
```

```kotlin
//Store the ID of the original window
val originalWindow = driver.getWindowHandle()

//Check we don't have other windows open already
assert(driver.getWindowHandles().size() === 1)

//Click the link which opens in a new window
driver.findElement(By.linkText("new window")).click()

//Wait for the new window or tab
wait.until(numberOfWindowsToBe(2))

//Loop through until we find a new window handle
for (windowHandle in driver.getWindowHandles()) {
    if (!originalWindow.contentEquals(windowHandle)) {
        driver.switchTo().window(windowHandle)
        break
    }
}

//Wait for the new tab to finish loading content
wait.until(titleIs("Selenium documentation"))

  
```

```java
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L31-L34)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.close()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L46-L46)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L32-L35)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
    #Close the tab or window
driver.close

    #Switch back to the old tab or window
driver.switch_to.window original_window
  
```

```javascript
//Close the tab or window
await driver.close();

//Switch back to the old tab or window
await driver.switchTo().window(originalWindow);
  
```

```kotlin
//Close the tab or window
driver.close()

//Switch back to the old tab or window
driver.switchTo().window(originalWindow)

  
```

```java
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L36-L42)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L53-L58)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L37-L43)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

Opens a new tab and switches to new tab

```rb
    driver.switch_to.new_window(:tab)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/windows_spec.rb#L9)

##### /examples/ruby/spec/interactions/windows\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Windows' do
  let(:driver) { start_session }

  it 'opens new tab' do
    driver.switch_to.new_window(:tab)

    expect(driver.window_handles.size).to eq 2
  end

  it 'opens new window' do
    driver.switch_to.new_window(:window)

    expect(driver.window_handles.size).to eq 2
  end
end
```

Opens a new window and switches to new window

```rb
    driver.switch_to.new_window(:window)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/interactions/windows_spec.rb#L15)

##### /examples/ruby/spec/interactions/windows\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Windows' do
  let(:driver) { start_session }

  it 'opens new tab' do
    driver.switch_to.new_window(:tab)

    expect(driver.window_handles.size).to eq 2
  end

  it 'opens new window' do
    driver.switch_to.new_window(:window)

    expect(driver.window_handles.size).to eq 2
  end
end
```

Opens a new tab and switches to new tab

```js
    await driver.switchTo().newWindow('tab');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L70)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

Opens a new window and switches to new window:

```js
    await driver.switchTo().newWindow('window');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L75)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Opens a new tab and switches to new tab
driver.switchTo().newWindow(WindowType.TAB)

// Opens a new window and switches to new window
driver.switchTo().newWindow(WindowType.WINDOW)
  
```

```java
        //quitting driver
        driver.quit(); //close all windows
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java#L44-L45)

##### /examples/java/src/test/java/dev/selenium/interactions/WindowsTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.time.Duration;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;

public class WindowsTest {

    @Test
    public void windowsExampleCode() {
        
    	WebDriver driver = new ChromeDriver();
        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));
        // Navigate to Url
        driver.get("https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html");
        //fetch handle of this
        String currHandle=driver.getWindowHandle();
        assertNotNull(currHandle);
        
        //click on link to open a new window
        driver.findElement(By.linkText("Open new window")).click();
        //fetch handles of all windows, there will be two, [0]- default, [1] - new window
        Object[] windowHandles=driver.getWindowHandles().toArray();
        driver.switchTo().window((String) windowHandles[1]);
        //assert on title of new window
        String title=driver.getTitle();
        assertEquals("Simple Page",title);
        
        //closing current window
        driver.close();
        //Switch back to the old tab or window
        driver.switchTo().window((String) windowHandles[0]);
        
        //Opens a new tab and switches to new tab
        driver.switchTo().newWindow(WindowType.TAB);
        assertEquals("",driver.getTitle());
        
        //Opens a new window and switches to new window
        driver.switchTo().newWindow(WindowType.WINDOW);
        assertEquals("",driver.getTitle());
             
        //quitting driver
        driver.quit(); //close all windows
	   
   	}
}
```

```py
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_windows.py#L13-L13)

##### /examples/python/tests/interactions/test\_windows.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC

url = "https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html"

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_current_window_handle(driver):
    driver.get(url)
    current_handle = driver.current_window_handle
    assert current_handle is not None


def test_switch_to_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)
    assert driver.current_window_handle == new_window_handle

def test_close_window(driver):
    driver.get(url)
    wait = WebDriverWait(driver, 10)

    original_window_handle = driver.current_window_handle

    driver.find_element(By.LINK_TEXT, "Open new window").click()
    wait.until(EC.number_of_windows_to_be(2))

    new_window_handle = (set(driver.window_handles) - {original_window_handle}).pop()
    driver.switch_to.window(new_window_handle)

    driver.close()
    driver.switch_to.window(original_window_handle)

    assert driver.current_window_handle == original_window_handle
    assert len(driver.window_handles) == 1

def test_create_new_window(driver):
    # Opens a new tab and switches to new tab
    driver.switch_to.new_window('tab')
    assert driver.title == ""
    # Opens a new window and switches to new window
    driver.switch_to.new_window('window')
    assert driver.title == ""
```

```cs
            //quitting driver
              driver.Quit(); //close all windows
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs#L45-L46)

##### /examples/dotnet/SeleniumDocs/Interactions/WindowsTest.cs

```cs
using System;
  using Microsoft.VisualStudio.TestTools.UnitTesting;
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using System.Collections.Generic;
  namespace SeleniumDocs.Interactions
  {
      [TestClass]
      public class WindowsTest
      {
          [TestMethod]
          public void TestWindowCommands()
          {
              WebDriver driver = new ChromeDriver();
              driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);
  
              // Navigate to Url
              driver.Url="https://www.selenium.dev/selenium/web/window_switching_tests/page_with_frame.html";
              //fetch handle of this
              String currHandle = driver.CurrentWindowHandle;
              Assert.IsNotNull(currHandle);
  
              //click on link to open a new window
              driver.FindElement(By.LinkText("Open new window")).Click();
              //fetch handles of all windows, there will be two, [0]- default, [1] - new window
              IList<string> windowHandles = new List<string>(driver.WindowHandles);
              driver.SwitchTo().Window(windowHandles[1]);
              //assert on title of new window
              String title = driver.Title;
              Assert.AreEqual("Simple Page", title);
  
              //closing current window
              driver.Close();
              //Switch back to the old tab or window
              driver.SwitchTo().Window(windowHandles[0]);
  
              //Opens a new tab and switches to new tab
              driver.SwitchTo().NewWindow(WindowType.Tab);
              Assert.AreEqual("", driver.Title);
  
              //Opens a new window and switches to new window
              driver.SwitchTo().NewWindow(WindowType.Window);
              Assert.AreEqual("", driver.Title);
  
              //quitting driver
              driver.Quit(); //close all windows
          }
      }
  }
  
```

```ruby
driver.quit
```

```javascript
await driver.quit();
```

```kotlin
driver.quit()
```

```java
/**
 * Example using JUnit
 * https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
 */
@AfterAll
public static void tearDown() {
    driver.quit();
}
  
```

```python
    # unittest teardown
    # https://docs.python.org/3/library/unittest.html?highlight=teardown#unittest.TestCase.tearDown
def tearDown(self):
    self.driver.quit()
  
```

```csharp
/*
    Example using Visual Studio's UnitTesting
    https://msdn.microsoft.com/en-us/library/microsoft.visualstudio.testtools.unittesting.aspx
*/
[TestCleanup]
public void TearDown()
{
    driver.Quit();
}
  
```

```ruby
    # UnitTest Teardown
    # https://www.rubydoc.info/github/test-unit/test-unit/Test/Unit/TestCase
def teardown
    @driver.quit
end
  
```

```javascript
/**
 * Example using Mocha
 * https://mochajs.org/#hooks
 */
after('Tear down', async function () {
  await driver.quit();
});
  
```

```kotlin
/**
 * Example using JUnit
 * https://junit.org/junit5/docs/current/api/org/junit/jupiter/api/AfterAll.html
 */
@AfterAll
fun tearDown() {
    driver.quit()
}
  
```

```java
try {
    //WebDriver code here...
} finally {
    driver.quit();
}
  
```

```python
try:
    #WebDriver code here...
finally:
    driver.quit()
  
```

```csharp
try {
    //WebDriver code here...
} finally {
    driver.Quit();
}
  
```

```ruby
begin
    #WebDriver code here...
ensure
    driver.quit
end
  
```

```javascript
try {
    //WebDriver code here...
} finally {
    await driver.quit();
}
  
```

```kotlin
try {
    //WebDriver code here...
} finally {
    driver.quit()
}
  
```

PythonのWebDriverは、pythonコンテキストマネージャーをサポートするようになりました。 withキーワードを使用すると、実行終了時にドライバーを自動的に終了できます。

```python
with webdriver.Firefox() as driver:
  # WebDriver code here...

# WebDriver will automatically quit after indentation
```

```java
//Access each dimension individually
int width = driver.manage().window().getSize().getWidth();
int height = driver.manage().window().getSize().getHeight();

//Or store the dimensions and query them later
Dimension size = driver.manage().window().getSize();
int width1 = size.getWidth();
int height1 = size.getHeight();
  
```

```python
    # Access each dimension individually
width = driver.get_window_size().get("width")
height = driver.get_window_size().get("height")

    # Or store the dimensions and query them later
size = driver.get_window_size()
width1 = size.get("width")
height1 = size.get("height")
  
```

```csharp
//Access each dimension individually
int width = driver.Manage().Window.Size.Width;
int height = driver.Manage().Window.Size.Height;

//Or store the dimensions and query them later
System.Drawing.Size size = driver.Manage().Window.Size;
int width1 = size.Width;
int height1 = size.Height;
  
```

```ruby
    # Access each dimension individually
width = driver.manage.window.size.width
height = driver.manage.window.size.height

    # Or store the dimensions and query them later
size = driver.manage.window.size
width1 = size.width
height1 = size.height
  
```

Access each dimension individually

```js
    const { width, height } = await driver.manage().window().getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L93)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

(or) store the dimensions and query them later

```js
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L96-L98)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
//Access each dimension individually
val width = driver.manage().window().size.width
val height = driver.manage().window().size.height

//Or store the dimensions and query them later
val size = driver.manage().window().size
val width1 = size.width
val height1 = size.height
  
```

```java
driver.manage().window().setSize(new Dimension(1024, 768));
```

```python
driver.set_window_size(1024, 768)
```

```csharp
driver.Manage().Window.Size = new Size(1024, 768);
```

```ruby
driver.manage.window.resize_to(1024,768)
```

```javascript
await driver.manage().window().setRect({ width: 1024, height: 768 });
```

```kotlin
driver.manage().window().size = Dimension(1024, 768)
```

```java
// Access each dimension individually
int x = driver.manage().window().getPosition().getX();
int y = driver.manage().window().getPosition().getY();

// Or store the dimensions and query them later
Point position = driver.manage().window().getPosition();
int x1 = position.getX();
int y1 = position.getY();
  
```

```python
    # Access each dimension individually
x = driver.get_window_position().get('x')
y = driver.get_window_position().get('y')

    # Or store the dimensions and query them later
position = driver.get_window_position()
x1 = position.get('x')
y1 = position.get('y')
  
```

```csharp
//Access each dimension individually
int x = driver.Manage().Window.Position.X;
int y = driver.Manage().Window.Position.Y;

//Or store the dimensions and query them later
Point position = driver.Manage().Window.Position;
int x1 = position.X;
int y1 = position.Y;
  
```

```ruby
    #Access each dimension individually
x = driver.manage.window.position.x
y = driver.manage.window.position.y

    # Or store the dimensions and query them later
rect  = driver.manage.window.rect
x1 = rect.x
y1 = rect.y
  
```

Access each dimension individually

```js
    const { x, y } = await driver.manage().window().getRect();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L108)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

(or) store the dimensions and query them later

```js
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L111-L113)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Access each dimension individually
val x = driver.manage().window().position.x
val y = driver.manage().window().position.y

// Or store the dimensions and query them later
val position = driver.manage().window().position
val x1 = position.x
val y1 = position.y

  
```

```
## ウィンドウの位置設定
```

```java
// Move the window to the top left of the primary monitor
driver.manage().window().setPosition(new Point(0, 0));
  
```

```python
    # Move the window to the top left of the primary monitor
driver.set_window_position(0, 0)
  
```

```csharp
// Move the window to the top left of the primary monitor
driver.Manage().Window.Position = new Point(0, 0);
  
```

```ruby
driver.manage.window.move_to(0,0)
  
```

```javascript
// Move the window to the top left of the primary monitor
await driver.manage().window().setRect({ x: 0, y: 0 });
  
```

```kotlin
// Move the window to the top left of the primary monitor
driver.manage().window().position = Point(0,0)
    
```

```java
driver.manage().window().maximize();
```

```python
driver.maximize_window()
```

```csharp
driver.Manage().Window.Maximize();
```

```ruby
driver.manage.window.maximize
```

```javascript
await driver.manage().window().maximize();
```

```kotlin
driver.manage().window().maximize()
```

```java
driver.manage().window().minimize();
```

```python
driver.minimize_window()
```

```csharp
driver.Manage().Window.Minimize();
```

```ruby
driver.manage.window.minimize
```

```javascript
await driver.manage().window().minimize();
```

```kotlin
driver.manage().window().minimize()
```

```java
driver.manage().window().fullscreen();
```

```python
driver.fullscreen_window()
```

```csharp
driver.Manage().Window.FullScreen();
```

```ruby
driver.manage.window.full_screen
```

```javascript
await driver.manage().window().fullscreen();
```

```kotlin
driver.manage().window().fullscreen()
```

```java
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.*;
import org.openqa.selenium.*;

public class SeleniumTakeScreenshot {
    public static void main(String args[]) throws IOException {
        WebDriver driver = new ChromeDriver();
        driver.get("http://www.example.com");
        File scrFile = ((TakesScreenshot)driver).getScreenshotAs(OutputType.FILE);
        FileUtils.copyFile(scrFile, new File("./image.png"));
        driver.quit();
    }
}
  
```

```python
from selenium import webdriver

driver = webdriver.Chrome()

    # Navigate to url
driver.get("http://www.example.com")

    # Returns and base64 encoded string into image
driver.save_screenshot('./image.png')

driver.quit()
```

```csharp
  using OpenQA.Selenium;
  using OpenQA.Selenium.Chrome;
  using OpenQA.Selenium.Support.UI;

  var driver = new ChromeDriver();
  driver.Navigate().GoToUrl("http://www.example.com");
  Screenshot screenshot = (driver as ITakesScreenshot).GetScreenshot();
  screenshot.SaveAsFile("screenshot.png", ScreenshotImageFormat.Png); // Format values are Bmp, Gif, Jpeg, Png, Tiff
  
```

```ruby
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://example.com/'

    # Takes and Stores the screenshot in specified path
  driver.save_screenshot('./image.png')

end
  
```

```js
    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L56-L59)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
import com.oracle.tools.packager.IOUtils.copyFile
import org.openqa.selenium.*
import org.openqa.selenium.chrome.ChromeDriver
import java.io.File

fun main(){
    val driver =  ChromeDriver()
    driver.get("https://www.example.com")
    val scrFile = (driver as TakesScreenshot).getScreenshotAs<File>(OutputType.FILE)
    copyFile(scrFile, File("./image.png"))
    driver.quit()
}
  
```

```java
import org.apache.commons.io.FileUtils;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import java.io.File;
import java.io.IOException;

public class SeleniumelementTakeScreenshot {
  public static void main(String args[]) throws IOException {
    WebDriver driver = new ChromeDriver();
    driver.get("https://www.example.com");
    WebElement element = driver.findElement(By.cssSelector("h1"));
    File scrFile = element.getScreenshotAs(OutputType.FILE);
    FileUtils.copyFile(scrFile, new File("./image.png"));
    driver.quit();
  }
}
 
```

```python
from selenium import webdriver
from selenium.webdriver.common.by import By

driver = webdriver.Chrome()

    # Navigate to url
driver.get("http://www.example.com")

ele = driver.find_element(By.CSS_SELECTOR, 'h1')

    # Returns and base64 encoded string into image
ele.screenshot('./image.png')

driver.quit()
  
```

```csharp
    using OpenQA.Selenium;
    using OpenQA.Selenium.Chrome;
    using OpenQA.Selenium.Support.UI;

    // Webdriver
    var driver = new ChromeDriver();
    driver.Navigate().GoToUrl("http://www.example.com");

    // Fetch element using FindElement
    var webElement = driver.FindElement(By.CssSelector("h1"));

    // Screenshot for the element
    var elementScreenshot = (webElement as ITakesScreenshot).GetScreenshot();
    elementScreenshot.SaveAsFile("screenshot_of_element.png");
  
```

```ruby
    # Works with Selenium4-alpha7 Ruby bindings and above
require 'selenium-webdriver'
driver = Selenium::WebDriver.for :chrome

begin
  driver.get 'https://example.com/'
  ele = driver.find_element(:css, 'h1')

    # Takes and Stores the element screenshot in specified path
  ele.save_screenshot('./image.jpg')
end
  
```

```js
    let header = await driver.findElement(By.css('h1'));
      // Captures the element screenshot
      let encodedString = await header.takeScreenshot(true);
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
  
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L44-L48)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
  const chrome = require('selenium-webdriver/chrome');
  const assert = require("node:assert");
  let opts = new chrome.Options();
  opts.addArguments('--headless');
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let imgMagicNumber = 'iVBOR'
  let base64Code
  
  describe('Interactions - Windows', function () {
    let driver;
    before(async function () {
      driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
    });
  
    after(async () => await driver.quit());
  
    it('Should be able to print page to pdf', async function () {
  
      await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
      let base64 = await driver.printPage({pageRanges: ["1-2"]});
      // page can be saved as a PDF as below
      // await fs.writeFileSync('./test.pdf', base64, 'base64');
  
      base64Code = base64.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, pdfMagicNumber)
    });
  
    it('Should be able to get text using executeScript', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
      // Stores the header element
      let header = await driver.findElement(By.css('h1'));
  
      // Executing JavaScript to capture innerText of header element
      let text = await driver.executeScript('return arguments[0].innerText', header);
      assert.strictEqual(text, `Type Stuff`)
    });
  
    it('Should be able to take Element Screenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      let header = await driver.findElement(By.css('h1'));
      // Captures the element screenshot
      let encodedString = await header.takeScreenshot(true);
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to takeScreenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      // Captures the screenshot
      let encodedString = await driver.takeScreenshot();
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to switch to newWindow and newTab and close', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
      const initialWindow = await driver.getAllWindowHandles();
      assert.strictEqual(initialWindow.length, 1)
  
      // Opens a new tab and switches to new tab
      await driver.switchTo().newWindow('tab');
      const browserTabs = await driver.getAllWindowHandles();
      assert.strictEqual(browserTabs.length, 2)
  
      // Opens a new window and switches to new window
      await driver.switchTo().newWindow('window');
      const windows = await driver.getAllWindowHandles();
      assert.strictEqual(windows.length, 3)
  
      //Close the tab or window
      await driver.close();
  
      //Switch back to the old tab or window
      await driver.switchTo().window(windows[1]);
  
      const windowsAfterClose = await driver.getAllWindowHandles();
      assert.strictEqual(windowsAfterClose.length, 2);
    });
  
    it('Should be able to getWindow Size', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { width, height } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const windowWidth = rect.width;
      const windowHeight = rect.height;
  
      assert.ok(windowWidth>0);
      assert.ok(windowHeight>0);
    });
  
    it('Should be able to getWindow position', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { x, y } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const x1 = rect.x;
      const y1 = rect.y;
  
      assert.ok(x1>=0);
      assert.ok(y1>=0);
    });
  });
```

```kotlin
import org.apache.commons.io.FileUtils
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.*
import java.io.File

fun main() {
    val driver = ChromeDriver()
    driver.get("https://www.example.com")
    val element = driver.findElement(By.cssSelector("h1"))
    val scrFile: File = element.getScreenshotAs(OutputType.FILE)
    FileUtils.copyFile(scrFile, File("./image.png"))
    driver.quit()
}
  
```

```java
    //Creating the JavascriptExecutor interface object by Type casting
      JavascriptExecutor js = (JavascriptExecutor)driver;
    //Button Element
      WebElement button =driver.findElement(By.name("btnLogin"));
    //Executing JavaScript to click on element
      js.executeScript("arguments[0].click();", button);
    //Get return value from script
      String text = (String) js.executeScript("return arguments[0].innerText", button);
    //Executing JavaScript directly
      js.executeScript("console.log('hello world')");
  
```

```python
    # Stores the header element
header = driver.find_element(By.CSS_SELECTOR, "h1")

    # Executing JavaScript to capture innerText of header element
driver.execute_script('return arguments[0].innerText', header)
  
```

```csharp
    //creating Chromedriver instance
	IWebDriver driver = new ChromeDriver();
	//Creating the JavascriptExecutor interface object by Type casting
	IJavaScriptExecutor js = (IJavaScriptExecutor) driver;
	//Button Element
	IWebElement button = driver.FindElement(By.Name("btnLogin"));
	//Executing JavaScript to click on element
	js.ExecuteScript("arguments[0].click();", button);
	//Get return value from script
	String text = (String)js.ExecuteScript("return arguments[0].innerText", button);
	//Executing JavaScript directly
	js.ExecuteScript("console.log('hello world')");
  
```

```ruby
    # Stores the header element
header = driver.find_element(css: 'h1')

    # Get return value from script
result = driver.execute_script("return arguments[0].innerText", header)

    # Executing JavaScript directly
driver.execute_script("alert('hello world')")
  
```

```js
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L33-L37)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
const chrome = require('selenium-webdriver/chrome');
const assert = require("node:assert");
let opts = new chrome.Options();
opts.addArguments('--headless');
let startIndex = 0
let endIndex = 5
let pdfMagicNumber = 'JVBER'
let imgMagicNumber = 'iVBOR'
let base64Code

describe('Interactions - Windows', function () {
  let driver;
  before(async function () {
    driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
  });

  after(async () => await driver.quit());

  it('Should be able to print page to pdf', async function () {

    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
    let base64 = await driver.printPage({pageRanges: ["1-2"]});
    // page can be saved as a PDF as below
    // await fs.writeFileSync('./test.pdf', base64, 'base64');

    base64Code = base64.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, pdfMagicNumber)
  });

  it('Should be able to get text using executeScript', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
    // Stores the header element
    let header = await driver.findElement(By.css('h1'));

    // Executing JavaScript to capture innerText of header element
    let text = await driver.executeScript('return arguments[0].innerText', header);
    assert.strictEqual(text, `Type Stuff`)
  });

  it('Should be able to take Element Screenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    let header = await driver.findElement(By.css('h1'));
    // Captures the element screenshot
    let encodedString = await header.takeScreenshot(true);
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to takeScreenshot', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');

    // Captures the screenshot
    let encodedString = await driver.takeScreenshot();
    // save screenshot as below
    // await fs.writeFileSync('./image.png', encodedString, 'base64');
    base64Code = encodedString.slice(startIndex, endIndex)
    assert.strictEqual(base64Code, imgMagicNumber)
  });

  it('Should be able to switch to newWindow and newTab and close', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');
    const initialWindow = await driver.getAllWindowHandles();
    assert.strictEqual(initialWindow.length, 1)

    // Opens a new tab and switches to new tab
    await driver.switchTo().newWindow('tab');
    const browserTabs = await driver.getAllWindowHandles();
    assert.strictEqual(browserTabs.length, 2)

    // Opens a new window and switches to new window
    await driver.switchTo().newWindow('window');
    const windows = await driver.getAllWindowHandles();
    assert.strictEqual(windows.length, 3)

    //Close the tab or window
    await driver.close();

    //Switch back to the old tab or window
    await driver.switchTo().window(windows[1]);

    const windowsAfterClose = await driver.getAllWindowHandles();
    assert.strictEqual(windowsAfterClose.length, 2);
  });

  it('Should be able to getWindow Size', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { width, height } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const windowWidth = rect.width;
    const windowHeight = rect.height;

    assert.ok(windowWidth>0);
    assert.ok(windowHeight>0);
  });

  it('Should be able to getWindow position', async function () {
    await driver.get('https://www.selenium.dev/selenium/web/');

    // Access each dimension individually
    const { x, y } = await driver.manage().window().getRect();

    // Or store the dimensions and query them later
    const rect = await driver.manage().window().getRect();
    const x1 = rect.x;
    const y1 = rect.y;

    assert.ok(x1>=0);
    assert.ok(y1>=0);
  });
});
```

```kotlin
// Stores the header element
val header = driver.findElement(By.cssSelector("h1"))

// Get return value from script
val result = driver.executeScript("return arguments[0].innerText", header)

// Executing JavaScript directly
driver.executeScript("alert('hello world')")
  
```

```java
    import org.openqa.selenium.print.PrintOptions;

    driver.get("https://www.selenium.dev");
    printer = (PrintsPage) driver;

    PrintOptions printOptions = new PrintOptions();
    printOptions.setPageRanges("1-2");

    Pdf pdf = printer.print(printOptions);
    String content = pdf.getContent();
  
```

```python
    from selenium.webdriver.common.print_page_options import PrintOptions

    print_options = PrintOptions()
    print_options.page_ranges = ['1-2']

    driver.get("printPage.html")

    base64code = driver.print_page(print_options)
  
```

```csharp
    // code sample not available please raise a PR
  
```

```ruby
    driver.navigate_to 'https://www.selenium.dev'

    base64encodedContent = driver.print_page(orientation: 'landscape')
  
```

```js
    await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
      let base64 = await driver.printPage({pageRanges: ["1-2"]});
      // page can be saved as a PDF as below
      // await fs.writeFileSync('./test.pdf', base64, 'base64');
  
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/interactions/windows.spec.js#L22-L25)

##### /examples/javascript/test/interactions/windows.spec.js

```js
const {Builder, By} = require('selenium-webdriver');
  const chrome = require('selenium-webdriver/chrome');
  const assert = require("node:assert");
  let opts = new chrome.Options();
  opts.addArguments('--headless');
  let startIndex = 0
  let endIndex = 5
  let pdfMagicNumber = 'JVBER'
  let imgMagicNumber = 'iVBOR'
  let base64Code
  
  describe('Interactions - Windows', function () {
    let driver;
    before(async function () {
      driver = await new Builder().forBrowser('chrome').setChromeOptions(opts).build();
    });
  
    after(async () => await driver.quit());
  
    it('Should be able to print page to pdf', async function () {
  
      await driver.get('https://www.selenium.dev/selenium/web/alerts.html');
      let base64 = await driver.printPage({pageRanges: ["1-2"]});
      // page can be saved as a PDF as below
      // await fs.writeFileSync('./test.pdf', base64, 'base64');
  
      base64Code = base64.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, pdfMagicNumber)
    });
  
    it('Should be able to get text using executeScript', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
      // Stores the header element
      let header = await driver.findElement(By.css('h1'));
  
      // Executing JavaScript to capture innerText of header element
      let text = await driver.executeScript('return arguments[0].innerText', header);
      assert.strictEqual(text, `Type Stuff`)
    });
  
    it('Should be able to take Element Screenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      let header = await driver.findElement(By.css('h1'));
      // Captures the element screenshot
      let encodedString = await header.takeScreenshot(true);
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to takeScreenshot', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/javascriptPage.html');
  
      // Captures the screenshot
      let encodedString = await driver.takeScreenshot();
      // save screenshot as below
      // await fs.writeFileSync('./image.png', encodedString, 'base64');
      base64Code = encodedString.slice(startIndex, endIndex)
      assert.strictEqual(base64Code, imgMagicNumber)
    });
  
    it('Should be able to switch to newWindow and newTab and close', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
      const initialWindow = await driver.getAllWindowHandles();
      assert.strictEqual(initialWindow.length, 1)
  
      // Opens a new tab and switches to new tab
      await driver.switchTo().newWindow('tab');
      const browserTabs = await driver.getAllWindowHandles();
      assert.strictEqual(browserTabs.length, 2)
  
      // Opens a new window and switches to new window
      await driver.switchTo().newWindow('window');
      const windows = await driver.getAllWindowHandles();
      assert.strictEqual(windows.length, 3)
  
      //Close the tab or window
      await driver.close();
  
      //Switch back to the old tab or window
      await driver.switchTo().window(windows[1]);
  
      const windowsAfterClose = await driver.getAllWindowHandles();
      assert.strictEqual(windowsAfterClose.length, 2);
    });
  
    it('Should be able to getWindow Size', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { width, height } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const windowWidth = rect.width;
      const windowHeight = rect.height;
  
      assert.ok(windowWidth>0);
      assert.ok(windowHeight>0);
    });
  
    it('Should be able to getWindow position', async function () {
      await driver.get('https://www.selenium.dev/selenium/web/');
  
      // Access each dimension individually
      const { x, y } = await driver.manage().window().getRect();
  
      // Or store the dimensions and query them later
      const rect = await driver.manage().window().getRect();
      const x1 = rect.x;
      const y1 = rect.y;
  
      assert.ok(x1>=0);
      assert.ok(y1>=0);
    });
  });
```

```kotlin
    driver.get("https://www.selenium.dev")
    val printer = driver as PrintsPage

    val printOptions = PrintOptions()
    printOptions.setPageRanges("1-2")
    
    val pdf: Pdf = printer.print(printOptions)
    val content = pdf.content
  
```

# 7 - Virtual Authenticator

```java
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L55-L61)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L48-55)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L40-L46)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setHasUserVerification(true);
    options.setIsUserConsenting(true);
    options.setTransport(Transport['USB']);
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    assert(Object.keys(options).length === 6);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticatorOptions.spec.js#L11-L17)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticatorOptions.spec.js

```js
const {VirtualAuthenticatorOptions, Transport, Protocol} = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')


describe('Virtual authenticator options', function () {
  let options;

  it('Virtual options', async function () {
    options = new VirtualAuthenticatorOptions();
    options.setIsUserVerified(true);
    options.setHasUserVerification(true);
    options.setIsUserConsenting(true);
    options.setTransport(Transport['USB']);
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    assert(Object.keys(options).length === 6);
  });

  it('User verified', async function () {
    options.setIsUserVerified(true);

    assert(options.toDict()['isUserVerified']);
  });
});
```

```java
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L68-L73)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L63-71)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L53-L58)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L51-L55)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L86)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#80-86)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L68-L74)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L62-L63)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L100-L103)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#103-107)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L89-L97)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L80-L94)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L143-L145)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L145-148)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L140-L147)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L136-L140)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L137-L146)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L139-150)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.add_credential(credential)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L150)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L131-L142)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L157-L171)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L162-178)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    credential_list = driver.get_credentials()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L183)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L154-L170)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

[Add Example](/documentation/about/contributing/#creating-examples)

## Remove Credential

Removes a credential from the authenticator based on the passed credential id.

```cs
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L189-198)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

*
*
*
*
*
*

```java
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L181-L190)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.remove_credential(credential.id)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L209)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```java
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L196-L205)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L207-216)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    driver.remove_all_credentials()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L239)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L181-L190)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

```java
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java#L211-L212)

##### /examples/java/src/test/java/dev/selenium/interactions/VirtualAuthenticatorTest.java

```java
package dev.selenium.interactions;

import dev.selenium.BaseChromeTest;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Base64;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Disabled;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.InvalidArgumentException;
import org.openqa.selenium.virtualauthenticator.Credential;
import org.openqa.selenium.virtualauthenticator.HasVirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticator;
import org.openqa.selenium.virtualauthenticator.VirtualAuthenticatorOptions;

public class VirtualAuthenticatorTest extends BaseChromeTest {

  /**
   * A pkcs#8 encoded encrypted RSA private key as a base64url string.
   */
  private final static String
    base64EncodedRsaPK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
    + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
    + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
    + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
    + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
    + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
    + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
    + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
    + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
    + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
    + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
    + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
    + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
    + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
    + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
    + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
    + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
    + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

  private final static PKCS8EncodedKeySpec rsaPrivateKey =
    new PKCS8EncodedKeySpec(Base64.getMimeDecoder().decode(base64EncodedRsaPK));

  // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
  String base64EncodedEC256PK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
    + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
    + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  PKCS8EncodedKeySpec ec256PrivateKey =
    new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

  @Test
  public void testVirtualOptions() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true)
      .setHasUserVerification(true)
      .setIsUserConsenting(true)
      .setTransport(VirtualAuthenticatorOptions.Transport.USB)
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    Assertions.assertEquals(6, options.toMap().size());
  }

  @Test
  public void testCreateAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    List<Credential> credentialList = authenticator.getCredentials();

    Assertions.assertEquals(0, credentialList.size());
  }

  @Test
  public void testRemoveAuthenticator() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions();
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    ((HasVirtualAuthenticator) driver).removeVirtualAuthenticator(authenticator);

    Assertions.assertThrows(InvalidArgumentException.class, authenticator::getCredentials);
  }

  @Test
  public void testCreateAndAddResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testAddResidentCredentialNotSupportedWhenAuthenticatorUsesU2FProtocol() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(true);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    PKCS8EncodedKeySpec privateKey =
      new PKCS8EncodedKeySpec(Base64.getUrlDecoder().decode(base64EncodedEC256PK));

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential credential = Credential.createResidentCredential(
      credentialId, "localhost", privateKey, userHandle, /*signCount=*/0);

    Assertions.assertThrows(InvalidArgumentException.class,
                            () -> authenticator.addCredential(credential));
  }


  @Test
  public void testCreateAndAddNonResidentialKey() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
      .setHasResidentKey(false);

    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    Credential nonResidentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", ec256PrivateKey, /*signCount=*/0);
    authenticator.addCredential(nonResidentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
  }

  @Test
  public void testGetCredential() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setProtocol(VirtualAuthenticatorOptions.Protocol.CTAP2)
      .setHasResidentKey(true)
      .setHasUserVerification(true)
      .setIsUserVerified(true);
    VirtualAuthenticator authenticator = ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(options);

    byte[] credentialId = {1, 2, 3, 4};
    byte[] userHandle = {1};
    Credential residentCredential = Credential.createResidentCredential(
      credentialId, "localhost", rsaPrivateKey, userHandle, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    List<Credential> credentialList = authenticator.getCredentials();
    Assertions.assertEquals(1, credentialList.size());

    Credential credential = credentialList.get(0);
    Assertions.assertArrayEquals(credentialId, credential.getId());
    Assertions.assertArrayEquals(rsaPrivateKey.getEncoded(), credential.getPrivateKey().getEncoded());
  }

  @Test
  public void testRemoveCredential() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential credential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, 0);

    authenticator.addCredential(credential);

    authenticator.removeCredential(credentialId);
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testRemoveAllCredentials() {
    VirtualAuthenticator authenticator =
      ((HasVirtualAuthenticator) driver).addVirtualAuthenticator(new VirtualAuthenticatorOptions());

    byte[] credentialId = {1, 2, 3, 4};
    Credential residentCredential = Credential.createNonResidentCredential(
      credentialId, "localhost", rsaPrivateKey, /*signCount=*/0);

    authenticator.addCredential(residentCredential);

    authenticator.removeAllCredentials();
    Assertions.assertEquals(0, authenticator.getCredentials().size());
  }

  @Test
  public void testSetUserVerified() {
    VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
      .setIsUserVerified(true);

    Assertions.assertTrue((boolean) options.toMap().get("isUserVerified"));
  }
}
```

```cs
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs#L224-225)

##### /examples/dotnet/SeleniumDocs/Interactions/VirtualAuthenticatorTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Microsoft.IdentityModel.Tokens;
using OpenQA.Selenium;
using OpenQA.Selenium.VirtualAuth;
using static OpenQA.Selenium.VirtualAuth.VirtualAuthenticatorOptions;
using System.Collections.Generic;
using System;

namespace SeleniumDocs.VirtualAuthentication
{
    [TestClass]
    public class VirtualAuthenticatorTest : BaseChromeTest
    {
        //A pkcs#8 encoded encrypted RSA private key as a base64 string.
        private static string base64EncodedRSAPK =
                "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr"
              + "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuB"
              + "GVoPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi"
              + "9AyQFR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1P"
              + "vSqXlqGjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsui"
              + "zAgyPuQ0+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/"
              + "XYY22ecYxM8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtib"
              + "RXz5FcNld9MgD/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swyko"
              + "QKBgQD8hCsp6FIQ5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMC"
              + "S6S64/qzZEqijLCqepwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnK"
              + "ws1t5GapfE1rmC/h4olL2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63"
              + "ojKjegxHIyYDKRZNVUR/dxAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM /r8PSflNHQKBgDnWgBh6OQncChPUl"
              + "OLv9FMZPR1ZOfqLCYrjYEqiuzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8V"
              + "ASOmqM1ml667axeZDIR867ZG8K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6B"
              + "hZC7z8mx+pnJODU3cYukxv3WTctlUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJw"
              + "WkBwYADmkfTRmHDvqzQSSvoC2S7aa9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KI"
              + "NpLwcR8fqaYOdAHWWz636osVEqosRrHzJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fB"
              + "nzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4HBYGpI8g==";

        private static byte[] bytes = System.Convert.FromBase64String(base64EncodedRSAPK);
        private string base64EncodedPK = Base64UrlEncoder.Encode(bytes);

        // A pkcs#8 encoded unencrypted EC256 private key as a base64url string.
        private string base64EncodedEC256PK =
              "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q"
              + "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU"
              + "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";


        [TestMethod]
        public void VirtualOptionsShouldAllowSettingOptions()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true)
                .SetHasUserVerification(true)
                .SetIsUserConsenting(true)
                .SetTransport(VirtualAuthenticatorOptions.Transport.USB)
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            Assert.AreEqual(6, options.ToDictionary().Count);
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAuthenticator()
        {
            // Create virtual authenticator options
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            // Register a virtual authenticator
            ((WebDriver)driver).AddVirtualAuthenticator(options);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();

            Assert.AreEqual(0, credentialList.Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAuthenticator()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            String virtualAuthenticatorId = ((WebDriver)driver).AddVirtualAuthenticator(options);

            ((WebDriver)driver).RemoveVirtualAuthenticator(virtualAuthenticatorId);

            // Since the authenticator was removed, any operation using it will throw an error
            Assert.ThrowsException<InvalidOperationException>(() => ((WebDriver)driver).GetCredentials());
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddResidentialKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, credential.Id);
        }

        [TestMethod]
        public void ShouldNotAddResidentCredentialWhenAuthenticatorUsesU2FProtocol()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential credential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, userHandle, 0);

            Assert.ThrowsException<WebDriverArgumentException>(() => ((WebDriver)driver).AddCredential(credential));
        }

        [TestMethod]
        public void ShouldBeAbleToCreateAndAddNonResidentKey()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(VirtualAuthenticatorOptions.Protocol.U2F)
                .SetHasResidentKey(false);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, nonResidentCredential.Id);
        }

        [TestMethod]
        public void ShouldBeAbleToGetCredential()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetProtocol(Protocol.CTAP2)
                .SetHasResidentKey(true)
                .SetHasUserVerification(true)
                .SetIsUserVerified(true);

            ((WebDriver)driver).AddVirtualAuthenticator(options);

            byte[] credentialId = { 1, 2, 3, 4 };
            byte[] userHandle = { 1 };

            Credential residentCredential = Credential.CreateResidentCredential(
              credentialId, "localhost", base64EncodedPK, userHandle, 0);

            ((WebDriver)driver).AddCredential(residentCredential);

            List<Credential> credentialList = ((WebDriver)driver).GetCredentials();
            Assert.AreEqual(1, credentialList.Count);

            Credential credential = credentialList[0];
            CollectionAssert.AreEqual(credentialId, residentCredential.Id);
            Assert.AreEqual(base64EncodedPK, credential.PrivateKey);
        }

        [TestMethod]
        public void ShouldBeAbleToRemoveCredential()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveCredential(credentialId);

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }


        [TestMethod]
        public void ShouldBeAbleToRemoveAllCredentias()
        {
            ((WebDriver)driver).AddVirtualAuthenticator(new VirtualAuthenticatorOptions());

            byte[] credentialId = { 1, 2, 3, 4 };

            Credential nonResidentCredential = Credential.CreateNonResidentCredential(
              credentialId, "localhost", base64EncodedEC256PK, 0);

            ((WebDriver)driver).AddCredential(nonResidentCredential);

            ((WebDriver)driver).RemoveAllCredentials();

            Assert.AreEqual(0, ((WebDriver)driver).GetCredentials().Count);
        }

        [TestMethod]
        public void ShouldBeSetVerifiedOption()
        {
            VirtualAuthenticatorOptions options = new VirtualAuthenticatorOptions()
                .SetIsUserVerified(true);

            Assert.IsTrue((bool)options.ToDictionary()["isUserVerified"]);
        }
    }
}
```

[Add Example](/documentation/about/contributing/#creating-examples)

```py
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_virtual_authenticator.py#L245-L247)

##### /examples/python/tests/interactions/test\_virtual\_authenticator.py

```py
import pytest
from base64 import urlsafe_b64decode, urlsafe_b64encode

from selenium.common.exceptions import InvalidArgumentException
from selenium.webdriver.chrome.webdriver import WebDriver
from selenium.webdriver.common.virtual_authenticator import (
    Credential,
    VirtualAuthenticatorOptions,
)


BASE64__ENCODED_PK = '''
MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr
MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV
oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ
FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq
GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0
+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM
8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD
/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ
5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe
pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol
L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d
xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi
uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8
K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct
lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa
9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH
zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H
BYGpI8g==
'''


@pytest.fixture(scope="module", autouse=True)
def driver():
    yield WebDriver()


def test_virtual_authenticator_options():
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True
    options.has_user_verification = True
    options.is_user_consenting = True
    options.transport = VirtualAuthenticatorOptions.Transport.USB
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    assert len(options.to_dict()) == 6


def test_add_authenticator(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Get list of credentials
    credential_list = driver.get_credentials()

    assert len(credential_list) == 0


def test_remove_authenticator(driver):
    # Create default virtual authenticator option
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # Remove virtual authenticator
    driver.remove_virtual_authenticator()
    assert driver.virtual_authenticator_id is None


def test_create_and_add_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verification = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1


def test_add_resident_credential_not_supported_when_authenticator_uses_u2f_protocol(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a  resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)

    # Expect InvalidArgumentException 
    with pytest.raises(InvalidArgumentException):
        driver.add_credential(credential)


def test_create_and_add_non_resident_key(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.U2F
    options.has_resident_key = False

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)
    
    # get list of all the registered credentials 
    credential_list = driver.get_credentials()
    assert len(credential_list) == 1



def test_get_credential(driver):
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.protocol = VirtualAuthenticatorOptions.Protocol.CTAP2
    options.has_resident_key = True
    options.has_user_verfied = True
    options.is_user_verified = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # get list of all the registered credentials 
    credential_list = driver.get_credentials()

    assert len(credential_list) == 1
    assert credential_list[0].id == urlsafe_b64encode(credential_id).decode()


def test_remove_credential(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Non Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a non resident credential using above parameters
    credential = Credential.create_non_resident_credential(credential_id, rp_id, privatekey, sign_count)

    # add the credential created to virtual authenticator
    driver.add_credential(credential)

    # remove the credential created from virtual authenticator
    driver.remove_credential(credential.id)

    # credential can also be removed using Byte Array
    # driver.remove_credential(credential_id) 

    assert len(driver.get_credentials()) == 0


def test_remove_all_credentials(driver):
    # Create default virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.has_resident_key = True

    # Register a virtual authenticator
    driver.add_virtual_authenticator(options)

    # parameters for Resident Credential
    credential_id = bytearray({1, 2, 3, 4})
    rp_id = "localhost"
    user_handle = bytearray({1})
    privatekey = urlsafe_b64decode(BASE64__ENCODED_PK)
    sign_count = 0

    # create a resident credential using above parameters
    resident_credential = Credential.create_resident_credential(credential_id, rp_id, user_handle, privatekey, sign_count)
    
    # add the credential created to virtual authenticator
    driver.add_credential(resident_credential)

    # remove all credentials in virtual authenticator
    driver.remove_all_credentials()

    assert len(driver.get_credentials()) == 0


def test_set_user_verified():
    # Create virtual authenticator options
    options = VirtualAuthenticatorOptions()
    options.is_user_verified = True

    assert options.to_dict().get("isUserVerified") is True
```

```js
    options.setIsUserVerified(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/virtual_authenticator/virtualAuthenticator.spec.js#L197-L197)

##### /examples/javascript/test/virtual\_authenticator/virtualAuthenticator.spec.js

```js

const { Builder} = require("selenium-webdriver");
const { Credential, VirtualAuthenticatorOptions, Transport, Protocol } = require("selenium-webdriver/lib/virtual_authenticator");
const assert = require('assert')
const { InvalidArgumentError } = require("selenium-webdriver/lib/error");


describe('Virtual authenticator', function() {
  const BASE64_ENCODED_PK =
    "MIIEvAIBADANBgkqhkiG9w0BAQEFAASCBKYwggSiAgEAAoIBAQDbBOu5Lhs4vpowbCnmCyLUpIE7JM9sm9QXzye2G+jr+Kr" +
    "MsinWohEce47BFPJlTaDzHSvOW2eeunBO89ZcvvVc8RLz4qyQ8rO98xS1jtgqi1NcBPETDrtzthODu/gd0sjB2Tk3TLuBGV" +
    "oPXt54a+Oo4JbBJ6h3s0+5eAfGplCbSNq6hN3Jh9YOTw5ZA6GCEy5l8zBaOgjXytd2v2OdSVoEDNiNQRkjJd2rmS2oi9AyQ" +
    "FR3B7BrPSiDlCcITZFOWgLF5C31Wp/PSHwQhlnh7/6YhnE2y9tzsUvzx0wJXrBADW13+oMxrneDK3WGbxTNYgIi1PvSqXlq" +
    "GjHtCK+R2QkXAgMBAAECggEAVc6bu7VAnP6v0gDOeX4razv4FX/adCao9ZsHZ+WPX8PQxtmWYqykH5CY4TSfsuizAgyPuQ0" +
    "+j4Vjssr9VODLqFoanspT6YXsvaKanncUYbasNgUJnfnLnw3an2XpU2XdmXTNYckCPRX9nsAAURWT3/n9ljc/XYY22ecYxM" +
    "8sDWnHu2uKZ1B7M3X60bQYL5T/lVXkKdD6xgSNLeP4AkRx0H4egaop68hoW8FIwmDPVWYVAvo8etzWCtibRXz5FcNld9MgD" +
    "/Ai7ycKy4Q1KhX5GBFI79MVVaHkSQfxPHpr7/XcmpQOEAr+BMPon4s4vnKqAGdGB3j/E3d/+4F2swykoQKBgQD8hCsp6FIQ" +
    "5umJlk9/j/nGsMl85LgLaNVYpWlPRKPc54YNumtvj5vx1BG+zMbT7qIE3nmUPTCHP7qb5ERZG4CdMCS6S64/qzZEqijLCqe" +
    "pwj6j4fV5SyPWEcpxf6ehNdmcfgzVB3Wolfwh1ydhx/96L1jHJcTKchdJJzlfTvq8wwKBgQDeCnKws1t5GapfE1rmC/h4ol" +
    "L2qZTth9oQmbrXYohVnoqNFslDa43ePZwL9Jmd9kYb0axOTNMmyrP0NTj41uCfgDS0cJnNTc63ojKjegxHIyYDKRZNVUR/d" +
    "xAYB/vPfBYZUS7M89pO6LLsHhzS3qpu3/hppo/Uc/AM/r8PSflNHQKBgDnWgBh6OQncChPUlOLv9FMZPR1ZOfqLCYrjYEqi" +
    "uzGm6iKM13zXFO4AGAxu1P/IAd5BovFcTpg79Z8tWqZaUUwvscnl+cRlj+mMXAmdqCeO8VASOmqM1ml667axeZDIR867ZG8" +
    "K5V029Wg+4qtX5uFypNAAi6GfHkxIKrD04yOHAoGACdh4wXESi0oiDdkz3KOHPwIjn6BhZC7z8mx+pnJODU3cYukxv3WTct" +
    "lUhAsyjJiQ/0bK1yX87ulqFVgO0Knmh+wNajrb9wiONAJTMICG7tiWJOm7fW5cfTJwWkBwYADmkfTRmHDvqzQSSvoC2S7aa" +
    "9QulbC3C/qgGFNrcWgcT9kCgYAZTa1P9bFCDU7hJc2mHwJwAW7/FQKEJg8SL33KINpLwcR8fqaYOdAHWWz636osVEqosRrH" +
    "zJOGpf9x2RSWzQJ+dq8+6fACgfFZOVpN644+sAHfNPAI/gnNKU5OfUv+eav8fBnzlf1A3y3GIkyMyzFN3DE7e0n/lyqxE4H" +
    "BYGpI8g==";

  const base64EncodedPK =
    "MIGHAgEAMBMGByqGSM49AgEGCCqGSM49AwEHBG0wawIBAQQg8_zMDQDYAxlU-Q" +
    "hk1Dwkf0v18GZca1DMF3SaJ9HPdmShRANCAASNYX5lyVCOZLzFZzrIKmeZ2jwU" +
    "RmgsJYxGP__fWN_S-j5sN4tT15XEpN_7QZnt14YvI6uvAgO0uJEboFaZlOEB";

  let options;
  let driver;

  before(async function() {
    options = new VirtualAuthenticatorOptions();
    driver = await new Builder().forBrowser('chrome').build();
  });

  after(async() => await driver.quit());

  function arraysEqual(array1, array2) {
    return (array1.length === array2.length &&
      array1.every((item) => array2.includes(item)) &&
      array2.every((item) => array1.includes(item)));
  }

  it('Register a virtual authenticator', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    // Register a virtual authenticator
    await driver.addVirtualAuthenticator(options);
    let credentialList = await driver.getCredentials();

    assert.equal(0, credentialList.length);
  });

  it('Remove authenticator', async function() {
    await driver.addVirtualAuthenticator(options);
    await driver.removeVirtualAuthenticator();

    // Since the authenticator was removed, any operation using it will throw an error
    try {
      await driver.getCredentials()
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Createa and add residential key', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);
    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Add resident credential not supported when authenticator uses U2F protocol', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(true);

    await driver.addVirtualAuthenticator(options);

    let credential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    try {
      await driver.addCredential(credential)
    }
    catch (e) {
      if (e instanceof InvalidArgumentError) {
        assert(true)
      }
      else {
        assert(false)
      }
    }
  });

  it('Create and add non residential key', async function() {
    options.setProtocol(Protocol['U2F']);
    options.setHasResidentKey(false);

    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(base64EncodedPK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
  });

  it('Get credential', async function() {
    options.setProtocol(Protocol['CTAP2']);
    options.setHasResidentKey(true);
    options.setHasUserVerification(true);
    options.setIsUserVerified(true);

    await driver.addVirtualAuthenticator(options);

    let residentCredential = new Credential().createResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      new Uint8Array([1]),
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(residentCredential);

    let credentialList = await driver.getCredentials();
    assert.equal(1, credentialList.length);

    let credential_id = credentialList[0].id();
    let test_id = new Uint8Array([1, 2, 3, 4]);

    assert(arraysEqual(credential_id, test_id));
    assert.equal(BASE64_ENCODED_PK, Buffer.from(credentialList[0].privateKey(), 'binary').toString('base64'));
  });

  it('Remove all credentials', async function() {
    await driver.addVirtualAuthenticator(options);

    let nonResidentCredential = new Credential().createNonResidentCredential(
      new Uint8Array([1, 2, 3, 4]),
      'localhost',
      Buffer.from(BASE64_ENCODED_PK, 'base64').toString('binary'),
      0);

    await driver.addCredential(nonResidentCredential);
    await driver.removeAllCredentials();

    let credentialList = await driver.getCredentials();
    assert.equal(0, credentialList.length);
  });

  it('Set is user verified', async function() {
    options.setIsUserVerified(true);
    assert.equal(options.getIsUserVerified(), true);
  });
});
```

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/drivers/service/
----

# 驱动服务类

```java
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L15-L16)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L5-L6)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L14-L15)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

```rb
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L14-L15)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

```java
    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L25-L26)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(executable_path=chromedriver_bin)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L15)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```cs
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L23)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
    service.executable_path = driver_path
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L26)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

```java
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L33)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(port=1234)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L23)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            service.Port = 1234;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L32)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
    service.port = 1234
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L33)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

----
url: https://www.selenium.dev/zh-cn/documentation/grid/configuration/toml_options/
----

# Toml配置选项

```toml
[section1]
option1="value"

[section2]
option2=["value1","value2"]
option3=true
```

下面是一些使用Toml文件配置的 Grid组件示例, 该组件可以 从下面的方式开始:

```
java -jar selenium-server-<version>.jar <component> --config /path/to/file/<file-name>.toml
```

### 单机模式

单机服务器, 在端口4449上运行, 新会话请求超时500秒.

```toml
[server]
port = 4449

[sessionqueue]
session-request-timeout = 500
```

### 特定浏览器和最大会话数限制

默认情况下仅启用Firefox 和Chrome的单机服务器或节点.

```toml
[node]
drivers = ["chrome", "firefox"]
max-sessions = 3
```

### 配置和定制驱动程序

具有定制驱动程序的单机或节点服务器, 允许使用Firefox试用或者每日构建的功能, 并且有不同的浏览器版本.

```toml
[node]
detect-drivers = false
[[node.driver-configuration]]
max-sessions = 100
display-name = "Firefox Nightly"
stereotype = "{\"browserName\": \"firefox\", \"browserVersion\": \"93\", \"platformName\": \"MAC\", \"moz:firefoxOptions\": {\"binary\": \"/Applications/Firefox Nightly.app/Contents/MacOS/firefox-bin\"}}"
[[node.driver-configuration]]
display-name = "Chrome Beta"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"94\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Beta.app/Contents/MacOS/Google Chrome Beta\"}}"
[[node.driver-configuration]]
display-name = "Chrome Dev"
stereotype = "{\"browserName\": \"chrome\", \"browserVersion\": \"95\", \"platformName\": \"MAC\", \"goog:chromeOptions\": {\"binary\": \"/Applications/Google Chrome Dev.app/Contents/MacOS/Google Chrome Dev\"}}"
webdriver-executable = '/path/to/chromedriver/95/chromedriver'
```

### 带Docker的单机或节点

单机或节点服务器能够在Docker容器中运行每个新会话. 禁用驱动程序检测, 则最多有2个并发会话. 原型配置需要映射一个Docker映像, Docker的守护进程需要通过http/tcp公开. 此外, 可以通过 `devices` 属性定义在主机上可访问的哪些设备文件将在容器中可用. 有关 docker 设备映射如何工作的更多信息, 请参阅 [docker](https://docs.docker.com/engine/reference/commandline/run/#add-host-device-to-container---device) 文档.

```toml
[node]
detect-drivers = false
max-sessions = 2

[docker]
configs = [
    "selenium/standalone-chrome:93.0", "{\"browserName\": \"chrome\", \"browserVersion\": \"91\"}", 
    "selenium/standalone-firefox:92.0", "{\"browserName\": \"firefox\", \"browserVersion\": \"92\"}"
]
#Optionally define all device files that should be mapped to docker containers
#devices = [
#    "/dev/kvm:/dev/kvm"
#]
url = "http://localhost:2375"
video-image = "selenium/video:latest"
```

### 将命令中继到支持WebDriver的服务端点

连接到支持WebDriver外部服务 的Selenium Grid非常有用. 这种服务的一个例子可以是 云提供商或Appium服务器. 这样, Grid可以实现对本地不存在的平台和版本的更多覆盖.

下面是一个将Appium服务器连接到Grid的示例.

```toml
[node]
detect-drivers = false

[relay]
# Default Appium/Cloud server endpoint
url = "http://localhost:4723/wd/hub"
status-endpoint = "/status"
# Optional, enforce a specific protocol version in HttpClient when communicating with the endpoint service status (e.g. HTTP/1.1, HTTP/2)
protocol-version = "HTTP/1.1"
# Stereotypes supported by the service. The initial number is "max-sessions", and will allocate 
# that many test slots to that particular configuration
configs = [
  "5", "{\"browserName\": \"chrome\", \"platformName\": \"android\", \"appium:platformVersion\": \"11\"}"
]
```

### 启用基本身份验证

通过配置包含用户名和密码的 路由器/集线器/单机的方式, 可以使用这样的基本身份验证保护Grid. 加载Grid UI或者开始一个新的会话时 需要此用户/密码组合.

```toml
[router]
username = "admin"
password = "myStrongPassword"
```

下面是一个Java示例, 演示如何使用配置的用户和密码启动会话.

```java
ClientConfig clientConfig = ClientConfig.defaultConfig()
  .baseUrl(new URL("http://localhost:4444"))
  .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"));
HttpCommandExecutor executor = new HttpCommandExecutor(clientConfig);
RemoteWebDriver driver = new RemoteWebDriver(executor, new ChromeOptions());
```

在其他语言中, 您可以使用 URL http\://admin:myStrongPassword\@localhost:4444

### 为匹配特定节点设置自定义功能

**重要提示:** 自定义功能需要在所有节点的配置中进行设置. 并且在每次会话请求中都必须包含这些功能.

```toml
[node]
detect-drivers = false

[[node.driver-configuration]]
display-name = "firefox"
stereotype = '{"browserName": "firefox", "platformName": "macOS", "browserVersion":"96", "networkname:applicationName":"node_1", "nodename:applicationName":"app_1" }'
max-sessions = 5
```

这里有一个 Java 示例, 展示了如何匹配那个节点

```java
FirefoxOptions options = new FirefoxOptions();
options.setCapability("networkname:applicationName", "node_1");
options.setCapability("nodename:applicationName", "app_1");
options.setBrowserVersion("96");
options.setPlatformName("macOS");
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444"), options);
driver.get("https://selenium.dev");
driver.quit();
```

### 启用节点的托管下载功能.

节点可以被设置为自动管理下载. 这将导致节点会把特定会话中下载的所有文件保存到一个临时目录中, 之后可以从节点中获取这些文件.\
要启用此功能, 请使用以下配置:

```toml
[node]
enable-managed-downloads = true
```

有关完整示例, 请参阅[CLI章节](https://www.selenium.dev/zh-cn/documentation/grid/configuration/cli_options/#enabling-managed-downloads-by-the-node) .

----
url: https://www.selenium.dev/_print/documentation/test_practices/encouraged/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/test_practices/encouraged/).

# Encouraged behaviors

Some guidelines and recommendations on testing from the Selenium project.

* 1: [Page object models](#pg-fa5d8fda885160f5bac36ddd0a759f2c)
* 2: [Domain specific language](#pg-2fa3bc7763585631cae7ebbfd2ab6f4d)
* 3: [Generating application state](#pg-806a27b179478d057a2a72eaecbb5a7f)
* 4: [Mock external services](#pg-8e67210230ed00981653880f12c0854b)
* 5: [Improved reporting](#pg-2fc5231d4be0c254ce4f3da24dd7ecac)
* 6: [Avoid sharing state](#pg-95634a04429bc3ee0d73ad583f402ecf)
* 7: [Tips on working with locators](#pg-84640ae953713c14fe36c508f185cc39)
* 8: [Test independency](#pg-86fac44b429f8cec078f2c489c86beb0)
* 9: [Consider using a fluent API](#pg-9a56c997c2608d98dbbc2d6cb49a33e0)
* 10: [Fresh browser per test](#pg-a725d846f871bf74490745badf015de3)

A note on “Best Practices”: We’ve intentionally avoided the phrase “Best Practices” in this documentation. No one approach works for all situations. We prefer the idea of “Guidelines and Recommendations”. We encourage you to read through these and thoughtfully decide what approaches will work for you in your particular environment.

Functional testing is difficult to get right for many reasons. As if application state, complexity, and dependencies do not make testing difficult enough, dealing with browsers (especially with cross-browser incompatibilities) makes writing good tests a challenge.

Selenium provides tools to make functional user interaction easier, but does not help you write well-architected test suites. In this chapter we offer advice, guidelines, and recommendations on how to approach functional web page automation.

This chapter records software design patterns popular amongst many of the users of Selenium that have proven successful over the years.

# 1 - Page object models

```java
/***
 * Tests login feature
 */
public class Login {

  public void testLogin() {
    // fill login data on sign-in page
    driver.findElement(By.name("user_name")).sendKeys("userName");
    driver.findElement(By.name("password")).sendKeys("my supersecret password");
    driver.findElement(By.name("sign-in")).click();

    // verify h1 tag is "Hello userName" after login
    driver.findElement(By.tagName("h1")).isDisplayed();
    assertThat(driver.findElement(By.tagName("h1")).getText(), is("Hello userName"));
  }
}
```

There are two problems with this approach.

* There is no separation between the test method and the AUT’s locators (IDs in this example); both are intertwined in a single method. If the AUT’s UI changes its identifiers, layout, or how a login is input and processed, the test itself must change.
* The ID-locators would be spread in multiple tests, in all tests that had to use this login page.

Applying the page object model, this example could be rewritten like this in the following example of a page object for a Sign-in page.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Sign-in page.
 */
public class SignInPage {
  protected WebDriver driver;

  // <input name="user_name" type="text" value="">
  private By usernameBy = By.name("user_name");
  // <input name="password" type="password" value="">
  private By passwordBy = By.name("password");
  // <input name="sign_in" type="submit" value="SignIn">
  private By signinBy = By.name("sign_in");

  public SignInPage(WebDriver driver){
    this.driver = driver;
     if (!driver.getTitle().equals("Sign In Page")) {
      throw new IllegalStateException("This is not Sign In Page," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Login as valid user
    *
    * @param userName
    * @param password
    * @return HomePage object
    */
  public HomePage loginValidUser(String userName, String password) {
    driver.findElement(usernameBy).sendKeys(userName);
    driver.findElement(passwordBy).sendKeys(password);
    driver.findElement(signinBy).click();
    return new HomePage(driver);
  }
}
```

and page object for a Home page could look like this.

```java
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;

/**
 * Page Object encapsulates the Home Page
 */
public class HomePage {
  protected WebDriver driver;

  // <h1>Hello userName</h1>
  private By messageBy = By.tagName("h1");

  public HomePage(WebDriver driver){
    this.driver = driver;
    if (!driver.getTitle().equals("Home Page of logged in user")) {
      throw new IllegalStateException("This is not Home Page of logged in user," +
            " current page is: " + driver.getCurrentUrl());
    }
  }

  /**
    * Get message (h1 tag)
    *
    * @return String message text
    */
  public String getMessageText() {
    return driver.findElement(messageBy).getText();
  }

  public HomePage manageProfile() {
    // Page encapsulation to manage profile functionality
    return new HomePage(driver);
  }
  /* More methods offering the services represented by Home Page
  of Logged User. These methods in turn might return more Page Objects
  for example click on Compose mail button could return ComposeMail class object */
}
```

So now, the login test would use these two page objects as follows.

```java
/***
 * Tests login feature
 */
public class TestLogin {

  @Test
  public void testLogin() {
    SignInPage signInPage = new SignInPage(driver);
    HomePage homePage = signInPage.loginValidUser("userName", "password");
    assertThat(homePage.getMessageText(), is("Hello userName"));
  }

}
```

```html
<!-- Products Page -->
<div class="header_container">
    <span class="title">Products</span>
</div>

<div class="inventory_list">
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
    <div class="inventory_item">
    </div>
</div>
```

Each product is a component of the Products page.

```html
<!-- Inventory Item -->
<div class="inventory_item">
    <div class="inventory_item_name">Backpack</div>
    <div class="pricebar">
        <div class="inventory_item_price">$29.99</div>
        <button id="add-to-cart-backpack">Add to cart</button>
    </div>
</div>
```

The Products page HAS-A list of products. This object relationship is called Composition. In simpler terms, something is *composed of* another thing.

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

// Page Object
public class ProductsPage extends BasePage {
    public ProductsPage(WebDriver driver) {
        super(driver);
        // No assertions, throws an exception if the element is not loaded
        new WebDriverWait(driver, Duration.ofSeconds(3))
            .until(d -> d.findElement(By.className​("header_container")));
    }

    // Returning a list of products is a service of the page
    public List<Product> getProducts() {
        return driver.findElements(By.className​("inventory_item"))
            .stream()
            .map(e -> new Product(e)) // Map WebElement to a product component
            .toList();
    }

    // Return a specific product using a boolean-valued function (predicate)
    // This is the behavioral Strategy Pattern from GoF
    public Product getProduct(Predicate<Product> condition) {
        return getProducts()
            .stream()
            .filter(condition) // Filter by product name or price
            .findFirst()
            .orElseThrow(() -> new RuntimeException("Product not found")); // Error thrown during actual test run
    }
}
```

The Product component object is used inside the Products page object.

```java
public abstract class BaseComponent {
    protected WebElement root;

    public BaseComponent(WebElement root) {
        this.root = root;
    }
}

// Page Component Object
public class Product extends BaseComponent {
    // The root element contains the entire component
    public Product(WebElement root) {
        super(root); // inventory_item
    }

    public String getName() {
        // Locating an element begins at the root of the component
        return root.findElement(By.className("inventory_item_name")).getText();
    }

    public BigDecimal getPrice() {
        return new BigDecimal(
                root.findElement(By.className("inventory_item_price"))
                    .getText()
                    .replace("$", "")
            ).setScale(2, RoundingMode.UNNECESSARY); // Sanitation and formatting
    }

    public void addToCart() {
        root.findElement(By.id("add-to-cart-backpack")).click();
    }
}
```

So now, the products test would use the page object and the page component object as follows.

```java
public class ProductsTest {
    @Test
    public void testProductInventory() {
        var productsPage = new ProductsPage(driver); // page object
        var products = productsPage.getProducts();
        assertEquals(6, products.size()); // expected, actual
    }
    
    @Test
    public void testProductPrices() {
        var productsPage = new ProductsPage(driver);

        // Pass a lambda expression (predicate) to filter the list of products
        // The predicate or "strategy" is the behavior passed as parameter
        var backpack = productsPage.getProduct(p -> p.getName().equals("Backpack")); // page component object
        var bikeLight = productsPage.getProduct(p -> p.getName().equals("Bike Light"));

        assertEquals(new BigDecimal("29.99"), backpack.getPrice());
        assertEquals(new BigDecimal("9.99"), bikeLight.getPrice());
    }
}
```

```java
public class LoginPage {
    public HomePage loginAs(String username, String password) {
        // ... clever magic happens here
    }
    
    public LoginPage loginAsExpectingError(String username, String password) {
        //  ... failed login here, maybe because one or both of the username and password are wrong
    }
    
    public String getErrorMessage() {
        // So we can verify that the correct error is shown
    }
}
```

The code presented above shows an important point: the tests, not the Page Objects, should be responsible for making assertions about the state of a page. For example:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    inbox.assertMessageWithSubjectIsUnread("I like cheese");
    inbox.assertMessageWithSubjectIsNotUnread("I'm not fond of tofu");
}
```

could be re-written as:

```java
public void testMessagesAreReadOrUnread() {
    Inbox inbox = new Inbox(driver);
    assertTrue(inbox.isMessageWithSubjectIsUnread("I like cheese"));
    assertFalse(inbox.isMessageWithSubjectIsUnread("I'm not fond of tofu"));
}
```

```java
public class LoginPage {
    private final WebDriver driver;

    public LoginPage(WebDriver driver) {
        this.driver = driver;

        // Check that we're on the right page.
        if (!"Login".equals(driver.getTitle())) {
            // Alternatively, we could navigate to the login page, perhaps logging out first
            throw new IllegalStateException("This is not the login page");
        }
    }

    // The login page contains several HTML elements that will be represented as WebElements.
    // The locators for these elements should only be defined once.
        By usernameLocator = By.id("username");
        By passwordLocator = By.id("passwd");
        By loginButtonLocator = By.id("login");

    // The login page allows the user to type their username into the username field
    public LoginPage typeUsername(String username) {
        // This is the only place that "knows" how to enter a username
        driver.findElement(usernameLocator).sendKeys(username);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to type their password into the password field
    public LoginPage typePassword(String password) {
        // This is the only place that "knows" how to enter a password
        driver.findElement(passwordLocator).sendKeys(password);

        // Return the current page object as this action doesn't navigate to a page represented by another PageObject
        return this;	
    }

    // The login page allows the user to submit the login form
    public HomePage submitLogin() {
        // This is the only place that submits the login form and expects the destination to be the home page.
        // A seperate method should be created for the instance of clicking login whilst expecting a login failure. 
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the login page ever
        // go somewhere else (for example, a legal disclaimer) then changing the method signature
        // for this method will mean that all tests that rely on this behaviour won't compile.
        return new HomePage(driver);	
    }

    // The login page allows the user to submit the login form knowing that an invalid username and / or password were entered
    public LoginPage submitLoginExpectingFailure() {
        // This is the only place that submits the login form and expects the destination to be the login page due to login failure.
        driver.findElement(loginButtonLocator).submit();

        // Return a new page object representing the destination. Should the user ever be navigated to the home page after submiting a login with credentials 
        // expected to fail login, the script will fail when it attempts to instantiate the LoginPage PageObject.
        return new LoginPage(driver);	
    }

    // Conceptually, the login page offers the user the service of being able to "log into"
    // the application using a user name and password. 
    public HomePage loginAs(String username, String password) {
        // The PageObject methods that enter username, password & submit login have already defined and should not be repeated here.
        typeUsername(username);
        typePassword(password);
        return submitLogin();
    }
}
```

# 2 - Domain specific language

```java
/**
 * Takes a username and password, fills out the fields, and clicks "login".
 * @return An instance of the AccountPage
 */
public AccountPage loginAsUser(String username, String password) {
  WebElement loginField = driver.findElement(By.id("loginField"));
  loginField.clear();
  loginField.sendKeys(username);

  // Fill out the password field. The locator we're using is "By.id", and we should
  // have it defined elsewhere in the class.
  WebElement passwordField = driver.findElement(By.id("password"));
  passwordField.clear();
  passwordField.sendKeys(password);

  // Click the login button, which happens to have the id "submit".
  driver.findElement(By.id("submit")).click();

  // Create and return a new instance of the AccountPage (via the built-in Selenium
  // PageFactory).
  return PageFactory.newInstance(AccountPage.class);
}
```

This method completely abstracts the concepts of input fields, buttons, clicking, and even pages from your test code. Using this approach, all a tester has to do is call this method. This gives you a maintenance advantage: if the login fields ever changed, you would only ever have to change this method - not your tests.

```java
public void loginTest() {
    loginAsUser("cbrown", "cl0wn3");

    // Now that we're logged in, do some other stuff--since we used a DSL to support
    // our testers, it's as easy as choosing from available methods.
    do.something();
    do.somethingElse();
    Assert.assertTrue("Something should have been done!", something.wasDone());

    // Note that we still haven't referred to a button or web control anywhere in this
    // script...
}
```

It bears repeating: one of your primary goals should be writing an API that allows your tests to address **the problem at hand, and NOT the problem of the UI**. The UI is a secondary concern for your users – they do not care about the UI, they just want to get their job done. Your test scripts should read like a laundry list of things the user wants to DO, and the things they want to KNOW. The tests should not concern themselves with HOW the UI requires you to go about it.

\***AUT**: Application under test

# 3 - Generating application state

Selenium should not be used to prepare a test case. All repetitive actions and preparations for a test case, should be done through other methods. For example, most web UIs have authentication (e.g. a login form). Eliminating logging in via web browser before every test will improve both the speed and stability of the test. A method should be created to gain access to the AUT\* (e.g. using an API to login and set a cookie). Also, creating methods to pre-load data for testing should not be done using Selenium. As mentioned previously, existing APIs should be leveraged to create data for the AUT\*.

\***AUT**: Application under test

# 4 - Mock external services

Eliminating the dependencies on external services will greatly improve the speed and stability of your tests.

# 5 - Improved reporting

Selenium is not designed to report on the status of test cases run. Taking advantage of the built-in reporting capabilities of unit test frameworks is a good start. Most unit test frameworks have reports that can generate xUnit or HTML formatted reports. xUnit reports are popular for importing results to a Continuous Integration (CI) server like Jenkins, Travis, Bamboo, etc. Here are some links for more information regarding report outputs for several languages.

[NUnit 3 Console Runner](//github.com/nunit/docs/wiki/Console-Runner)

[NUnit 3 Console Command Line](//github.com/nunit/docs/wiki/Console-Command-Line)

[xUnit getting test results in TeamCity](//xunit.net/docs/getting-test-results-in-teamcity)

[xUnit getting test results in CruiseControl.NET](//xunit.net/docs/getting-test-results-in-ccnet)

[xUnit getting test results in Azure DevOps](//xunit.net/docs/getting-test-results-in-azure-devops)

# 6 - Avoid sharing state

Although mentioned in several places, it is worth mentioning again. We must ensure that the tests are isolated from one another.

* Do not share test data. Imagine several tests that each query the database for valid orders before picking one to perform an action on. Should two tests pick up the same order you are likely to get unexpected behavior.

* Clean up stale data in the application that might be picked up by another test e.g. invalid order records.

* Create a new WebDriver instance per test. This helps ensure test isolation and makes parallelization simpler.

  * If you choose [pytest](https://pytest.org/) as your test runner, this can be easily done by yielding your driver in a global fixture. This way each test gets its own driver instance, and you can ensure that drivers always quit after a test is finished (pass or fail).

# 7 - Tips on working with locators

# 8 - Test independency

Write each test as its own unit. Write the tests in a way that will not be reliant on other tests to complete:

Let us say there is a content management system with which you can create some custom content which then appears on your website as a module after publishing, and it may take some time to sync between the CMS and the application.

A wrong way of testing your module is that the content is created and published in one test, and then checking the module in another test. This is not feasible as the content may not be available immediately for the other test after publishing.

Instead, you can create a stub content which can be turned on and off within the affected test, and use that for validating the module. However, for content creation, you can still have a separate test.

# 9 - Consider using a fluent API

Martin Fowler coined the term [“Fluent API”](//www.martinfowler.com/bliki/FluentInterface.html). Selenium already implements something like this in their `FluentWait` class, which is meant as an alternative to the standard `Wait` class. You could enable the Fluent API design pattern in your page object and then query the Google search page with a code snippet like this one:

```java
driver.get( "http://www.google.com/webhp?hl=en&amp;tab=ww" );
GoogleSearchPage gsp = new GoogleSearchPage(driver);
gsp.setSearchString().clickSearchButton();
```

The Google page object class with this fluent behavior might look like this:

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

public class GoogleSearchPage extends BasePage {
    public GoogleSearchPage(WebDriver driver) {
        super(driver);
        // Generally do not assert within pages or components.
        // Effectively throws an exception if the lambda condition is not met.
        new WebDriverWait(driver, Duration.ofSeconds(3)).until(d -> d.findElement(By.id("logo")));
    }

    public GoogleSearchPage setSearchString(String sstr) {
        driver.findElement(By.id("gbqfq")).sendKeys(sstr);
        return this;
    }

    public void clickSearchButton() {
        driver.findElement(By.id("gbqfb")).click();
    }
}
```

# 10 - Fresh browser per test

Start each test from a clean, known state. Ideally, spin up a new virtual machine for each test. If spinning up a new virtual machine is not practical, at least start a new WebDriver for each test. Most browser drivers like GeckoDriver and ChromeDriver will start with a clean known state with a new user profile, by default.

```java
WebDriver driver = new FirefoxDriver();
```

----
url: https://www.selenium.dev/documentation/ie_driver_server/
----

# IE Driver Server

The Internet Explorer Driver is a standalone server that implements the WebDriver specification.

| Switch                         | Meaning                                                                                                                                                        |
| ------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| –port=`<portNumber>`           | Specifies the port on which the HTTP server of the IE driver will listen for commands from language bindings. Defaults to 5555.                                |
| –host=`<hostAdapterIPAddress>` | Specifies the IP address of the host adapter on which the HTTP server of the IE driver will listen for commands from language bindings. Defaults to 127.0.0.1. |
| –log-level=`<logLevel>`        | Specifies the level at which logging messages are output. Valid values are FATAL, ERROR, WARN, INFO, DEBUG, and TRACE. Defaults to FATAL.                      |
| –log-file=`<logFile>`          | Specifies the full path and file name of the log file. Defaults to stdout.                                                                                     |
| –extract-path=`<path>`         | Specifies the full path to the directory used to extract supporting files used by the server. Defaults to the TEMP directory if not specified.                 |
| –silent                        | Suppresses diagnostic output when the server is started.                                                                                                       |

## Important System Properties

The following system properties (read using `System.getProperty()` and set using `System.setProperty()` in Java code or the “`-DpropertyName=value`” command line flag) are used by the `InternetExplorerDriver`:

| **Property**                      | **What it means**                                                                                                                              |
| --------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `webdriver.ie.driver`             | The location of the IE driver binary.                                                                                                          |
| `webdriver.ie.driver.host`        | Specifies the IP address of the host adapter on which the IE driver will listen.                                                               |
| `webdriver.ie.driver.loglevel`    | Specifies the level at which logging messages are output. Valid values are FATAL, ERROR, WARN, INFO, DEBUG, and TRACE. Defaults to FATAL.      |
| `webdriver.ie.driver.logfile`     | Specifies the full path and file name of the log file.                                                                                         |
| `webdriver.ie.driver.silent`      | Suppresses diagnostic output when the IE driver is started.                                                                                    |
| `webdriver.ie.driver.extractpath` | Specifies the full path to the directory used to extract supporting files used by the server. Defaults to the TEMP directory if not specified. |


***

##### [Internet Explorer Driver Internals](/documentation/ie_driver_server/internals/)

More detailed information on the IE Driver.

Last modified January 23, 2022: [Updating IE info links in all docs\[deploy site\] (a5c7b8a0d9e)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/a5c7b8a0d9e1a6087da8f68bea1ce8f972b7dd92)

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/encouraged/generating_application_state/
----

# 生成应用程序状态

Selenium不应用于准备测试用例. 测试用例中所有重复性动作和准备工作, 都应通过其他方法来完成.\
例如, 大多数Web UI都具有身份验证 (诸如一个登录表单) . 在每次测试之前通过Web浏览器进行登录的消除, 将提高测试的速度和稳定性. 应该创建一种方法来获取对 AUT\* 的访问权限 (例如, 使用API登录并设置Cookie) . 此外, 不应使用Selenium创建预加载数据来进行测试的方法.\
如前所述, 应利用现有的API为 AUT\* 创建数据. \***AUT**: 待测系统

----
url: https://www.selenium.dev/zh-cn/_print/documentation/webdriver/drivers/
----

这是本节的多页打印视图。 [点击此处打印](#).

[返回本页常规视图](/zh-cn/documentation/webdriver/drivers/).

# 驱动会话

* 1: [浏览器选项](#pg-eceb2fa6f5734a163b76f0f05d50ce51)
* 2: [HTTP Client Configuration](#pg-4d031336938953ea899b618b3017a9db)
* 3: [驱动服务类](#pg-57a6b2296172e62e94628610d9c999ef)
* 4: [远程WebDriver](#pg-16183125c40ffe05c8673aa3affcdcf8)

```java
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L23)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L9)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            driver = new ChromeDriver(options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BaseTest.cs#L48)

##### /examples/dotnet/SeleniumDocs/BaseTest.cs

```cs
using System;
using System.Diagnostics;
using System.IO;
using System.Net;
using System.Net.Http;
using System.Net.Sockets;
using System.Runtime.InteropServices;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs
{
    public class BaseTest
    {
        protected IWebDriver driver;
        protected Uri GridUrl;
        private Process _webserverProcess;
        private const string ServerJarName = "selenium-server-4.44.0.jar";
        private static readonly string BaseDirectory = AppContext.BaseDirectory;
        private const string RelativePathToGrid = "../../../../../";
        private readonly string _examplesDirectory = Path.GetFullPath(Path.Combine(BaseDirectory, RelativePathToGrid));

        [TestCleanup]
        public void Cleanup()
        {
            driver?.Quit();

            if (_webserverProcess != null)
            {
                StopServer();
            }
        }

        protected void StartDriver(string browserVersion = null)
        {
            ChromeOptions options = new ChromeOptions();
            if (browserVersion != null)
            {
                options.BrowserVersion = browserVersion;
                string userDataDir = System.IO.Path.Combine(System.IO.Path.GetTempPath(), System.IO.Path.GetRandomFileName());
                System.IO.Directory.CreateDirectory(userDataDir);
                options.AddArgument($"--user-data-dir={userDataDir}");
                options.AddArgument("--no-sandbox");
                options.AddArgument("--disable-dev-shm-usage");
            }
            driver = new ChromeDriver(options);
        }

        protected async Task StartServer()
        {
            if (_webserverProcess == null || _webserverProcess.HasExited)
            {
                _webserverProcess = new Process();
                _webserverProcess.StartInfo.FileName =
                    RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? "java.exe" : "java";
                string port = GetFreeTcpPort().ToString();
                GridUrl = new Uri("http://localhost:" + port + "/wd/hub");
                _webserverProcess.StartInfo.Arguments = " -jar " + ServerJarName +
                                                        " standalone --port " + port +
                                                        " --selenium-manager true --enable-managed-downloads true";
                _webserverProcess.StartInfo.WorkingDirectory = _examplesDirectory;
                _webserverProcess.Start();
                await EnsureGridIsRunningAsync();
            }
        }

        private void StopServer()
        {
            if (_webserverProcess != null && !_webserverProcess.HasExited)
            {
                _webserverProcess.Kill();
                _webserverProcess.Dispose();
                _webserverProcess = null;
            }
        }

        private static int GetFreeTcpPort()
        {
            TcpListener l = new TcpListener(IPAddress.Loopback, 0);
            l.Start();
            int port = ((IPEndPoint)l.LocalEndpoint).Port;
            l.Stop();
            return port;
        }

        private async Task EnsureGridIsRunningAsync()
        {
            DateTime timeout = DateTime.Now.Add(TimeSpan.FromSeconds(240));
            bool isRunning = false;
            HttpClient client = new HttpClient();

            while (!isRunning && DateTime.Now < timeout)
            {
                try
                {
                    HttpResponseMessage response = await client.GetAsync(GridUrl + "/status");
                    if (response.IsSuccessStatusCode)
                    {
                        isRunning = true;
                    }
                    else
                    {
                        await Task.Delay(1000);
                    }
                }
                catch (HttpRequestException)
                {
                    await Task.Delay(1000);
                }
            }

            if (!isRunning)
            {
                throw new TimeoutException("Could not confirm the remote selenium server is running within 30 seconds");
            }
        }
    }
}
```

```rb
      driver = Selenium::WebDriver.for :chrome, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L14)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options)
      .setChromeService(service)
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/drivers/service.spec.js#L46-L50)

##### /examples/javascript/test/drivers/service.spec.js

```js
const fs = require('fs');
const os = require('os');
const path = require('path');
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const {getBinaryPaths} = require("selenium-webdriver/common/driverFinder");

describe('Service Test', function () {
  let driver;
  let userDataDir;
  let service;
  let options;

  afterEach(async function () {
    if (driver) {
      await driver.quit();
      driver = null;
    }
    if (userDataDir) {
      fs.rmSync(userDataDir, { recursive: true, force: true });
      userDataDir = null;
    }
  });

  it('Default service', async function () {
    service = new Chrome.ServiceBuilder();
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });

  it('Set Driver Location', async function () {
    options = new Chrome.Options();
    options.setBrowserVersion("stable");
    let paths = getBinaryPaths(options);
    let driverPath = paths.driverPath;
    let browserPath = paths.browserPath;
    options.setChromeBinaryPath(browserPath);
    userDataDir = fs.mkdtempSync(path.join(os.tmpdir(), 'chrome-profile-'));
    options.addArguments(`--user-data-dir=${userDataDir}`);
    options.addArguments('--no-sandbox');
    options.addArguments('--disable-dev-shm-usage');
    service = new Chrome.ServiceBuilder(driverPath);
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });

  it('Set port', async function () {
    service = new Chrome.ServiceBuilder().setPort(1234);
    driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeService(service)
      .build();
    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
  });
});
```

```java
        driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/getting_started/FirstScript.java#L29)

##### /examples/java/src/test/java/dev/selenium/getting\_started/FirstScript.java

```java
package dev.selenium.getting_started;

import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;

import java.time.Duration;

public class FirstScript {
    public static void main(String[] args) {
        WebDriver driver = new ChromeDriver();

        driver.get("https://www.selenium.dev/selenium/web/web-form.html");

        driver.getTitle();

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500));

        WebElement textBox = driver.findElement(By.name("my-text"));
        WebElement submitButton = driver.findElement(By.cssSelector("button"));

        textBox.sendKeys("Selenium");
        submitButton.click();

        WebElement message = driver.findElement(By.id("message"));
        message.getText();

        driver.quit();
    }
}
```

```py
    driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L11)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs#L28)

##### /examples/dotnet/SeleniumDocs/GettingStarted/FirstScript.cs

```cs
using System;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.GettingStarted;

public static class FirstScript
{
    public static void Main()
    {
        IWebDriver driver = new ChromeDriver();

        driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/web-form.html");

        var title = driver.Title;

        driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromMilliseconds(500);

        var textBox = driver.FindElement(By.Name("my-text"));
        var submitButton = driver.FindElement(By.TagName("button"));
            
        textBox.SendKeys("Selenium");
        submitButton.Click();
            
        var message = driver.FindElement(By.Id("message"));
        var value = message.Text;
            
        driver.Quit();
    }
}
```

```rb
      driver.quit
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L16)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/getting_started/firstScript.spec.js#L28)

##### /examples/javascript/test/getting\_started/firstScript.spec.js

```js
const {By, Builder, Browser} = require('selenium-webdriver');
const assert = require("assert");

(async function firstTest() {
  let driver;
  
  try {
    driver = await new Builder().forBrowser(Browser.CHROME).build();
    await driver.get('https://www.selenium.dev/selenium/web/web-form.html');
  
    let title = await driver.getTitle();
    assert.equal("Web form", title);
  
    await driver.manage().setTimeouts({implicit: 500});
  
    let textBox = await driver.findElement(By.name('my-text'));
    let submitButton = await driver.findElement(By.css('button'));
  
    await textBox.sendKeys('Selenium');
    await submitButton.click();
  
    let message = await driver.findElement(By.id('message'));
    let value = await message.getText();
    assert.equal("Received!", value);
  } catch (e) {
    console.log(e)
  } finally {
    await driver.quit();
  }
}())
```

```kt
        driver.quit()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/getting_started/FirstScriptTest.kt#L35)

##### /examples/kotlin/src/test/kotlin/dev/selenium/getting\_started/FirstScriptTest.kt

```kt
package dev.selenium.getting_started

import org.junit.jupiter.api.*
import org.junit.jupiter.api.Assertions.assertEquals
import org.openqa.selenium.By
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import java.time.Duration

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class FirstScriptTest {
    private lateinit var driver: WebDriver

    @Test
    fun eightComponents() {
        driver = ChromeDriver()

        driver.get("https://www.selenium.dev/selenium/web/web-form.html")

        val title = driver.title
        assertEquals("Web form", title)

        driver.manage().timeouts().implicitlyWait(Duration.ofMillis(500))

        var textBox = driver.findElement(By.name("my-text"))
        val submitButton = driver.findElement(By.cssSelector("button"))

        textBox.sendKeys("Selenium")
        submitButton.click()

        val message = driver.findElement(By.id("message"))
        val value = message.getText()
        assertEquals("Received!", value)

        driver.quit()
    }

}
```

# 1 - 浏览器选项

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L73-74)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L79-80)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L11)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L80-82)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L86-88)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options.browser_version = 'latest'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L40)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## pageLoadStrategy

共有三种类型的页面加载策略.

页面加载策略可以在此链接查询 [document.readyState](//developer.mozilla.org/en-US/docs/Web/API/Document/readyState) , 如下表所述:

| 策略     | 就绪状态        | 备注                            |
| ------ | ----------- | ----------------------------- |
| normal | complete    | 默认值, 等待所有资源下载                 |
| eager  | interactive | DOM 访问已准备就绪, 但诸如图像的其他资源可能仍在加载 |
| none   | Any         | 完全不会阻塞 WebDriver              |

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L21-L23)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L7-9)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L13-14)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L11-L12)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L28-L34)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L34-L36)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L15-L17)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L29-30)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L20-L21)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L8-L14)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L47-L49)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L23-L25)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
        public void SetPageLoadStrategyNone()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L41-42)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L29-L30)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L18-L24)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L88-L90)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L94-96)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L38-L39)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L60-L61)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L101-103)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L51-L52)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L38-L41)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L96-L98)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L30-32)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L114-L115)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L111-L113)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L37-39)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L105-L106)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L126-L128)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L44-46)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L96-L97)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L141-L142)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L51-53)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L60-L61)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L151-L152)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L58-60)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L69-L70)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L163-L164)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L65-67)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L78-L79)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class ProxyTest {
  public static void main(String[] args) {
    Proxy proxy = new Proxy();
    proxy.setHttpProxy("<HOST:PORT>");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("proxy", proxy);
    WebDriver driver = new ChromeDriver(options);
    driver.get("https://www.google.com/");
    driver.manage().window().maximize();
    driver.quit();
  }
}
```

```py
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L72-74)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

public class ProxyTest{
public static void Main() {
ChromeOptions options = new ChromeOptions();
Proxy proxy = new Proxy();
proxy.Kind = ProxyKind.Manual;
proxy.IsAutoDetect = false;
proxy.SslProxy = "<HOST:PORT>";
options.Proxy = proxy;
options.AddArgument("ignore-certificate-errors");
IWebDriver driver = new ChromeDriver(options);
driver.Navigate().GoToUrl("https://www.selenium.dev/");
}
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L87-L88)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```javascript
let webdriver = require('selenium-webdriver');
let chrome = require('selenium-webdriver/chrome');
let proxy = require('selenium-webdriver/proxy');
let opts = new chrome.Options();

(async function example() {
opts.setProxy(proxy.manual({http: '<HOST:PORT>'}));
let driver = new webdriver.Builder()
.forBrowser('chrome')
.setChromeOptions(opts)
.build();
try {
await driver.get("https://selenium.dev");
}
finally {
await driver.quit();
}
}());
```

```kotlin
import org.openqa.selenium.Proxy
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

class proxyTest {
fun main() {

        val proxy = Proxy()
        proxy.setHttpProxy("<HOST:PORT>")
        val options = ChromeOptions()
        options.setCapability("proxy", proxy)
        val driver: WebDriver = ChromeDriver(options)
        driver["https://www.google.com/"]
        driver.manage().window().maximize()
        driver.quit()
    }
}
```

# 2 - HTTP Client Configuration

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import org.openqa.selenium.remote.http.ClientConfig;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.RemoteWebDriver;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import javax.net.ssl.X509TrustManager;
import java.io.FileInputStream;
import java.net.URL;
import java.nio.file.Path;
import java.security.KeyStore;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.time.Duration;

import org.openqa.selenium.UsernameAndPassword;

import static java.net.http.HttpClient.Version.HTTP_1_1;

public class HttpClientTest extends BaseTest {
    URL gridUrl;

    @BeforeEach
    public void startGrid() {
        gridUrl = startStandaloneGridAdvanced();
    }

    @Test
    public void remoteWebDriverWithClientConfig() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createSSLContextWithCA(Path.of("src/test/resources/tls.crt").toAbsolutePath().toString()))
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
    }

    @Test
    public void remoteWebDriverIgnoreSSL() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createIgnoreSSLContext())
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .authenticateAs(new UsernameAndPassword("admin", "myStrongPassword"))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(gridUrl)
                .config(clientConfig)
                .build();
    }

    @Test
    public void remoteWebDriverWithEmbedAuthUrl() throws Exception {
        ClientConfig clientConfig = ClientConfig.defaultConfig()
                .withRetries()
                .sslContext(createSSLContextWithCA(Path.of("src/test/resources/tls.crt").toAbsolutePath().toString()))
                .connectionTimeout(Duration.ofSeconds(300))
                .readTimeout(Duration.ofSeconds(3600))
                .version(HTTP_1_1.toString());
        ChromeOptions options = getDefaultChromeOptions();
        options.setEnableDownloads(true);
        driver = RemoteWebDriver.builder()
                .oneOf(options)
                .address(embedAuthToUrl(gridUrl, "admin", "myStrongPassword"))
                .config(clientConfig)
                .build();
    }

    private URL embedAuthToUrl(URL url, String username, String password) throws Exception {
        String userInfo = username + ":" + password;
        String urlWithAuth = url.getProtocol() + "://" + userInfo + "@" + url.getHost() + ":" + url.getPort() + url.getPath();
        return new URL(urlWithAuth);
    }

    public static SSLContext createSSLContextWithCA(String caCertPath) throws Exception {
        FileInputStream fis = new FileInputStream(caCertPath);
        CertificateFactory cf = CertificateFactory.getInstance("X.509");
        X509Certificate caCert = (X509Certificate) cf.generateCertificate(fis);
        KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
        keyStore.load(null, null);
        keyStore.setCertificateEntry("caCert", caCert);
        TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
        tmf.init(keyStore);
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, tmf.getTrustManagers(), null);
        return sslContext;
    }

    public static SSLContext createIgnoreSSLContext() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[]{
                new X509TrustManager() {
                    public X509Certificate[] getAcceptedIssuers() {
                        return null;
                    }

                    public void checkClientTrusted(X509Certificate[] certs, String authType) {
                    }

                    public void checkServerTrusted(X509Certificate[] certs, String authType) {
                    }
                }
        };
        SSLContext sslContext = SSLContext.getInstance("TLS");
        sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
        return sslContext;
    }
}
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/HttpClientTest.java)

```py
import os
import pytest
import sys
from urllib3.util import Retry, Timeout
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType
from selenium.webdriver.remote.client_config import ClientConfig


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_with_client_config(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    retries = Retry(connect=2, read=2, redirect=2)
    timeout = Timeout(connect=300, read=3600)
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 init_args_for_pool_manager={
                                     "init_args_for_pool_manager": {"retries": retries, "timeout": timeout}},
                                 ca_certs=_get_resource_path("tls.crt"),
                                 username="admin", password="myStrongPassword")
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote_ignore_certs(grid_server):
    proxy = Proxy({"proxyType": ProxyType.AUTODETECT})
    client_config = ClientConfig(remote_server_addr=grid_server,
                                 proxy=proxy,
                                 timeout=3600,
                                 ignore_certificates=True,
                                 username="admin", password="myStrongPassword")
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=grid_server, options=options, client_config=client_config)
    driver.get("https://www.selenium.dev")
    driver.quit()


def _get_resource_path(file_name: str):
    if os.path.abspath("").endswith("tests"):
        path = os.path.abspath(f"resources/{file_name}")
    else:
        path = os.path.abspath(f"tests/resources/{file_name}")
    return path

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[****View on GitHub**](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_http_client.py)

[Add Example](/documentation/about/contributing/#creating-examples)

```rb

  it 'sets client configuration' do
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/http_client_spec.rb#L7-L8)

##### /examples/ruby/spec/drivers/http\_client\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'HTTP Client' do
  let(:url) { 'https://www.selenium.dev/selenium/web/' }

  it 'sets client configuration' do
    client = Selenium::WebDriver::Remote::Http::Default.new(open_timeout: 30, read_timeout: 30)
    expect(client.open_timeout).to eq 30
  end

  it 'uses the custom http client' do
    client = Selenium::WebDriver::Remote::Http::Default.new
    driver = Selenium::WebDriver.for :chrome, http_client: client
    driver.get(url)
    driver.quit
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

# 3 - 驱动服务类

```java
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L15-L16)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L5-L6)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L14-L15)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

```rb
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L14-L15)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

```java
    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L25-L26)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(executable_path=chromedriver_bin)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L15)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Selenium v4.9](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.9.0)

```cs
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L23)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
    service.executable_path = driver_path
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L26)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```

```java
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java#L33)

##### /examples/java/src/test/java/dev/selenium/drivers/ServiceTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeDriverService;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.service.DriverFinder;

public class ServiceTest extends BaseTest {
  
  @Test
  public void defaultService() {
    ChromeDriverService service = new ChromeDriverService.Builder().build();
    driver = new ChromeDriver(service);
  }

  @Test
  public void setDriverLocation() {
    setBinaryPaths();
    ChromeOptions options = getDefaultChromeOptions();
    options.setBinary(browserPath);

    ChromeDriverService service =
        new ChromeDriverService.Builder().usingDriverExecutable(driverPath).build();

    driver = new ChromeDriver(service, options);
  }

  @Test
  public void setPort() {
    ChromeDriverService service = new ChromeDriverService.Builder().usingPort(1234).build();

    driver = new ChromeDriver(service);
  }

  private void setBinaryPaths() {
    ChromeOptions options = getDefaultChromeOptions();
    options.setBrowserVersion("stable");
    DriverFinder finder = new DriverFinder(ChromeDriverService.createDefaultService(), options);
    driverPath = new File(finder.getDriverPath());
    browserPath = new File(finder.getBrowserPath());
  }
}
```

[Selenium v4.11](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.11.0)

```py
    service = webdriver.ChromeService(port=1234)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_service.py#L23)

##### /examples/python/tests/drivers/test\_service.py

```py
from selenium import webdriver


def test_basic_service():
    service = webdriver.ChromeService()
    driver = webdriver.Chrome(service=service)

    driver.quit()


def test_driver_location(chromedriver_bin, chrome_bin):
    options = get_default_chrome_options()
    options.binary_location = chrome_bin

    service = webdriver.ChromeService(executable_path=chromedriver_bin)

    driver = webdriver.Chrome(service=service, options=options)

    driver.quit()


def test_driver_port():
    service = webdriver.ChromeService(port=1234)

    driver = webdriver.Chrome(service=service)

    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            service.Port = 1234;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs#L32)

##### /examples/dotnet/SeleniumDocs/Drivers/ServiceTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using SeleniumDocs.TestSupport;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class ServiceTest : BaseTest
    {
        [TestMethod]
        public void BasicService()
        {
            var service = ChromeDriverService.CreateDefaultService();
            driver = new ChromeDriver(service);
        }

        [TestMethodCustom]
        [EnabledOnOs("OSX")]
        public void DriverLocation()
        {
            var options = GetLatestChromeOptions();
            var service = ChromeDriverService.CreateDefaultService(GetDriverLocation(options));

            driver = new ChromeDriver(service, options);
        }

        [TestMethod]
        public void DriverPort()
        {
            var service = ChromeDriverService.CreateDefaultService();
            service.Port = 1234;

            driver = new ChromeDriver(service);
        }
        
        private static string GetDriverLocation(ChromeOptions options)
        {
            return new DriverFinder(options).GetDriverPathAsync().AsTask().GetAwaiter().GetResult();
        }

        private static ChromeOptions GetLatestChromeOptions()
        {
            return new ChromeOptions
            {
                BrowserVersion = "stable"
            };
        }
    }
}
```

[Selenium v4.8](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.8.0)

```rb
    service.port = 1234
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/service_spec.rb#L33)

##### /examples/ruby/spec/drivers/service\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Service' do
  let(:file_name) { File.expand_path('driver.log') }
  let(:driver_path) { ENV.fetch('CHROMEDRIVER_BIN', nil) }
  let(:browser_path) { ENV.fetch('CHROME_BIN', nil) }

  before { driver_finder }
  after { FileUtils.rm_f(file_name) }

  it 'has default service' do
    service = Selenium::WebDriver::Service.chrome
    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  it 'specifies driver location' do
    user_data_dir = Dir.mktmpdir('chrome-profile-')
    options = Selenium::WebDriver::Options.chrome(binary: browser_path)
    options.add_argument("--user-data-dir=#{user_data_dir}")
    options.add_argument('--no-sandbox')
    options.add_argument('--disable-dev-shm-usage')
    service = Selenium::WebDriver::Service.chrome

    service.executable_path = driver_path

    @driver = Selenium::WebDriver.for :chrome, service: service, options: options
  end

  it 'specifies driver port' do
    service = Selenium::WebDriver::Service.chrome
    service.port = 1234

    @driver = Selenium::WebDriver.for :chrome, service: service
  end

  def driver_finder
    options = Selenium::WebDriver::Options.chrome(browser_version: 'stable')
    service = Selenium::WebDriver::Service.chrome
    finder = Selenium::WebDriver::DriverFinder.new(options, service)
    ENV['CHROMEDRIVER_BIN'] = finder.driver_path
    ENV['CHROME_BIN'] = finder.browser_path
  end
end
```


# 4 - 远程WebDriver

```java
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L38-L39)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L13-L14)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L28-L29)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L20-L21)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L49-L52)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

Python adds a local file detector to remote webdriver instances by default, but you can also create your own class.

```py
    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#LL29-L32)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

.NET adds a local file detector to remote webdriver instances by default, but you can also create your own class.

```cs
            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L47-L50)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

Ruby adds a local file detector to remote webdriver instances by default, but you can also create your own lambda:

```rb
    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L33-L36)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## 下载

Chrome、Edge和Firefox都允许您设置下载目录的位置. 但是, 当您在远程计算机上执行此操作时, 位置在远程计算机的本地文件系统上. Selenium允许您启用下载功能, 将这些文件下载到客户端计算机上.

### 在网格中启用下载

当以节点或独立模式启动网格时, 你必须添加参数:

```
--enable-managed-downloads true
```

```java
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L60-L62)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L42-L44)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L59-L64)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L43-L44)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    List<String> files = ((HasDownloads) driver).getDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L73)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    files = driver.get_downloadable_files()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L52)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L72)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    files = driver.downloadable_files
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L52)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L83)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    driver.download_file(downloadable_file, target_directory)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L58)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L79)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    driver.download_file(downloadable_file, target_directory)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L57)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    ((HasDownloads) driver).deleteDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L88)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

```py
    driver.delete_downloadable_files()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_remote_webdriver.py#L64)

##### /examples/python/tests/drivers/test\_remote\_webdriver.py

```py
import os
import sys

import pytest
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.remote.file_detector import LocalFileDetector
from selenium.webdriver.support.wait import WebDriverWait


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_start_remote(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    assert "localhost" in driver.command_executor._client_config.remote_server_addr
    driver.quit()


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_uploads(server):
    options = get_default_chrome_options()
    driver = webdriver.Remote(command_executor=server, options=options)

    driver.get("https://the-internet.herokuapp.com/upload")
    upload_file = os.path.abspath(
        os.path.join(os.path.dirname(__file__), "..", "selenium-snapshot.png"))

    driver.file_detector = LocalFileDetector()
    file_input = driver.find_element(By.CSS_SELECTOR, "input[type='file']")
    file_input.send_keys(upload_file)
    driver.find_element(By.ID, "file-submit").click()

    file_name_element = driver.find_element(By.ID, "uploaded-files")
    file_name = file_name_element.text

    assert file_name == "selenium-snapshot.png"


@pytest.mark.skipif(sys.platform == "win32", reason="Gets stuck on Windows, passes locally")
def test_downloads(server, temp_dir):
    options = get_default_chrome_options()
    options.enable_downloads = True
    driver = webdriver.Remote(command_executor=server, options=options)

    file_names = ["file_1.txt", "file_2.jpg"]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(By.ID, "file-1").click()
    driver.find_element(By.ID, "file-2").click()
    WebDriverWait(driver, 3).until(lambda d: "file_2.jpg" in d.get_downloadable_files())

    files = driver.get_downloadable_files()

    assert sorted(files) == sorted(file_names)
    downloadable_file = file_names[0]
    target_directory = temp_dir

    driver.download_file(downloadable_file, target_directory)

    target_file = os.path.join(target_directory, downloadable_file)
    with open(target_file, "r") as file:
        assert "Hello, World!" in file.read()

    driver.delete_downloadable_files()

    assert not driver.get_downloadable_files()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ((RemoteWebDriver)driver).DeleteDownloadableFiles();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L84)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```rb
    driver.delete_downloadable_files
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/remote_webdriver_spec.rb#L62)

##### /examples/ruby/spec/drivers/remote\_webdriver\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'
require 'selenium/server'

RSpec.describe 'Remote WebDriver' do
  let(:target_directory) { File.join(Dir.tmpdir, SecureRandom.uuid) }
  let(:wait) { Selenium::WebDriver::Wait.new(timeout: 2) }
  let(:server) do
    Selenium::Server.new(File.expand_path(File.join('..', '..', '..', 'selenium-server-4.44.0.jar'), __dir__),
                         background: true,
                         args: %w[--selenium-manager true --enable-managed-downloads true])
  end
  let(:grid_url) { server.webdriver_url }

  before { server.start }
  after { server.stop }

  it 'starts remotely' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    expect { driver.session_id }.not_to raise_exception
  end

  it 'uploads' do
    options = Selenium::WebDriver::Options.chrome
    driver = Selenium::WebDriver.for :remote, url: server.webdriver_url, options: options

    driver.get('https://the-internet.herokuapp.com/upload')
    upload_file = File.expand_path('../spec_support/selenium-snapshot.png', __dir__)

    driver.file_detector = ->((filename, *)) { filename.include?('selenium') && filename }
    file_input = driver.find_element(css: 'input[type=file]')
    file_input.send_keys(upload_file)
    driver.find_element(id: 'file-submit').click

    wait.until { driver.find_element(id: 'uploaded-files') }
    expect(driver.find_element(id: 'uploaded-files').text).to eq 'selenium-snapshot.png'
  end

  it 'downloads' do
    options = Selenium::WebDriver::Options.chrome(enable_downloads: true)
    driver = Selenium::WebDriver.for :remote, url: grid_url, options: options

    file_names = %w[file_1.txt file_2.jpg]
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')
    driver.find_element(id: 'file-1').click
    driver.find_element(id: 'file-2').click
    wait.until { driver.downloadable_files.include?('file_2.jpg') && driver.downloadable_files.include?('file_1.txt') }

    files = driver.downloadable_files

    expect(files.sort).to eq file_names.sort
    downloadable_file = 'file_1.txt'

    driver.download_file(downloadable_file, target_directory)

    file_content = File.read("#{target_directory}/#{downloadable_file}").strip
    expect(file_content).to eq('Hello, World!')

    driver.delete_downloadable_files

    expect(driver.downloadable_files).to be_empty
  end
end
```

```java
    driver = new Augmenter().augment(driver);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L98)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

Of interest, using the `RemoteWebDriverBuilder` automatically augments the driver, so it is a great way to get all the functionality by default:

```java
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java#L106-L111)

##### /examples/java/src/test/java/dev/selenium/drivers/RemoteWebDriverTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.HasDownloads;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chromium.HasCasting;
import org.openqa.selenium.remote.Augmenter;
import org.openqa.selenium.remote.LocalFileDetector;
import org.openqa.selenium.remote.RemoteWebDriver;
import org.openqa.selenium.remote.http.ClientConfig;
import org.openqa.selenium.support.ui.WebDriverWait;

public class RemoteWebDriverTest extends BaseTest {
  URL gridUrl;

  @BeforeEach
  public void startGrid() {
    gridUrl = startStandaloneGrid();
  }

  @Test
  public void runRemote() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
  }

  @Test
  public void uploads() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);
    driver.get("https://the-internet.herokuapp.com/upload");
    File uploadFile = new File("src/test/resources/selenium-snapshot.png");

    ((RemoteWebDriver) driver).setFileDetector(new LocalFileDetector());
    WebElement fileInput = driver.findElement(By.cssSelector("input[type=file]"));
    fileInput.sendKeys(uploadFile.getAbsolutePath());
    driver.findElement(By.id("file-submit")).click();

    WebElement fileName = driver.findElement(By.id("uploaded-files"));
    Assertions.assertEquals("selenium-snapshot.png", fileName.getText());
  }

  @Test
  public void downloads() throws IOException {
    ChromeOptions options = getDefaultChromeOptions();
    options.setEnableDownloads(true);
    driver = new RemoteWebDriver(gridUrl, options);

    List<String> fileNames = new ArrayList<>();
    fileNames.add("file_1.txt");
    fileNames.add("file_2.jpg");
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");
    driver.findElement(By.id("file-1")).click();
    driver.findElement(By.id("file-2")).click();
    new WebDriverWait(driver, Duration.ofSeconds(5))
        .until(d -> ((HasDownloads) d).getDownloadableFiles().contains("file_2.jpg"));

    List<String> files = ((HasDownloads) driver).getDownloadableFiles();

    // Sorting them to avoid differences when comparing the files
    fileNames.sort(Comparator.naturalOrder());
    files.sort(Comparator.naturalOrder());
    
    Assertions.assertEquals(fileNames, files);
    String downloadableFile = files.get(0);
    Path targetDirectory = Files.createTempDirectory("download");

    ((HasDownloads) driver).downloadFile(downloadableFile, targetDirectory);

    String fileContent = String.join("", Files.readAllLines(targetDirectory.resolve(downloadableFile)));
    Assertions.assertEquals("Hello, World!", fileContent);

    ((HasDownloads) driver).deleteDownloadableFiles();

    Assertions.assertTrue(((HasDownloads) driver).getDownloadableFiles().isEmpty());
  }

  @Test
  public void augment() {
    ChromeOptions options = getDefaultChromeOptions();
    driver = new RemoteWebDriver(gridUrl, options);

    driver = new Augmenter().augment(driver);

    Assertions.assertTrue(driver instanceof HasCasting);
  }

  @Test
  public void remoteWebDriverBuilder() {
    driver =
        RemoteWebDriver.builder()
            .address(gridUrl)
            .oneOf(getDefaultChromeOptions())
            .setCapability("ext:options", Map.of("key", "value"))
            .config(ClientConfig.defaultConfig())
            .build();

    Assertions.assertTrue(driver instanceof HasCasting);
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

.NET uses a custom command executor for executing commands that are valid for the given browser in the remote driver.

```cs
            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs#L96-L100)

##### /examples/dotnet/SeleniumDocs/Drivers/RemoteWebDriverTest.cs

```cs
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;
using OpenQA.Selenium.Firefox;
using OpenQA.Selenium.Remote;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class RemoteWebDriverTest : BaseTest
    {
        [TestInitialize]
        public async Task Setup()
        {
            await StartServer();
        }

        [TestMethod]
        public void RunRemote()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            Assert.IsInstanceOfType(driver, typeof(IHasDownloads));
        }

        [TestMethod]
        public void Uploads()
        {
            var options = new ChromeOptions();
            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://the-internet.herokuapp.com/upload";

            string baseDirectory = AppContext.BaseDirectory;
            string relativePath = "../../../TestSupport/selenium-snapshot.png";

            string uploadFile = Path.GetFullPath(Path.Combine(baseDirectory, relativePath));

            ((RemoteWebDriver)driver).FileDetector = new LocalFileDetector();
            IWebElement fileInput = driver.FindElement(By.CssSelector("input[type=file]"));
            fileInput.SendKeys(uploadFile);
            driver.FindElement(By.Id("file-submit")).Click();

            IWebElement fileName = driver.FindElement(By.Id("uploaded-files"));
            Assert.AreEqual("selenium-snapshot.png", fileName.Text);
        }

        [TestMethod]
        public void Downloads()
        {
            ChromeOptions options = new ChromeOptions
            {
                EnableDownloads = true
            };

            driver = new RemoteWebDriver(GridUrl, options);

            driver.Url = "https://selenium.dev/selenium/web/downloads/download.html";
            driver.FindElement(By.Id("file-1")).Click();
            driver.FindElement(By.Id("file-2")).Click();
            WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(5));
            wait.Until(d => ((RemoteWebDriver)d).GetDownloadableFiles().Contains("file_2.jpg"));

            IReadOnlyList<string> names = ((RemoteWebDriver)driver).GetDownloadableFiles();

            Assert.IsTrue(names.Contains("file_1.txt"));
            Assert.IsTrue(names.Contains("file_2.jpg"));
            string downloadableFile = names.First(f => f == "file_1.txt");
            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());

            ((RemoteWebDriver)driver).DownloadFile(downloadableFile, targetDirectory);

            string fileContent = File.ReadAllText(Path.Combine(targetDirectory, downloadableFile));
            Assert.AreEqual("Hello, World!", fileContent.Trim());

            ((RemoteWebDriver)driver).DeleteDownloadableFiles();

            Assert.IsTrue(((RemoteWebDriver)driver).GetDownloadableFiles().IsNullOrEmpty());
            Directory.Delete(targetDirectory, recursive: true);
        }

        [TestMethod]
        public void CustomExecutor()
        {
            driver = new RemoteWebDriver(GridUrl, new FirefoxOptions());
            driver.Navigate().GoToUrl("https://www.selenium.dev/");

            var customCommandDriver = driver as ICustomDriverCommandExecutor;
            customCommandDriver.RegisterCustomDriverCommands(FirefoxDriver.CustomCommandDefinitions);

            var screenshotResponse = customCommandDriver
                .ExecuteCustomDriverCommand(FirefoxDriver.GetFullPageScreenshotCommand, null);

            Screenshot image = new Screenshot((string)screenshotResponse);

            string targetDirectory = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
            Directory.CreateDirectory(targetDirectory);
            string targetFile = Path.GetFullPath(Path.Combine(targetDirectory, "fullPage.png"));

            using (var memoryStream = new MemoryStream(image.AsByteArray))
            using (var fileStream = new FileStream(targetFile, FileMode.Create))
            {
                memoryStream.WriteTo(fileStream);
            }

            Assert.IsTrue(File.Exists(targetFile));
            
            Directory.Delete(targetDirectory, true);
        }
    }
}
```

```xml
  <dependency>
      <groupId>io.opentelemetry</groupId>
      <artifactId>opentelemetry-exporter-jaeger</artifactId>
      <version>1.0.0</version>
    </dependency>
    <dependency>
      <groupId>io.grpc</groupId>
      <artifactId>grpc-netty</artifactId>
      <version>1.35.0</version>
    </dependency>
```

### 在运行客户端时添加/传递所需的系统属性

*

```java
System.setProperty("otel.traces.exporter", "jaeger");
System.setProperty("otel.exporter.jaeger.endpoint", "http://localhost:14250");
System.setProperty("otel.resource.attributes", "service.name=selenium-java-client");

ImmutableCapabilities capabilities = new ImmutableCapabilities("browserName", "chrome");

WebDriver driver = new RemoteWebDriver(new URL("http://www.example.com"), capabilities);

driver.get("http://www.google.com");

driver.quit();

  
```

有关所需Selenium版本 及其外部依赖关系版本等更多信息, 请参阅[追踪设置](https://github.com/SeleniumHQ/selenium/blob/selenium-4.0.0-beta-1/java/server/src/org/openqa/selenium/grid/commands/tracing.txt) .

更多信息请访问:

* OpenTelemetry: <https://opentelemetry.io>
* 配置OpenTelemetry: <https://github.com/open-telemetry/opentelemetry-java/tree/main/sdk-extensions/autoconfigure>
* Jaeger: <https://www.jaegertracing.io>
* [Selenium Grid 可观测性](https://www.selenium.dev/zh-cn/documentation/grid/advanced_features/observability/)

----
url: https://www.selenium.dev/ja/_print/documentation/webdriver/bidi/cdp/
----

これは、このセクションの複数ページの印刷可能なビューです。 [印刷するには、ここをクリックしてください](#).

[このページの通常のビューに戻る](/ja/documentation/webdriver/bidi/cdp/).

# Chrome DevTools Protocol

Examples of working with Chrome DevTools Protocol in Selenium. CDP support is temporary until WebDriver BiDi has been implemented.

* 1: [Chrome DevTools Logging Features](#pg-1741675ff6cb1113ab10410cce599658)
* 2: [Chrome DevTools Network Features](#pg-e9f01e3b8535290b9020173df6e76f9c)
* 3: [Chrome DevTools Script Features](#pg-16ae21cdcb7440592aa58367788b8f2c)

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/CdpTest.java#L22-L27)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/CdpTest.java

```java
package dev.selenium.bidi.cdp;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chromium.HasCdp;

import java.util.HashMap;
import java.util.Map;

public class CdpTest extends BaseTest {
  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
  }

  @Test
  public void setCookie() {
    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);

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }
}
```

```py
    cookie = {'name': 'cheese',
              'value': 'gouda',
              'domain': 'www.selenium.dev',
              'secure': True}

    driver.execute_cdp_cmd('Network.setCookie', cookie)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_cdp.py#L2-L7)

##### /examples/python/tests/bidi/cdp/test\_cdp.py

```py
def test_set_cookie(driver):
    cookie = {'name': 'cheese',
              'value': 'gouda',
              'domain': 'www.selenium.dev',
              'secure': True}

    driver.execute_cdp_cmd('Network.setCookie', cookie)

    driver.get('https://www.selenium.dev')
    cheese = driver.get_cookie(cookie['name'])

    assert cheese['value'] == 'gouda'
```

```cs
            var cookie = new Dictionary<string, object>
            {
                { "name", "cheese" },
                { "value", "gouda" },
                { "domain", "www.selenium.dev" },
                { "secure", true }
            };
            ((ChromeDriver)driver).ExecuteCdpCommand("Network.setCookie", cookie);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/CDPTest.cs#L14-L21)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/CDPTest.cs

```cs
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class CDPTest : BaseChromeTest
    {
        [TestMethod]
        public void SetCookie()
        {
            var cookie = new Dictionary<string, object>
            {
                { "name", "cheese" },
                { "value", "gouda" },
                { "domain", "www.selenium.dev" },
                { "secure", true }
            };
            ((ChromeDriver)driver).ExecuteCdpCommand("Network.setCookie", cookie);
            
            driver.Url = "https://www.selenium.dev";
            Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);

        }
    }
}
```

```rb
    driver.execute_cdp('Network.setCookie',
                       name: 'cheese',
                       value: 'gouda',
                       domain: 'www.selenium.dev',
                       secure: true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/cdp_spec.rb#L9-L13)

##### /examples/ruby/spec/bidi/cdp/cdp\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'sets cookie' do
    driver.execute_cdp('Network.setCookie',
                       name: 'cheese',
                       value: 'gouda',
                       domain: 'www.selenium.dev',
                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end
end
```

```java
    ((HasLogEvents) driver).onLogEvent(consoleEvent(e -> messages.add(e.getMessages().get(0))));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/LoggingTest.java#L31)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/LoggingTest.java

```java
package dev.selenium.bidi.cdp;

import static org.openqa.selenium.devtools.events.CdpEventTypes.consoleEvent;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.concurrent.CopyOnWriteArrayList;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.HasLogEvents;
import org.openqa.selenium.support.ui.WebDriverWait;

public class LoggingTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void consoleLogs() {
    driver.get("https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html");
    CopyOnWriteArrayList<String> messages = new CopyOnWriteArrayList<>();

    ((HasLogEvents) driver).onLogEvent(consoleEvent(e -> messages.add(e.getMessages().get(0))));

    driver.findElement(By.id("consoleLog")).click();
    driver.findElement(By.id("consoleError")).click();

    wait.until(_d -> messages.size() > 1);
    Assertions.assertTrue(messages.contains("Hello, world!"));
    Assertions.assertTrue(messages.contains("I am console error"));
  }
}
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_logs.py#L11-12)

##### /examples/python/tests/bidi/cdp/test\_logs.py

```py
import pytest
from selenium.webdriver.common.bidi.console import Console
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log


@pytest.mark.trio
async def test_console_log(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
            driver.find_element(by=By.ID, value='consoleLog').click()

        assert messages["message"] == "Hello, world!"


@pytest.mark.trio
async def test_js_error(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
            driver.find_element(by=By.ID, value='jsException').click()

        assert "Error: Not working" in messages.exception_details.exception.description
```

```cs
            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs#L19-L25)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class LoggingTest : BaseChromeTest
    {
        [TestMethod]
        public async Task ConsoleLogs()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("consoleLog")).Click();
            driver.FindElement(By.Id("consoleError")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => messages.Count > 1);
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Hello, world!"));
            Assert.IsTrue(messages.Contains("I am console error"));
        }
        
        [TestMethod]
        public async Task JsErrors()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("jsException")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !messages.IsNullOrEmpty());
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Uncaught"));
        }
    }
}
```

```rb
    driver.on_log_event(:console) { |log| logs << log.args.first }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/logging_spec.rb#L12)

##### /examples/ruby/spec/bidi/cdp/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'listens for console logs' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    logs = []
    driver.on_log_event(:console) { |log| logs << log.args.first }

    driver.find_element(id: 'consoleLog').click
    driver.find_element(id: 'consoleError').click

    Selenium::WebDriver::Wait.new.until { logs.size > 1 }
    expect(logs).to include 'Hello, world!'
    expect(logs).to include 'I am console error'
  end

  it 'listens for js exception' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    exceptions = []
    driver.on_log_event(:exception) { |exception| exceptions << exception }

    driver.find_element(id: 'jsException').click

    Selenium::WebDriver::Wait.new.until { exceptions.any? }
    expect(exceptions.first&.description).to include 'Error: Not working'
  end
end
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_logs.py#L22-L23)

##### /examples/python/tests/bidi/cdp/test\_logs.py

```py
import pytest
from selenium.webdriver.common.bidi.console import Console
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log


@pytest.mark.trio
async def test_console_log(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_listener(Console.ALL) as messages:
            driver.find_element(by=By.ID, value='consoleLog').click()

        assert messages["message"] == "Hello, world!"


@pytest.mark.trio
async def test_js_error(driver):
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    async with driver.bidi_connection() as session:
        async with Log(driver, session).add_js_error_listener() as messages:
            driver.find_element(by=By.ID, value='jsException').click()

        assert "Error: Not working" in messages.exception_details.exception.description
```

```cs
            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs#L41-L47)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/LoggingTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class LoggingTest : BaseChromeTest
    {
        [TestMethod]
        public async Task ConsoleLogs()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptConsoleApiCalled += (_, e) =>
            {
                messages.Add(e.MessageContent);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("consoleLog")).Click();
            driver.FindElement(By.Id("consoleError")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => messages.Count > 1);
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Hello, world!"));
            Assert.IsTrue(messages.Contains("I am console error"));
        }
        
        [TestMethod]
        public async Task JsErrors()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html";

            using IJavaScriptEngine monitor = new JavaScriptEngine(driver);
            var messages = new List<string>();
            monitor.JavaScriptExceptionThrown += (_, e) =>
            {
                messages.Add(e.Message);
            };
            await monitor.StartEventMonitoring();

            driver.FindElement(By.Id("jsException")).Click();
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !messages.IsNullOrEmpty());
            monitor.StopEventMonitoring();

            Assert.IsTrue(messages.Contains("Uncaught"));
        }
    }
}
```

```rb
    driver.on_log_event(:exception) { |exception| exceptions << exception }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/logging_spec.rb#L26)

##### /examples/ruby/spec/bidi/cdp/logging\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'listens for console logs' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    logs = []
    driver.on_log_event(:console) { |log| logs << log.args.first }

    driver.find_element(id: 'consoleLog').click
    driver.find_element(id: 'consoleError').click

    Selenium::WebDriver::Wait.new.until { logs.size > 1 }
    expect(logs).to include 'Hello, world!'
    expect(logs).to include 'I am console error'
  end

  it 'listens for js exception' do
    driver.get('https://www.selenium.dev/selenium/web/bidi/logEntryAdded.html')

    exceptions = []
    driver.on_log_event(:exception) { |exception| exceptions << exception }

    driver.find_element(id: 'jsException').click

    Selenium::WebDriver::Wait.new.until { exceptions.any? }
    expect(exceptions.first&.description).to include 'Error: Not working'
  end
end
```

```java
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L41-L43)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
        credentials = base64.b64encode("admin:admin".encode()).decode()
        auth = {'authorization': 'Basic ' + credentials}
        await connection.session.execute(connection.devtools.network.set_extra_http_headers(Headers(auth)))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L13-15)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L25-L32)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L9-L11)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      HttpResponse res = next.execute(req);
                      contentType.add(res.getHeader("Content-Type"));
                      return res;
                    })) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L56-L65)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L46-L51)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L20-L24)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    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!"))))) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L75-L85)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L62-L73)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L31-L35)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L97-L110)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L85-L97)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    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
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L42-L46)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L125-L126)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    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())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L26-L28)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L114-L118)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L56-L57)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    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()));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L142-L157)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    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)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_network.py#L37-L44)

##### /examples/python/tests/bidi/cdp/test\_network.py

```py
import base64

import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.common.devtools.v145.network import Headers


@pytest.mark.trio
async def test_basic_auth(driver):
    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)))

        driver.get('https://the-internet.herokuapp.com/basic_auth')

    success = driver.find_element(by=By.TAG_NAME, value='p')
    assert success.text == 'Congratulations! You must have the proper credentials.'

@pytest.mark.trio
async def test_performance(driver):
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    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())

    metrics = {metric.name: metric.value for metric in metric_list}

    assert metrics["DevToolsCommandDuration"] > 0
    assert metrics["Frames"] == 12

@pytest.mark.trio
async def test_set_cookie(driver):
    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)

    driver.get("https://www.selenium.dev")
    cheese = driver.get_cookie("cheese")

    assert cheese["value"] == "gouda"
```

```cs
            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs#L136-L143)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/NetworkTest.cs

```cs
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.DevTools;
using System.Linq;
using OpenQA.Selenium.DevTools.V145.Network;
using OpenQA.Selenium.DevTools.V145.Performance;


namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class NetworkTest : BaseTest
    {
        [TestInitialize]
        public void Startup()
        {
            StartDriver("145");
        }

        [TestMethod]
        public async Task BasicAuthentication()
        {
            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.Navigate().GoToUrl("https://the-internet.herokuapp.com/basic_auth");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("Congratulations! You must have the proper credentials.",
                driver.FindElement(By.TagName("p")).Text);
        }

        [TestMethod]
        public async Task RecordNetworkResponse()
        {
            var contentType = new List<string>();

            INetwork networkInterceptor = driver.Manage().Network;
            networkInterceptor.NetworkResponseReceived += (_, e)  =>
            {
                contentType.Add(e.ResponseHeaders["content-type"]);
            };
            await networkInterceptor.StartMonitoring();

            driver.Navigate().GoToUrl("https://www.selenium.dev/selenium/web/blank.html");
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("text/html; charset=utf-8", contentType[0]);
        }

        [TestMethod]
        public async Task TransformNetworkResponse()
        {
            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.Navigate().GoToUrl("https://www.selenium.dev");
            await networkInterceptor.StopMonitoring();

            var body = driver.FindElement(By.TagName("body"));
            Assert.AreEqual("Creamy, delicious cheese!", body.Text);
        }

        [TestMethod]
        public async Task TransformNetworkRequest()
        {
            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.Url = "https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html";
            driver.FindElement(By.TagName("button")).Click();
            await networkInterceptor.StopMonitoring();

            Assert.AreEqual("two", driver.FindElement(By.Id("result")).Text);
        }

        [TestMethod]
        public async Task PerformanceMetrics()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/frameset.html";

            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();

            await domains.Performance.Enable(new OpenQA.Selenium.DevTools.V145.Performance.EnableCommandSettings());
            var metricsResponse =
                await session.SendCommand<GetMetricsCommandSettings, GetMetricsCommandResponse>(
                    new GetMetricsCommandSettings()
                );

            var metrics = metricsResponse.Metrics.ToDictionary(
                dict => dict.Name,
                dict => dict.Value
            );

            Assert.IsTrue(metrics["DevToolsCommandDuration"] > 0);
            Assert.AreEqual(12, metrics["Frames"]);
        }

        [TestMethod]
        public async Task SetCookie()
        {
            var session = ((IDevTools)driver).GetDevToolsSession();
            var domains = session.GetVersionSpecificDomains<OpenQA.Selenium.DevTools.V145.DevToolsSessionDomains>();
            await domains.Network.Enable(new OpenQA.Selenium.DevTools.V145.Network.EnableCommandSettings());

            var cookieCommandSettings = new SetCookieCommandSettings
            {
                Name = "cheese",
                Value = "gouda",
                Domain = "www.selenium.dev",
                Secure = true
            };
            await domains.Network.SetCookie(cookieCommandSettings);

            driver.Url = "https://www.selenium.dev";
            OpenQA.Selenium.Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);
        }

    }
}
```

```rb
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L68-L71)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    devTools.send(
            Browser.setDownloadBehavior(
                    Browser.SetDownloadBehaviorBehavior.ALLOWANDNAME,
                    Optional.empty(),
                    Optional.of(""),
                    Optional.of(true)));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L171-L176)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```rb
    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
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/network_spec.rb#L82-L88)

##### /examples/ruby/spec/bidi/cdp/network\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Network' do
  let(:driver) { start_session }

  it 'does basic authentication' do
    driver.register(username: 'admin',
                    password: 'admin',
                    uri: /herokuapp/)

    driver.get('https://the-internet.herokuapp.com/basic_auth')

    expect(driver.find_element(tag_name: 'p').text).to eq('Congratulations! You must have the proper credentials.')
  end

  it 'records network response' do
    content_type = []
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        content_type << response.headers['content-type']
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(content_type.first).to eq('text/html; charset=utf-8')
  end

  it 'transforms network response' do
    driver.intercept do |request, &continue|
      continue.call(request) do |response|
        response.body = 'Creamy, delicious cheese!' if request.url.include?('blank')
      end
    end

    driver.get('https://www.selenium.dev/selenium/web/blank.html')
    expect(driver.find_element(tag_name: 'body').text).to eq('Creamy, delicious cheese!')
  end

  it 'intercepts network request' do
    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

    driver.get('https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html')
    driver.find_element(tag_name: 'button').click
    expect(driver.find_element(id: 'result').text).to eq('two')
  end

  it 'gets performance metrics' do
    driver.get('https://www.selenium.dev/selenium/web/frameset.html')

    driver.devtools.performance.enable
    metric_list = driver.devtools.performance.get_metrics.dig('result', 'metrics')

    metrics = metric_list.each_with_object({}) do |metric, hash|
      hash[metric['name']] = metric['value']
    end

    expect(metrics['DevToolsCommandDuration']).to be > 0
    expect(metrics['Frames']).to eq 12
  end

  it 'sets cookie' do
    driver.devtools.network.set_cookie(name: 'cheese',
                                       value: 'gouda',
                                       domain: 'www.selenium.dev',
                                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end

  it 'waits for downloads', except: {platform: :windows} do
    driver.get('https://www.selenium.dev/selenium/web/downloads/download.html')

    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

    driver.find_element(id: 'file-2').click

    expect { Selenium::WebDriver::Wait.new.until { @completed } }.not_to raise_exception
  end
end
```

```java
    ScriptKey key = ((JavascriptExecutor) driver).pin("return arguments;");
    List<Object> arguments =
        (List<Object>) ((JavascriptExecutor) driver).executeScript(key, 1, true, element);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/ScriptTest.java#L32-L34)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/ScriptTest.java

```java
package dev.selenium.bidi.cdp;

import static org.openqa.selenium.devtools.events.CdpEventTypes.domMutation;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.HasLogEvents;
import org.openqa.selenium.support.ui.WebDriverWait;

public class ScriptTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void pinScript() {
    driver.get("https://www.selenium.dev/selenium/web/xhtmlTest.html");
    WebElement element = driver.findElement(By.id("id1"));

    ScriptKey key = ((JavascriptExecutor) driver).pin("return arguments;");
    List<Object> arguments =
        (List<Object>) ((JavascriptExecutor) driver).executeScript(key, 1, true, element);

    Assertions.assertEquals(List.of(1L, true, element), arguments);
  }

  @Test
  public void mutatedElements() {
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    CopyOnWriteArrayList<WebElement> mutations = new CopyOnWriteArrayList<>();

    ((HasLogEvents) driver).onLogEvent(domMutation(e -> mutations.add(e.getElement())));

    driver.findElement(By.id("reveal")).click();

    wait.until(_d -> !mutations.isEmpty());
    Assertions.assertEquals(mutations.get(0), driver.findElement(By.id("revealed")));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs#L21-L22)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs

```cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class ScriptTest : BaseChromeTest
    {
        [TestMethod]
        public async Task PinScript()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/xhtmlTest.html";
            var element = driver.FindElement(By.Id("id1"));

            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);

            var expected = new List<object>
            {
                1L,
                true,
                element
            };
            CollectionAssert.AreEqual(expected, (ICollection)arguments);
        }

        [TestMethod]
        public async Task MutatedElements()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            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();

            driver.FindElement(By.Id("reveal")).Click();
            
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !mutations.IsNullOrEmpty());
            await monitor.DisableDomMutationMonitoring();
            monitor.StopEventMonitoring();

            var revealed = driver.FindElement(By.Id("revealed")); 
            Assert.AreEqual(revealed, mutations[0]);
        }
    }
}
```

```rb
    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/script_spec.rb#L12-L13)

##### /examples/ruby/spec/bidi/cdp/script\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Script' do
  let(:driver) { start_session }

  it 'pins script' do
    driver.get('https://www.selenium.dev/selenium/web/xhtmlTest.html')
    element = driver.find_element(id: 'id1')

    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)

    expect(arguments).to eq([1, true, element])
  end

  it 'gets mutated elements' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'

    mutations = []
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }

    driver.find_element(id: 'reveal').click
    Selenium::WebDriver::Wait.new(timeout: 30).until { mutations.any? }

    expect(mutations).to include(driver.find_element(id: 'revealed'))
  end
end
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).mutation_events() as event:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_script.py#L10-L11)

##### /examples/python/tests/bidi/cdp/test\_script.py

```py
import pytest
import trio
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

@pytest.mark.trio
async def test_mutation(driver):
    async with driver.bidi_connection() as session:
        async with Log(driver, session).mutation_events() as event:
            await trio.to_thread.run_sync(lambda: driver.get('https://www.selenium.dev/selenium/web/dynamic.html'))
            await trio.to_thread.run_sync(lambda: WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "reveal"))))
            await trio.to_thread.run_sync(lambda: driver.find_element(By.ID, "reveal").click())

    assert event["element"] == driver.find_element(By.ID, "revealed")
```

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs#L39-L46)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs

```cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class ScriptTest : BaseChromeTest
    {
        [TestMethod]
        public async Task PinScript()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/xhtmlTest.html";
            var element = driver.FindElement(By.Id("id1"));

            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);

            var expected = new List<object>
            {
                1L,
                true,
                element
            };
            CollectionAssert.AreEqual(expected, (ICollection)arguments);
        }

        [TestMethod]
        public async Task MutatedElements()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            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();

            driver.FindElement(By.Id("reveal")).Click();
            
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !mutations.IsNullOrEmpty());
            await monitor.DisableDomMutationMonitoring();
            monitor.StopEventMonitoring();

            var revealed = driver.FindElement(By.Id("revealed")); 
            Assert.AreEqual(revealed, mutations[0]);
        }
    }
}
```

```rb
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/script_spec.rb#L22)

##### /examples/ruby/spec/bidi/cdp/script\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Script' do
  let(:driver) { start_session }

  it 'pins script' do
    driver.get('https://www.selenium.dev/selenium/web/xhtmlTest.html')
    element = driver.find_element(id: 'id1')

    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)

    expect(arguments).to eq([1, true, element])
  end

  it 'gets mutated elements' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'

    mutations = []
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }

    driver.find_element(id: 'reveal').click
    Selenium::WebDriver::Wait.new(timeout: 30).until { mutations.any? }

    expect(mutations).to include(driver.find_element(id: 'revealed'))
  end
end
```

----
url: https://www.selenium.dev/documentation/webdriver/interactions/print_page/
----

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L14-L17)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L12-L19)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L12-L14)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L23-L26)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L22-L29)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L18-L20)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L32-L35)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L32-L38)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L24-L26)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L41-L48)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L51-L57)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L30-L35)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L53-L57)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L61-L68)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L42-L45)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L63-L66)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L41-L48)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L49-L51)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java#L72-L75)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintOptionsTest.java

```java
package dev.selenium.interactions;

import org.junit.jupiter.api.Test;
import org.openqa.selenium.print.PageMargin;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.print.PageSize;
import dev.selenium.BaseChromeTest;

public class PrintOptionsTest extends BaseChromeTest {

    @Test
    public void TestOrientation() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setOrientation(PrintOptions.Orientation.LANDSCAPE);
        PrintOptions.Orientation current_orientation = printOptions.getOrientation();
    }

    @Test
    public void TestRange() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageRanges("1-2");
        String[] current_range = printOptions.getPageRanges();
    }

    @Test
    public void TestSize() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setPageSize(new PageSize(27.94, 21.59)); // A4 size in cm
        double currentHeight = printOptions.getPageSize().getHeight(); // use getWidth() to retrieve width
    }

    @Test
    public void TestMargins() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        PageMargin margins = new PageMargin(1.0,1.0,1.0,1.0);
        printOptions.setPageMargin(margins);
        double topMargin = margins.getTop();
        double bottomMargin = margins.getBottom();
        double leftMargin = margins.getLeft();
        double rightMargin = margins.getRight();
    }

    @Test
    public void TestScale() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setScale(.50);
        double current_scale = printOptions.getScale();
    }

    @Test
    public void TestBackground() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setBackground(true);
        boolean current_background = printOptions.getBackground();
    }

    @Test
    public void TestShrinkToFit() 
    {
        driver.get("https://www.selenium.dev/");
        PrintOptions printOptions = new PrintOptions();
        printOptions.setShrinkToFit(true);
        boolean current_shrink_to_fit = printOptions.getShrinkToFit();
    }
}
```

```cs
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L71-L78)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_print_options.py#L55-L57)

##### /examples/python/tests/interactions/test\_print\_options.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

@pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_orientation(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.orientation = "landscape" ## landscape or portrait
    assert print_options.orientation == "landscape"

def test_range(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_ranges = ["1, 2, 3"] ## ["1", "2", "3"] or ["1-3"]
    assert print_options.page_ranges == ["1, 2, 3"]

def test_size(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.page_height = 27.94  # Use page_width to assign width
    assert print_options.page_height == 27.94

def test_margin(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.margin_top = 10
    print_options.margin_bottom = 10
    print_options.margin_left = 10
    print_options.margin_right = 10
    assert print_options.margin_top == 10
    assert print_options.margin_bottom == 10
    assert print_options.margin_left == 10
    assert print_options.margin_right == 10

def test_scale(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.scale = 0.5 ## 0.1 to 2.0
    current_scale = print_options.scale
    assert current_scale == 0.5

def test_background(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.background = True ## True or False
    assert print_options.background is True

def test_shrink_to_fit(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    print_options.shrink_to_fit = True ## True or False
    assert print_options.shrink_to_fit is True
```

```java
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java#L27-L31)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.Pdf;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.PrintsPage;
import dev.selenium.BaseTest;

public class PrintsPageTest extends BaseTest{

    @BeforeEach
    public void setup() {
        ChromeOptions options = getDefaultChromeOptions();
        options.setCapability("webSocketUrl", true);
        driver = new ChromeDriver(options);
    }

    @Test
    public void PrintWithPrintsPageTest() 
    {
        driver.get("https://www.selenium.dev/");
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }

    @Test
    public void PrintWithBrowsingContextTest() 
    {
        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);
        Assertions.assertTrue(printPage.length() > 0);
    }
}
```

**BrowsingContext()**

```java
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
        PrintOptions printOptions = new PrintOptions();
        String printPage = browsingContext.print(printOptions);
        Assertions.assertTrue(printPage.length() > 0);
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java#L37-L41)

##### /examples/java/src/test/java/dev/selenium/interactions/PrintsPageTest.java

```java
package dev.selenium.interactions;

import org.openqa.selenium.Pdf;
import org.openqa.selenium.bidi.browsingcontext.BrowsingContext;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.openqa.selenium.print.PrintOptions;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.PrintsPage;
import dev.selenium.BaseTest;

public class PrintsPageTest extends BaseTest{

    @BeforeEach
    public void setup() {
        ChromeOptions options = getDefaultChromeOptions();
        options.setCapability("webSocketUrl", true);
        driver = new ChromeDriver(options);
    }

    @Test
    public void PrintWithPrintsPageTest() 
    {
        driver.get("https://www.selenium.dev/");
        PrintsPage printer = (PrintsPage) driver;
        PrintOptions printOptions = new PrintOptions();
        Pdf printedPage = printer.print(printOptions);
        Assertions.assertNotNull(printedPage);
    }

    @Test
    public void PrintWithBrowsingContextTest() 
    {
        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);
        Assertions.assertTrue(printPage.length() > 0);
    }
}
```

```cs
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs#L81-L88)

##### /examples/dotnet/SeleniumDocs/Interactions/PrintOptionsTest.cs

```cs
using System;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocumentation.SeleniumInteractions
{
    [TestClass]
    public class PrintOptionsTest
    {
        [TestMethod]
        public void TestOrientation()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.Orientation = PrintOrientation.Landscape;
            PrintOrientation currentOrientation = printOptions.Orientation;
            driver.Quit();
        }

        [TestMethod]
        public void TestRange()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://selenium.dev");
            PrintOptions printOptions  = new PrintOptions();
            printOptions.AddPageRangeToPrint("1-3"); // add range of pages
            printOptions.AddPageToPrint(5); // add individual page
            driver.Quit();
        }

        [TestMethod]
        public void TestSize()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.PageSize currentDimensions = printOptions.PageDimensions;
            driver.Quit();
        }

        [TestMethod]
        public void TestBackgrounds()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.OutputBackgroundImages = true;
            bool currentBackgrounds = printOptions.OutputBackgroundImages;
            driver.Quit();
        }

        [TestMethod]
        public void TestMargins()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintOptions.Margins currentMargins = printOptions.PageMargins;
            driver.Quit();
        }


        [TestMethod]
        public void TestScale()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ScaleFactor = 0.5;
            double currentScale = printOptions.ScaleFactor;
            driver.Quit();
        }

        [TestMethod]
        public void TestShrinkToFit()
        {
            IWebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            printOptions.ShrinkToFit = true;
            bool currentShrinkToFit = printOptions.ShrinkToFit;
            driver.Quit();
        }

        [TestMethod]
        public void PrintWithPrintsPageTest()
        {
            WebDriver driver = new ChromeDriver();
            driver.Navigate().GoToUrl("https://www.selenium.dev/");
            PrintOptions printOptions = new PrintOptions();
            PrintDocument printedPage = driver.Print(printOptions);
            Assert.IsTrue(printedPage.AsBase64EncodedString.StartsWith("JVBER"));
            driver.Quit();
        }
    }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

**print\_page()**

```py
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    pdf = driver.print_page(print_options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/interactions/test_prints_page.py#L12-L14)

##### /examples/python/tests/interactions/test\_prints\_page.py

```py
import pytest
from selenium import webdriver
from selenium.webdriver.common.print_page_options import PrintOptions

pytest.fixture()
def driver():
    driver = webdriver.Chrome()
    yield driver
    driver.quit()

def test_prints_page(driver):
    driver.get("https://www.selenium.dev/")
    print_options = PrintOptions()
    pdf = driver.print_page(print_options)
    assert len(pdf) > 0
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

----
url: https://www.selenium.dev/zh-cn/documentation/test_practices/encouraged/fresh_browser_per_test/
----

# 每次测试都刷新浏览器

每次测试都从一个干净的已知状态开始. 理想情况下, 为每次测试打开一个新的虚拟机. 如果打开新虚拟机不切实际, 则至少应为每次测试启动一个新的WebDriver. 对于Firefox, 请使用您已知的配置文件去启动WebDriver. 大多数浏览器驱动器，像GeckoDriver和ChromeDriver那样，默认都会以干净的已知状态和一个新的用户配置文件开始。

```java
WebDriver driver = new FirefoxDriver();
```

最后修改 November 20, 2022: [docs:Update zh-cn of Fresh browser per test page (#1237) (702d6e943c7)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/702d6e943c7bd7acb18a58314020ffd82bc025fd)

----
url: https://www.selenium.dev/zh-cn/documentation/webdriver/bidi/cdp/script/
----

# Chrome DevTools Script Features

```java
    ScriptKey key = ((JavascriptExecutor) driver).pin("return arguments;");
    List<Object> arguments =
        (List<Object>) ((JavascriptExecutor) driver).executeScript(key, 1, true, element);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/ScriptTest.java#L32-L34)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/ScriptTest.java

```java
package dev.selenium.bidi.cdp;

import static org.openqa.selenium.devtools.events.CdpEventTypes.domMutation;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;

import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.logging.HasLogEvents;
import org.openqa.selenium.support.ui.WebDriverWait;

public class ScriptTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void pinScript() {
    driver.get("https://www.selenium.dev/selenium/web/xhtmlTest.html");
    WebElement element = driver.findElement(By.id("id1"));

    ScriptKey key = ((JavascriptExecutor) driver).pin("return arguments;");
    List<Object> arguments =
        (List<Object>) ((JavascriptExecutor) driver).executeScript(key, 1, true, element);

    Assertions.assertEquals(List.of(1L, true, element), arguments);
  }

  @Test
  public void mutatedElements() {
    driver.get("https://www.selenium.dev/selenium/web/dynamic.html");
    CopyOnWriteArrayList<WebElement> mutations = new CopyOnWriteArrayList<>();

    ((HasLogEvents) driver).onLogEvent(domMutation(e -> mutations.add(e.getElement())));

    driver.findElement(By.id("reveal")).click();

    wait.until(_d -> !mutations.isEmpty());
    Assertions.assertEquals(mutations.get(0), driver.findElement(By.id("revealed")));
  }
}
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

```cs
            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs#L21-L22)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs

```cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class ScriptTest : BaseChromeTest
    {
        [TestMethod]
        public async Task PinScript()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/xhtmlTest.html";
            var element = driver.FindElement(By.Id("id1"));

            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);

            var expected = new List<object>
            {
                1L,
                true,
                element
            };
            CollectionAssert.AreEqual(expected, (ICollection)arguments);
        }

        [TestMethod]
        public async Task MutatedElements()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            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();

            driver.FindElement(By.Id("reveal")).Click();
            
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !mutations.IsNullOrEmpty());
            await monitor.DisableDomMutationMonitoring();
            monitor.StopEventMonitoring();

            var revealed = driver.FindElement(By.Id("revealed")); 
            Assert.AreEqual(revealed, mutations[0]);
        }
    }
}
```

```rb
    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/script_spec.rb#L12-L13)

##### /examples/ruby/spec/bidi/cdp/script\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Script' do
  let(:driver) { start_session }

  it 'pins script' do
    driver.get('https://www.selenium.dev/selenium/web/xhtmlTest.html')
    element = driver.find_element(id: 'id1')

    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)

    expect(arguments).to eq([1, true, element])
  end

  it 'gets mutated elements' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'

    mutations = []
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }

    driver.find_element(id: 'reveal').click
    Selenium::WebDriver::Wait.new(timeout: 30).until { mutations.any? }

    expect(mutations).to include(driver.find_element(id: 'revealed'))
  end
end
```

```java
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java#L44)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/NetworkTest.java

```java
package dev.selenium.bidi.cdp;

import com.google.common.net.MediaType;
import dev.selenium.BaseTest;
import java.net.*;
import java.time.Duration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Predicate;
import java.util.function.Supplier;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.*;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.devtools.DevTools;
import org.openqa.selenium.devtools.HasDevTools;
import org.openqa.selenium.devtools.NetworkInterceptor;
import org.openqa.selenium.devtools.v145.browser.Browser;
import org.openqa.selenium.devtools.v145.network.Network;
import org.openqa.selenium.devtools.v145.performance.Performance;
import org.openqa.selenium.devtools.v145.performance.model.Metric;
import org.openqa.selenium.remote.http.*;
import org.openqa.selenium.support.ui.WebDriverWait;

public class NetworkTest extends BaseTest {

  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
    wait = new WebDriverWait(driver, Duration.ofSeconds(10));
  }

  @Test
  public void basicAuthentication() {
    Predicate<URI> uriPredicate = uri -> uri.toString().contains("herokuapp.com");
    Supplier<Credentials> authentication = UsernameAndPassword.of("admin", "admin");
    ((HasAuthentication) driver).register(uriPredicate, authentication);

    driver.get("https://the-internet.herokuapp.com/basic_auth");

    String successMessage = "Congratulations! You must have the proper credentials.";
    WebElement elementMessage = driver.findElement(By.tagName("p"));
    Assertions.assertEquals(successMessage, elementMessage.getText());
  }

  @Test
  public void recordResponse() {
    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;
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
      wait.until(_d -> contentType.size() > 1);
    }

    Assertions.assertEquals("text/html; charset=utf-8", contentType.get(0));
  }

  @Test
  public void transformResponses() {
    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!"))))) {
      driver.get("https://www.selenium.dev/selenium/web/blank.html");
    }

    WebElement body = driver.findElement(By.tagName("body"));
    Assertions.assertEquals("Creamy, delicious cheese!", body.getText());
  }

  @Test
  public void interceptRequests() {
    AtomicBoolean completed = new AtomicBoolean(false);

    try (NetworkInterceptor ignored =
        new NetworkInterceptor(
            driver,
            (Filter)
                next ->
                    req -> {
                      if (req.getUri().contains("one.js")) {
                        req =
                            new HttpRequest(
                                HttpMethod.GET, req.getUri().replace("one.js", "two.js"));
                      }
                      completed.set(true);
                      return next.execute(req);
                    })) {
      driver.get("https://www.selenium.dev/selenium/web/devToolsRequestInterceptionTest.html");
      driver.findElement(By.tagName("button")).click();
    }

    Assertions.assertEquals("two", driver.findElement(By.id("result")).getText());
  }

  @Test
  public void performanceMetrics() {
    driver.get("https://www.selenium.dev/selenium/web/frameset.html");

    DevTools devTools = ((HasDevTools) driver).getDevTools();
    devTools.createSession();

    devTools.send(Performance.enable(Optional.empty()));
    List<Metric> metricList = devTools.send(Performance.getMetrics());

    Map<String, Number> metrics = new HashMap<>();
    for (Metric metric : metricList) {
      metrics.put(metric.getName(), metric.getValue());
    }

    Assertions.assertTrue(metrics.get("DevToolsCommandDuration").doubleValue() > 0);
    Assertions.assertEquals(12, metrics.get("Frames").intValue());
  }

  @Test
  public void setCookie() {
    DevTools 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()));

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }

  @Test
  public void waitForDownload() {
    driver.get("https://www.selenium.dev/selenium/web/downloads/download.html");

    DevTools 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.findElement(By.id("file-2")).click();

    Assertions.assertDoesNotThrow(() -> wait.until(_d -> completed));
  }
}
```

```py
    async with driver.bidi_connection() as session:
        async with Log(driver, session).mutation_events() as event:
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_script.py#L10-L11)

##### /examples/python/tests/bidi/cdp/test\_script.py

```py
import pytest
import trio
from selenium.webdriver.common.by import By
from selenium.webdriver.common.log import Log
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

@pytest.mark.trio
async def test_mutation(driver):
    async with driver.bidi_connection() as session:
        async with Log(driver, session).mutation_events() as event:
            await trio.to_thread.run_sync(lambda: driver.get('https://www.selenium.dev/selenium/web/dynamic.html'))
            await trio.to_thread.run_sync(lambda: WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.ID, "reveal"))))
            await trio.to_thread.run_sync(lambda: driver.find_element(By.ID, "reveal").click())

    assert event["element"] == driver.find_element(By.ID, "revealed")
```

```cs
            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();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs#L39-L46)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/ScriptTest.cs

```cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading.Tasks;
using Microsoft.IdentityModel.Tokens;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class ScriptTest : BaseChromeTest
    {
        [TestMethod]
        public async Task PinScript()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/xhtmlTest.html";
            var element = driver.FindElement(By.Id("id1"));

            var key = await new JavaScriptEngine(driver).PinScript("return arguments;");
            var arguments = ((WebDriver)driver).ExecuteScript(key, 1, true, element);

            var expected = new List<object>
            {
                1L,
                true,
                element
            };
            CollectionAssert.AreEqual(expected, (ICollection)arguments);
        }

        [TestMethod]
        public async Task MutatedElements()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/dynamic.html";
            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();

            driver.FindElement(By.Id("reveal")).Click();
            
            new WebDriverWait(driver, TimeSpan.FromSeconds(5)).Until(_ => !mutations.IsNullOrEmpty());
            await monitor.DisableDomMutationMonitoring();
            monitor.StopEventMonitoring();

            var revealed = driver.FindElement(By.Id("revealed")); 
            Assert.AreEqual(revealed, mutations[0]);
        }
    }
}
```

```rb
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/script_spec.rb#L22)

##### /examples/ruby/spec/bidi/cdp/script\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Script' do
  let(:driver) { start_session }

  it 'pins script' do
    driver.get('https://www.selenium.dev/selenium/web/xhtmlTest.html')
    element = driver.find_element(id: 'id1')

    key = driver.pin_script('return arguments;')
    arguments = driver.execute_script(key, 1, true, element)

    expect(arguments).to eq([1, true, element])
  end

  it 'gets mutated elements' do
    driver.get 'https://www.selenium.dev/selenium/web/dynamic.html'

    mutations = []
    driver.on_log_event(:mutation) { |mutation| mutations << mutation.element }

    driver.find_element(id: 'reveal').click
    Selenium::WebDriver::Wait.new(timeout: 30).until { mutations.any? }

    expect(mutations).to include(driver.find_element(id: 'revealed'))
  end
end
```

[Implementation Missing](https://github.com/SeleniumHQ/selenium)

[Add Example](/documentation/about/contributing/#creating-examples)

最后修改 November 5, 2024: [Add examples for Drivers HTTP Client in Java and Python (#2041) (2ce6752bfc8)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/2ce6752bfc8a0d1643519fbbe6934f903e33d097)

----
url: https://www.selenium.dev/pt-br/documentation/webdriver/drivers/options/
----

# Opções do navegador

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L73-74)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L79-80)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L11)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L80-82)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L86-88)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options.browser_version = 'latest'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L40)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

[Add Example](/documentation/about/contributing/#creating-examples)

[Add Example](/documentation/about/contributing/#creating-examples)

## pageLoadStrategy

Três tipos de estratégias de carregamento de página estão disponíveis.

A estratégia de carregamento da página consulta o [document.readyState](//developer.mozilla.org/en-US/docs/Web/API/Document/readyState) conforme descrito na tabela abaixo:

| Estratégia | Estado pronto | Notas                                                                                   |
| ---------- | ------------- | --------------------------------------------------------------------------------------- |
| normal     | completo      | Usado por padrão, aguarda o download de todos os recursos                               |
| ansioso    | interativo    | O acesso DOM está pronto, mas outros recursos como imagens ainda podem estar carregando |
| nenhum     | Qualquer      | Não bloqueia o WebDriver                                                                |

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L21-L23)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L7-9)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L13-14)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L11-L12)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L28-L34)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L34-L36)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L15-L17)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L29-30)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L20-L21)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L8-L14)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L47-L49)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L23-L25)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```cs
        [TestMethod]
        public void SetPageLoadStrategyNone()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs#L41-42)

##### /examples/dotnet/SeleniumDocs/Drivers/OptionsTest.cs

```cs
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.Drivers
{
    [TestClass]
    public class OptionsTest : BaseTest
    {
        [TestMethod]
        public void SetPageLoadStrategyNormal()
        {
            ChromeOptions chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Normal;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                // Navigate to Url
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyEager()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.Eager;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
        [TestMethod]
        public void SetPageLoadStrategyNone()
        {
            var chromeOptions = new ChromeOptions();
            chromeOptions.PageLoadStrategy = PageLoadStrategy.None;
            IWebDriver driver = new ChromeDriver(chromeOptions);
            try
            {
                driver.Navigate().GoToUrl("https://selenium.dev");
            }
            finally
            {
                driver.Quit();
            }
        }
    }
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L29-L30)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L18-L24)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```kotlin
import org.openqa.selenium.PageLoadStrategy
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

fun main() {
  val chromeOptions = ChromeOptions()
  chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE)
  val driver = ChromeDriver(chromeOptions)
  try {
    driver.get("https://www.google.com")
  }
  finally {
    driver.quit()
  }
}
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L88-L90)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L94-96)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L38-L39)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L60-L61)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L101-103)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L51-L52)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```js
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/capabilities/pageLoading.spec.js#L38-L41)

##### /examples/javascript/test/capabilities/pageLoading.spec.js

```js
const Chrome = require('selenium-webdriver/chrome');
const {Browser, Builder} = require("selenium-webdriver");
const options = new Chrome.Options()


describe('Page loading strategies', function () {
  it('Navigate using eager page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('eager'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using none page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('none'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Navigate using normal page loading strategy', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setPageLoadStrategy('normal'))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });

  it('Should be able to accept certs', async function () {
    let driver = new Builder()
      .forBrowser(Browser.CHROME)
      .setChromeOptions(options.setAcceptInsecureCerts(true))
      .build();

    await driver.get('https://www.selenium.dev/selenium/web/blank.html');
    await driver.quit();
  });
});
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L96-L98)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L30-32)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L114-L115)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L111-L113)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L37-39)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L105-L106)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L126-L128)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L44-46)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L96-L97)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L141-L142)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L51-53)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L60-L61)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L151-L152)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L58-60)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L69-L70)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java#L163-L164)

##### /examples/java/src/test/java/dev/selenium/drivers/OptionsTest.java

```java
package dev.selenium.drivers;

import dev.selenium.BaseTest;

import java.time.Duration;
import java.time.temporal.ChronoUnit;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.Assertions;
import org.openqa.selenium.PageLoadStrategy;
import org.openqa.selenium.UnexpectedAlertBehaviour;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeOptions;
import org.openqa.selenium.remote.CapabilityType;
import org.openqa.selenium.chrome.ChromeDriver;

public class OptionsTest extends BaseTest {

  @Test
  public void setPageLoadStrategyNormal() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NORMAL);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyEager() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.EAGER);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setPageLoadStrategyNone() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setPageLoadStrategy(PageLoadStrategy.NONE);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void setAcceptInsecureCerts() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setAcceptInsecureCerts(true);
    WebDriver driver = new ChromeDriver(chromeOptions);
    try {
      // Navigate to Url
      driver.get("https://selenium.dev");
    } finally {
      driver.quit();
    }
  }

  @Test
  public void getBrowserName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String name = chromeOptions.getBrowserName();
	Assertions.assertFalse(name.isEmpty(), "Browser name should not be empty");
  }

  @Test
  public void setBrowserVersion() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String version = "latest";
	chromeOptions.setBrowserVersion(version);
	Assertions.assertEquals(version, chromeOptions.getBrowserVersion());
  }

  @Test
  public void setPlatformName() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	String platform = "OS X 10.6";
	chromeOptions.setPlatformName(platform);
	Assertions.assertEquals(platform, chromeOptions.getPlatformName().toString());
  }

  @Test
  public void setScriptTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setScriptTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getScriptTimeout();
	  Assertions.assertEquals(timeout, duration, "The script timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setPageLoadTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setPageLoadTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getPageLoadTimeout();
	  Assertions.assertEquals(timeout, duration, "The page load timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setImplicitWaitTimeout() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	Duration duration = Duration.of(5, ChronoUnit.SECONDS);
	chromeOptions.setImplicitWaitTimeout(duration);

	WebDriver driver = new ChromeDriver(chromeOptions);
	try {
	  Duration timeout = driver.manage().timeouts().getImplicitWaitTimeout();
	  Assertions.assertEquals(timeout, duration, "The implicit wait timeout should be set to 5 seconds.");
	} finally {
	  driver.quit();
	}
  }

  @Test
  public void setUnhandledPromptBehaviour() {
	ChromeOptions chromeOptions = getDefaultChromeOptions();
	chromeOptions.setUnhandledPromptBehaviour(UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY);
	//verify the capability object is not null
	Object capabilityObject = chromeOptions.getCapability(CapabilityType.UNHANDLED_PROMPT_BEHAVIOUR);
	Assertions.assertNotNull(capabilityObject, "Capability UNHANDLED_PROMPT_BEHAVIOUR should not be null.");
	Assertions.assertEquals(capabilityObject.toString(), UnexpectedAlertBehaviour.DISMISS_AND_NOTIFY.toString());
  }

  @Test
  public void setWindowRect() {
   	ChromeOptions chromeOptions = getDefaultChromeOptions();
   	chromeOptions.setCapability(CapabilityType.SET_WINDOW_RECT, true);
   	//verify the capability object is not null
   	Object capabilityObject = chromeOptions.getCapability(CapabilityType.SET_WINDOW_RECT);
    Assertions.assertNotNull(capabilityObject, "Capability SET_WINDOW_RECT should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability SET_WINDOW_RECT should be set to true.");
  }
	
  @Test
  public void setStrictFileInteractability() {
    ChromeOptions chromeOptions = getDefaultChromeOptions();
    chromeOptions.setCapability(CapabilityType.STRICT_FILE_INTERACTABILITY, true);
	//verify the capability object is not null
    Object capabilityObject = chromeOptions.getCapability(CapabilityType.STRICT_FILE_INTERACTABILITY);
    Assertions.assertNotNull(capabilityObject, "Capability STRICT_FILE_INTERACTABILITY should not be null.");

    Boolean capability = (Boolean) capabilityObject;
    Assertions.assertTrue(capability, "The capability STRICT_FILE_INTERACTABILITY should be set to true.");
  }
}
```

```py
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L65-67)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

[Add Example](/documentation/about/contributing/#creating-examples)

```rb
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L78-L79)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```java
import org.openqa.selenium.Proxy;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chrome.ChromeOptions;

public class ProxyTest {
  public static void main(String[] args) {
    Proxy proxy = new Proxy();
    proxy.setHttpProxy("<HOST:PORT>");
    ChromeOptions options = new ChromeOptions();
    options.setCapability("proxy", proxy);
    WebDriver driver = new ChromeDriver(options);
    driver.get("https://www.google.com/");
    driver.manage().window().maximize();
    driver.quit();
  }
}
```

```py
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/drivers/test_options.py#L72-74)

##### /examples/python/tests/drivers/test\_options.py

```py
from selenium import webdriver
from selenium.webdriver.common.proxy import Proxy
from selenium.webdriver.common.proxy import ProxyType


def test_page_load_strategy_normal():
    options = get_default_chrome_options()
    options.page_load_strategy = 'normal'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_eager():
    options = get_default_chrome_options()
    options.page_load_strategy = 'eager'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()


def test_page_load_strategy_none():
    options = get_default_chrome_options()
    options.page_load_strategy = 'none'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_script():
    options = get_default_chrome_options()
    options.timeouts = { 'script': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_page_load():
    options = get_default_chrome_options()
    options.timeouts = { 'pageLoad': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_timeouts_implicit_wait():
    options = get_default_chrome_options()
    options.timeouts = { 'implicit': 5000 }
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_unhandled_prompt():
    options = get_default_chrome_options()
    options.unhandled_prompt_behavior = 'accept'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_set_window_rect():
    options = webdriver.FirefoxOptions()
    options.set_window_rect = True # Full support in Firefox
    driver = webdriver.Firefox(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_strict_file_interactability():
    options = get_default_chrome_options()
    options.strict_file_interactability = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def test_proxy():
    options = get_default_chrome_options()
    options.proxy = Proxy({ 'proxyType': ProxyType.MANUAL, 'httpProxy' : 'http.proxy:1234'})
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_name():
    options = get_default_chrome_options()
    assert options.capabilities['browserName'] == 'chrome'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_set_browser_version():
    options = get_default_chrome_options()
    options.browser_version = 'stable'
    assert options.capabilities['browserVersion'] == 'stable'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_platform_name():
    options = get_default_chrome_options()
    options.platform_name = 'any'
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()
    
def test_accept_insecure_certs():
    options = get_default_chrome_options()
    options.accept_insecure_certs = True
    driver = webdriver.Chrome(options=options)
    driver.get("https://www.selenium.dev/")
    driver.quit()

def get_default_chrome_options():
    options = webdriver.ChromeOptions()
    options.add_argument("--no-sandbox")
    return options
```

```csharp
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

public class ProxyTest{
public static void Main() {
ChromeOptions options = new ChromeOptions();
Proxy proxy = new Proxy();
proxy.Kind = ProxyKind.Manual;
proxy.IsAutoDetect = false;
proxy.SslProxy = "<HOST:PORT>";
options.Proxy = proxy;
options.AddArgument("ignore-certificate-errors");
IWebDriver driver = new ChromeDriver(options);
driver.Navigate().GoToUrl("https://www.selenium.dev/");
}
}
```

```rb
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/drivers/options_spec.rb#L87-L88)

##### /examples/ruby/spec/drivers/options\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Chrome' do
  describe 'Driver Options' do
    let(:chrome_location) { driver_finder && ENV.fetch('CHROME_BIN', nil) }
    let(:url) { 'https://www.selenium.dev/selenium/web/' }

    it 'page load strategy normal' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :normal

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy eager' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :eager

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'page load strategy none' do
      options = Selenium::WebDriver::Options.chrome
      options.page_load_strategy = :none

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets remote capabilities', skip: 'this is example code that will not execute' do
      options = Selenium::WebDriver::Options.firefox
      options.platform_name = 'Windows 10'
      options.browser_version = 'latest'
      cloud_options = {}
      cloud_options[:build] = my_test_build
      cloud_options[:name] = my_test_name
      options.add_option('cloud:options', cloud_options)
      driver = Selenium::WebDriver.for :remote, capabilities: options
      driver.get(url)
      driver.quit
    end

    it 'accepts untrusted certificates' do
      options = Selenium::WebDriver::Options.chrome
      options.accept_insecure_certs = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets unhandled prompt behavior' do
      options = Selenium::WebDriver::Options.chrome
      options.unhandled_prompt_behavior = :accept

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets window rect' do
      options = Selenium::WebDriver::Options.firefox
      options.set_window_rect = true

      driver = Selenium::WebDriver.for :firefox, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets strict file interactability' do
      options = Selenium::WebDriver::Options.chrome
      options.strict_file_interactability = true

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the proxy' do
      options = Selenium::WebDriver::Options.chrome
      options.proxy = Selenium::WebDriver::Proxy.new(http: 'myproxy.com:8080')

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the implicit timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {implicit: 1}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the page load timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {page_load: 400_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets the script timeout' do
      options = Selenium::WebDriver::Options.chrome
      options.timeouts = {script: 40_000}

      driver = Selenium::WebDriver.for :chrome, options: options
      driver.get(url)
      driver.quit
    end

    it 'sets capabilities in the pre-selenium 4 way', skip: 'this is example code that will not execute' do
      caps = Selenium::WebDriver::Remote::Capabilities.firefox
      caps[:platform] = 'Windows 10'
      caps[:version] = '92'
      caps[:build] = my_test_build
      caps[:name] = my_test_name
      driver = Selenium::WebDriver.for :remote, url: cloud_url, desired_capabilities: caps
      driver.get(url)
      driver.quit
    end
  end
end
```

```javascript
let webdriver = require('selenium-webdriver');
let chrome = require('selenium-webdriver/chrome');
let proxy = require('selenium-webdriver/proxy');
let opts = new chrome.Options();

(async function example() {
opts.setProxy(proxy.manual({http: '<HOST:PORT>'}));
let driver = new webdriver.Builder()
.forBrowser('chrome')
.setChromeOptions(opts)
.build();
try {
await driver.get("https://selenium.dev");
}
finally {
await driver.quit();
}
}());
```

```kotlin
import org.openqa.selenium.Proxy
import org.openqa.selenium.WebDriver
import org.openqa.selenium.chrome.ChromeDriver
import org.openqa.selenium.chrome.ChromeOptions

class proxyTest {
fun main() {

        val proxy = Proxy()
        proxy.setHttpProxy("<HOST:PORT>")
        val options = ChromeOptions()
        options.setCapability("proxy", proxy)
        val driver: WebDriver = ChromeDriver(options)
        driver["https://www.google.com/"]
        driver.manage().window().maximize()
        driver.quit()
    }
}
```

----
url: https://www.selenium.dev/ja/documentation/webdriver/support_features/select_lists/
----

# 選択要素の操作

```html
<select name="selectomatic">
    <option selected="selected" id="non_multi_option" value="one">One</option>
    <option value="two">Two</option>
    <option value="four">Four</option>
    <option value="still learning how to count, apparently">Still learning how to count, apparently</option>
</select>
```

### Multiple select

This select list allows selecting and deselecting more than one option at a time. This only applies to `<select>` elements with the `multiple` attribute.

```html
<select name="multi" id="multi" multiple="multiple">
    <option selected="selected" value="eggs">Eggs</option>
    <option value="ham">Ham</option>
    <option selected="selected" value="sausages">Sausages</option>
    <option value="onion gravy">Onion gravy</option>
</select>
```

```java
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L23-L24)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L9-L10)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L23-L24)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L13-L14)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js

  it('Select an option', async function () {
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L18-L19)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L20-L21)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        List<WebElement> optionList = select.getOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L51)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    option_list = select.options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L37)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            IList<IWebElement> optionList = select.Options;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L52)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    option_list = select.options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L40)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L45)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val optionList = select.getOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L48)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L54)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    selected_option_list = select.all_selected_options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L40)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L56)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    selected_option_list = select.selected_options
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L43)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L51)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    val selectedOptionList = select.getAllSelectedOptions()
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L51)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByVisibleText("Four");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L30)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_visible_text('Four')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L16)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByText("Four");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L30)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:text, 'Four')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L20)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L25)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByVisibleText("Four")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L27)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByValue("two");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L33)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_value('two')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L19)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByValue("two");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L33)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:value, 'two')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L23)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await fourElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L28)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByValue("two")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L30)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.selectByIndex(3);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L36)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.select_by_index(3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L22)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.SelectByIndex(3);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L36)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.select_by(:index, 3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L26)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await twoElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L31)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.selectByIndex(3)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L33)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

### Disabled options

[Selenium v4.5](https://github.com/SeleniumHQ/selenium/releases/tag/selenium-4.5.0)

Options with a `disabled` attribute may not be selected.

```html
    <select name="single_disabled">
      <option id="sinlge_disabled_1" value="enabled">Enabled</option>
      <option id="sinlge_disabled_2" value="disabled" disabled="disabled">Disabled</option>
    </select>
```

*
*
*
*
*
*

```java
        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L77-L79)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L60-L61)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L77)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L62-L64)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L73-L76)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L74-L76)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

```java
        select.deselectByValue("eggs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/support/SelectListTest.java#L66)

##### /examples/java/src/test/java/dev/selenium/support/SelectListTest.java

```java
package dev.selenium.support;

import dev.selenium.BaseChromeTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.By;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.support.ui.Select;

import java.util.ArrayList;
import java.util.List;

public class SelectListTest extends BaseChromeTest {

    @BeforeEach
    public void navigate() {
        driver.get("https://www.selenium.dev/selenium/web/formPage.html");
    }

    @Test
    public void selectOption() {
        WebElement selectElement = driver.findElement(By.name("selectomatic"));
        Select select = new Select(selectElement);

        WebElement twoElement = driver.findElement(By.cssSelector("option[value=two]"));
        WebElement fourElement = driver.findElement(By.cssSelector("option[value=four]"));
        WebElement countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"));

        select.selectByVisibleText("Four");
        Assertions.assertTrue(fourElement.isSelected());

        select.selectByValue("two");
        Assertions.assertTrue(twoElement.isSelected());

        select.selectByIndex(3);
        Assertions.assertTrue(countElement.isSelected());
    }

    @Test
    public void selectMultipleOption() {
        WebElement selectElement = driver.findElement(By.name("multi"));
        Select select = new Select(selectElement);

        WebElement hamElement = driver.findElement(By.cssSelector("option[value=ham]"));
        WebElement gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"));
        WebElement eggElement = driver.findElement(By.cssSelector("option[value=eggs]"));
        WebElement sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"));

        List<WebElement> optionElements = selectElement.findElements(By.tagName("option"));
        List<WebElement> optionList = select.getOptions();
        Assertions.assertEquals(optionElements, optionList);

        List<WebElement> selectedOptionList = select.getAllSelectedOptions();
        List<WebElement> expectedSelection = new ArrayList<WebElement>() {{
            add(eggElement);
            add(sausageElement);
        }};
        Assertions.assertEquals(expectedSelection, selectedOptionList);

        select.selectByValue("ham");
        select.selectByValue("onion gravy");
        Assertions.assertTrue(hamElement.isSelected());
        Assertions.assertTrue(gravyElement.isSelected());

        select.deselectByValue("eggs");
        select.deselectByValue("sausages");
        Assertions.assertFalse(eggElement.isSelected());
        Assertions.assertFalse(sausageElement.isSelected());
    }

    @Test
    public void disabledOption() {
        WebElement selectElement = driver.findElement(By.name("single_disabled"));
        Select select = new Select(selectElement);

        Assertions.assertThrows(UnsupportedOperationException.class, () -> {
            select.selectByValue("disabled");
        });
    }
}
```

```py
    select.deselect_by_value('eggs')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/support/test_select_list.py#L49)

##### /examples/python/tests/support/test\_select\_list.py

```py
import pytest
from selenium.webdriver.common.by import By
from selenium.webdriver.support.select import Select


def test_select_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'selectomatic')
    select = Select(select_element)

    two_element = driver.find_element(By.CSS_SELECTOR, 'option[value=two]')
    four_element = driver.find_element(By.CSS_SELECTOR, 'option[value=four]')
    count_element = driver.find_element(By.CSS_SELECTOR, "option[value='still learning how to count, apparently']")

    select.select_by_visible_text('Four')
    assert four_element.is_selected()

    select.select_by_value('two')
    assert two_element.is_selected()

    select.select_by_index(3)
    assert count_element.is_selected()


def test_select_multiple_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')
    select_element = driver.find_element(By.NAME, 'multi')
    select = Select(select_element)

    ham_element = driver.find_element(By.CSS_SELECTOR, 'option[value=ham]')
    gravy_element = driver.find_element(By.CSS_SELECTOR, "option[value='onion gravy']")
    egg_element = driver.find_element(By.CSS_SELECTOR, 'option[value=eggs]')
    sausage_element = driver.find_element(By.CSS_SELECTOR, "option[value='sausages']")

    option_elements = select_element.find_elements(By.TAG_NAME, 'option')
    option_list = select.options
    assert option_elements == option_list

    selected_option_list = select.all_selected_options
    expected_selection = [egg_element, sausage_element]
    assert selected_option_list == expected_selection

    select.select_by_value('ham')
    select.select_by_value('onion gravy')
    assert ham_element.is_selected()
    assert gravy_element.is_selected()

    select.deselect_by_value('eggs')
    select.deselect_by_value('sausages')
    assert not egg_element.is_selected()
    assert not sausage_element.is_selected()

def test_disabled_options(driver):
    driver.get('https://selenium.dev/selenium/web/formPage.html')

    select_element = driver.find_element(By.NAME, 'single_disabled')
    select = Select(select_element)

    with pytest.raises(NotImplementedError):
        select.select_by_value('disabled')
```

```cs
            select.DeselectByValue("eggs");
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/Support/SelectListTest.cs#L65)

##### /examples/dotnet/SeleniumDocs/Support/SelectListTest.cs

```cs
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Support.UI;

namespace SeleniumDocs.Support
{
    [TestClass]
    public class SelectListTest : BaseChromeTest
    {
        [TestInitialize]
        public void Navigate()
        {
            driver.Url = "https://www.selenium.dev/selenium/web/formPage.html";
        }

        [TestMethod]
        public void SelectOption()
        {
            var selectElement = driver.FindElement(By.Name("selectomatic"));
            var select = new SelectElement(selectElement);

            var twoElement = driver.FindElement(By.CssSelector("option[value=two]"));
            var fourElement = driver.FindElement(By.CssSelector("option[value=four]"));
            var countElement = driver.FindElement(By.CssSelector("option[value='still learning how to count, apparently']"));

            select.SelectByText("Four");
            Assert.IsTrue(fourElement.Selected);

            select.SelectByValue("two");
            Assert.IsTrue(twoElement.Selected);

            select.SelectByIndex(3);
            Assert.IsTrue(countElement.Selected);

        }

        [TestMethod]
        public void SelectMultipleOption()
        {
            var selectElement = driver.FindElement(By.Name("multi"));
            var select = new SelectElement(selectElement);

            var hamElement = driver.FindElement(By.CssSelector("option[value=ham]"));
            var gravyElement = driver.FindElement(By.CssSelector("option[value='onion gravy']"));
            var eggElement = driver.FindElement(By.CssSelector("option[value=eggs]"));
            var sausageElement = driver.FindElement(By.CssSelector("option[value='sausages']"));

            IList<IWebElement> optionList = select.Options;
            IWebElement[] optionElements = selectElement.FindElements(By.TagName("option")).ToArray();
            CollectionAssert.AreEqual(optionElements, optionList.ToArray());

            IList<IWebElement> selectedOptionList = select.AllSelectedOptions;
            IWebElement[] expectedSelection = { eggElement, sausageElement };
            CollectionAssert.AreEqual(expectedSelection, selectedOptionList.ToArray());

            select.SelectByValue("ham");
            select.SelectByValue("onion gravy");
            Assert.IsTrue(hamElement.Selected);
            Assert.IsTrue(gravyElement.Selected);

            select.DeselectByValue("eggs");
            select.DeselectByValue("sausages");
            Assert.IsFalse(eggElement.Selected);
            Assert.IsFalse(sausageElement.Selected);
        }

        [TestMethod]
        public void DisabledOption()
        {
            var selectElement = driver.FindElement(By.Name("single_disabled"));
            var select = new SelectElement(selectElement);

            Assert.ThrowsException<InvalidOperationException>(() => select.SelectByValue("disabled"));
        }
    }
}
```

```rb
    select.deselect_by(:value, 'eggs')
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/support/select_list_spec.rb#L52)

##### /examples/ruby/spec/support/select\_list\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Select List' do
  let(:driver) { start_session }

  before do
    driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  end

  it 'select options' do
    select_element = driver.find_element(name: 'selectomatic')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    two_element = driver.find_element(css: 'option[value=two]')
    four_element = driver.find_element(css: 'option[value=four]')
    count_element = driver.find_element(css: "option[value='still learning how to count, apparently']")

    select.select_by(:text, 'Four')
    expect(four_element).to be_selected

    select.select_by(:value, 'two')
    expect(two_element).to be_selected

    select.select_by(:index, 3)
    expect(count_element).to be_selected
  end

  it 'select multiple options' do
    select_element = driver.find_element(name: 'multi')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    ham_element = driver.find_element(css: 'option[value=ham]')
    gravy_element = driver.find_element(css: "option[value='onion gravy']")
    egg_element = driver.find_element(css: 'option[value=eggs]')
    sausage_element = driver.find_element(css: "option[value='sausages']")

    option_elements = select_element.find_elements(tag_name: 'option')
    option_list = select.options
    expect(option_elements).to eq option_list

    selected_option_list = select.selected_options
    expected_selection = [egg_element, sausage_element]
    expect(selected_option_list).to eq expected_selection

    select.select_by(:value, 'ham')
    select.select_by(:value, 'onion gravy')
    expect(ham_element).to be_selected
    expect(gravy_element).to be_selected

    select.deselect_by(:value, 'eggs')
    select.deselect_by(:value, 'sausages')
    expect(egg_element).not_to be_selected
    expect(sausage_element).not_to be_selected
  end

  it 'disabled options' do
    select_element = driver.find_element(name: 'single_disabled')
    select = Selenium::WebDriver::Support::Select.new(select_element)

    expect {
      select.select_by(:value, 'disabled')
    }.to raise_exception(Selenium::WebDriver::Error::UnsupportedOperationError)
  end
end
```

```js
    assert.equal(true, await gravyElement.isSelected())
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/javascript/test/select/selectListTest.spec.js#L63)

##### /examples/javascript/test/select/selectListTest.spec.js

```js

const {By, Browser, Builder} = require('selenium-webdriver')
const assert = require('assert/strict')
const {Select} = require('selenium-webdriver')


describe('Select Tests', async function () {
  let driver

  before(async function () {
    driver = new Builder()
      .forBrowser(Browser.FIREFOX)
      .build()
    await driver.get('https://www.selenium.dev/selenium/web/formPage.html')
  })

  after(async () => await driver.quit())

  it('Select an option', async function () {
    const selectElement = await driver.findElement(By.name('selectomatic'))
    const select = new Select(selectElement)

    const twoElement = await driver.findElement(By.css('option[value=two]'))
    const fourElement = await driver.findElement(By.css('option[value=four]'))
    const countElement = await driver.findElement(By.css("option[value='still learning how to count, apparently']"))

    await select.selectByVisibleText('Four')
    assert.equal(true, await fourElement.isSelected())

    await select.selectByValue('two')
    assert.equal(true, await twoElement.isSelected())

    await select.selectByIndex(3)
    assert.equal(true, await countElement.isSelected())
  })

  it('Select by multiple options', async function () {
    const selectElement = await driver.findElement(By.name('multi'))
    const select = await new Select(selectElement)

    const hamElement = await driver.findElement(By.css('option[value=ham]'))
    const gravyElement = await driver.findElement(By.css("option[value='onion gravy']"))
    const eggElement = await driver.findElement(By.css('option[value=eggs]'))
    const sausageElement = await driver.findElement(By.css("option[value='sausages']"))

    const optionElements = await selectElement.findElements(By.css('option'))
    const optionList = await select.getOptions()
    assert.equal(optionList.length, optionElements.length)
    for (const index in optionList) {
      assert.equal(await optionList[index].getText(), await optionElements[index].getText())
    }

    const selectedOptionList = await select.getAllSelectedOptions()
    const expectedSelection = [eggElement, sausageElement]
    assert.equal(expectedSelection.length, selectedOptionList.length)
    for (const index in selectedOptionList) {
      assert.equal(await selectedOptionList[index].getText(), await expectedSelection[index].getText())
    }

    await select.selectByValue('ham')
    await select.selectByValue('onion gravy')
    assert.equal(true, await hamElement.isSelected())
    assert.equal(true, await gravyElement.isSelected())

    await select.deselectByValue('eggs')
    await select.deselectByValue('sausages')
    assert.equal(false, await eggElement.isSelected())
    assert.equal(false, await sausageElement.isSelected())
  })

  it('Try selecting disabled option', async function () {
    const selectElement = await driver.findElement(By.name('single_disabled'))
    const select = await new Select(selectElement)

    await assert.rejects(async () => {
      await select.selectByValue("disabled")
    }, {
      name: 'UnsupportedOperationError',
      message: 'You may not select a disabled option'
    })
  })
})
```

```kt
    select.deselectByValue("eggs")
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt#L63)

##### /examples/kotlin/src/test/kotlin/dev/selenium/support/SelectListTest.kt

```kt
package dev.selenium.support

import dev.selenium.BaseTest
import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.BeforeEach
import org.junit.jupiter.api.Test
import org.openqa.selenium.By
import org.openqa.selenium.WebElement
import org.openqa.selenium.support.ui.Select

class SelectListTest : BaseTest() {
  
  @BeforeEach
  fun navigate() {
    driver.get("https://www.selenium.dev/selenium/web/formPage.html")
  }
  
  @Test
  fun selectOption() {
    val selectElement = driver.findElement(By.name("selectomatic"))
    val select = Select(selectElement)
    
    val twoElement = driver.findElement(By.cssSelector("option[value=two]"))
    val fourElement = driver.findElement(By.cssSelector("option[value=four]"))
    val countElement = driver.findElement(By.cssSelector("option[value='still learning how to count, apparently']"))
    
    select.selectByVisibleText("Four")
    Assertions.assertTrue(fourElement.isSelected())

    select.selectByValue("two")
    Assertions.assertTrue(twoElement.isSelected())

    select.selectByIndex(3)
    Assertions.assertTrue(countElement.isSelected())
  }
  
  @Test
  fun selectMultipleOption() {
    val selectElement = driver.findElement(By.name("multi"))
    val select = Select(selectElement)
    
    val hamElement = driver.findElement(By.cssSelector("option[value=ham]"))
    val gravyElement = driver.findElement(By.cssSelector("option[value='onion gravy']"))
    val eggElement = driver.findElement(By.cssSelector("option[value=eggs]"))
    val sausageElement = driver.findElement(By.cssSelector("option[value='sausages']"))

    val optionElements = selectElement.findElements(By.tagName("option"))
    val optionList = select.getOptions()
    Assertions.assertEquals(optionElements, optionList)

    val selectedOptionList = select.getAllSelectedOptions()
    val expectedSelection = ArrayList<WebElement>() 
      expectedSelection.add(eggElement)
      expectedSelection.add(sausageElement)

    Assertions.assertEquals(expectedSelection, selectedOptionList)

    select.selectByValue("ham")
    select.selectByValue("onion gravy")
    Assertions.assertTrue(hamElement.isSelected())
    Assertions.assertTrue(gravyElement.isSelected())

    select.deselectByValue("eggs")
    select.deselectByValue("sausages")
    Assertions.assertFalse(eggElement.isSelected())
    Assertions.assertFalse(sausageElement.isSelected())
  }

  @Test
  fun disabledOption() {
    val selectElement = driver.findElement(By.name("single_disabled"))
    val select = Select(selectElement)
    
    Assertions.assertThrows(UnsupportedOperationException::class.java) {
      select.selectByValue("disabled")
    }
  }
}
```

----
url: https://www.selenium.dev/documentation/test_practices/encouraged/locators/
----

# Tips on working with locators

Last modified February 10, 2022: [#891 Update locators (#947) \[deploy site\] (f39d357da08)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/f39d357da08a64c9dc00e3be29c6c369729482bb)

----
url: https://www.selenium.dev/pt-br/documentation/about/contributing/
----

# Contribuindo com o Site e Documentação do Selenium

Informações em como melhorar a documentação e exemplos de código para Selenium.

Selenium é um grande projeto de software, seu site e documentação são fundamentais para entender como as coisas funcionam e aprender maneiras eficazes de explorar seu potencial.

Este projeto contém o site e a documentação do Selenium. Isto é um esforço contínuo (não direcionado a nenhuma versão específica) para fornecer informações atualizadas sobre como usar o Selenium de forma eficaz, como se envolver e como contribuir para o Selenium.

As contribuições para o site e documentação seguem o processo descrito na seção abaixo sobre contribuições.

***

```
    {{< tab header="Ruby" >}}
    {{< gh-codeblock path="/examples/ruby/spec/browsers/chrome_spec.rb#L8-L9" >}}
    {{< /tab >}}
```

```shell
% git clone git@github.com:seleniumhq/seleniumhq.github.io.git
% cd seleniumhq.github.io
```

#### Dependências: Hugo

Usamos [Hugo](https://gohugo.io/) e [Docsy theme](https://www.docsy.dev/) para criar e gerar o website. Você vai necessitar de usar a versão “extended” Sass/SCSS do binário Hugo. Recomendamos a versão 0.148.2 .

Por favor siga as instruções do Docsy [Install Hugo](https://www.docsy.dev/docs/getting-started/#install-hugo)

### Passo 2: Branch

Crie uma branch e comece a hackear:

```shell
% git checkout -b my-feature-branch
```

Praticamos o desenvolvimento baseado em HEAD, o que significa que todas as mudanças são aplicadas diretamente no topo do `dev`.

### Passo 3: Faça mudanças

O repositório contém o website e a documentação. Antes de começar a alterar coisas, por favor veja o resto dos passos para preparar as dependências e sub-módulos (veja os comandos abaixo).

Para fazer alterações ao website, trabalha na pasta `website_and_docs`. Para ver uma previsão do aspecto do website, execute `hugo server` a partir da raíz do projecto.

```shell
% git submodule update --init --recursive
% cd website_and_docs
% hugo server
```

See [Style Guide](https://www.selenium.dev/pt-br/documentation/about/style/) for more information on our conventions for contribution

### Passo 4: Commit

Primeiro, certifique-se de que o git saiba seu nome e endereço de e-mail:

```shell
% git config --global user.name 'Santa Claus'
% git config --global user.email 'santa@example.com'
```

**Escrever boas mensagens de commit é importante.** Uma mensagem de confirmação deve descrever o que mudou, por que e conter referência de problemas corrigidos (se houver). Siga estas diretrizes ao escrever um:

1. A primeira linha deve ter cerca de 50 caracteres ou menos e conter uma breve da descrição da mudança.
2. Mantenha a segunda linha em branco.
3. Quebra todas as outras linhas em 72 colunas.
4. Incluir `Fixes # N`, onde *N* é o número do problema que o commit corrige se houver.

Uma boa mensagem de confirmação pode ter a seguinte aparência:

```text
explain commit normatively in one line

Body of commit message is a few lines of text, explaining things
in more detail, possibly giving some background about the issue
being fixed, etc.

The body of the commit message can be several paragraphs, and
please do proper word-wrap and keep columns shorter than about
72 characters or so. That way `git log` will show things
nicely even when it is indented.

Fixes #141
```

A primeira linha deve ser significativa, pois é o que as pessoas veem quando executam `git shortlog` ou` git log --oneline`.

### Passo 5: Rebase

Use `git rebase` (não `git merge`) para sincronizar seu trabalho de tempos em tempos.

```shell
% git fetch origin
% git rebase origin/trunk
```

### Passo 6: Teste

Lembre-se sempre de [executar o servidor local](https://gohugo.io/getting-started/usage/#livereload), com isso, você pode ter certeza de que suas alterações não prejudicaram nada.

### Passo 7: Push

```shell
% git push origin my-feature-branch
```

Acesse <https://github.com/yourusername/seleniumhq.github.io.git> e clique em *Pull Request* e preencha o formulário. **Por favor indique que você assinou o CLA** (consulte a Etapa 7).

Os Pull Requests geralmente são revisados em alguns dias. Se houver comentários a abordar, aplique suas alterações em novos commits (de preferência [fixups](http://git-scm.com/docs/git-commit)) e envie para a mesma branch.

### Passo 8: Integração

Quando a revisão do código for concluída, um committer integrará seu PR no branch de tronco do repositório. Porque gostamos de manter um histórico linear no `trunk`, nós normalmente iremos dar Squash & Rebase no histórico da sua branch.

## Comunicação

Todos os detalhes sobre como se comunicar com os colaboradores do projeto e a comunidade em geral podem ser encontrados em <https://selenium.dev/support>

Última modificação November 4, 2025: [added information about web examples for english document (#2492) (4dc5f22359d)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/4dc5f22359dfceb83b43afb473ca2ef7882abd19)

----
url: https://www.selenium.dev/zh-cn/documentation/legacy/selenium_ide/html_runner/
----

# HTML runner

```shell
[user@localhost ~]$ cat /etc/redhat-release
CentOS Linux release 7.4.1708 (Core)

[user@localhost ~]$ rpm -qa | egrep -i "xvfb|java-1.8|firefox"
xorg-x11-server-Xvfb-1.19.3-11.el7.x86_64
firefox-52.4.0-1.el7.centos.x86_64
java-1.8.0-openjdk-1.8.0.151-1.b12.el7_4.x86_64
java-1.8.0-openjdk-headless-1.8.0.151-1.b12.el7_4.x86_64
```

Test Suite 示例：

```html
[user@localhost ~]$ cat testsuite.html
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta content="text/html; charset=UTF-8" http-equiv="content-type" />
  <title>Test Suite</title>
</head>
<body>
<table id="suiteTable" cellpadding="1" cellspacing="1" border="1" class="selenium"><tbody>
<tr><td><b>Test Suite</b></td></tr>
<tr><td><a href="YOUR-TEST-SCENARIO.html">YOUR-TEST-SCENARIO</a></td></tr>
</tbody></table>
</body>
</html>
```

## 如何运行 selenium-html-runner headless

现在，最重要的部分，一个如何运行 selenium-html-runner 的例子！ 您的体验可能因软件组合而异 - geckodriver / FF / html-runner 版本。

```shell
xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
```

```shell
[user@localhost ~]$ xvfb-run java -Dwebdriver.gecko.driver=/home/mmasek/geckodriver.0.18.0 -jar selenium-html-runner-3.7.1.jar -htmlSuite "*firefox" "https://YOUR-BASE-URL" "$(pwd)/testsuite.html" "results.html" ; grep result: -A1 results.html/firefox.results.html
Multi-window mode is longer used as an option and will be ignored.
1510061109691   geckodriver     INFO    geckodriver 0.18.0
1510061109708   geckodriver     INFO    Listening on 127.0.0.1:2885
1510061110162   geckodriver::marionette INFO    Starting browser /usr/bin/firefox with args ["-marionette"]
1510061111084   Marionette      INFO    Listening on port 43229
1510061111187   Marionette      WARN    TLS certificate errors will be ignored for this session
Nov 07, 2017 1:25:12 PM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: W3C
2017-11-07 13:25:12.714:INFO::main: Logging initialized @3915ms to org.seleniumhq.jetty9.util.log.StdErrLog
2017-11-07 13:25:12.804:INFO:osjs.Server:main: jetty-9.4.z-SNAPSHOT
2017-11-07 13:25:12.822:INFO:osjsh.ContextHandler:main: Started o.s.j.s.h.ContextHandler@87a85e1{/tests,null,AVAILABLE}
2017-11-07 13:25:12.843:INFO:osjs.AbstractConnector:main: Started ServerConnector@52102734{HTTP/1.1,[http/1.1]}{0.0.0.0:31892}
2017-11-07 13:25:12.843:INFO:osjs.Server:main: Started @4045ms
Nov 07, 2017 1:25:13 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |open | /auth_mellon.php |  |
Nov 07, 2017 1:25:14 PM org.openqa.selenium.server.htmlrunner.CoreTestCase run
INFO: |waitForPageToLoad | 3000 |  |
.
.
.etc

<td>result:</td>
<td>PASS</td>
```

----
url: https://www.selenium.dev/ja/documentation/test_practices/encouraged/consider_using_a_fluent_api/
----

# Fluent APIの使用を検討する

マーチン・ファウラーは[“Fluent API”](//www.martinfowler.com/bliki/FluentInterface.html)という用語を作り出しました。 Seleniumは既に、`FluentWait`クラスでこのようなものを実装しています。 これは、標準の`Wait`クラスの代替としてのものです。 ページオブジェクトでFluent APIデザインパターンを有効にしてから、次のようなコードスニペットを使用してGoogle検索ページを照会できます。

```java
driver.get( "http://www.google.com/webhp?hl=en&amp;tab=ww" );
GoogleSearchPage gsp = new GoogleSearchPage(driver);
gsp.setSearchString().clickSearchButton();
```

この流暢な動作を持つGoogleページオブジェクトクラスは次のようになります。

```java
public abstract class BasePage {
    protected WebDriver driver;

    public BasePage(WebDriver driver) {
        this.driver = driver;
    }
}

public class GoogleSearchPage extends BasePage {
    public GoogleSearchPage(WebDriver driver) {
        super(driver);
        // Generally do not assert within pages or components.
        // Effectively throws an exception if the lambda condition is not met.
        new WebDriverWait(driver, Duration.ofSeconds(3)).until(d -> d.findElement(By.id("logo")));
    }

    public GoogleSearchPage setSearchString(String sstr) {
        driver.findElement(By.id("gbqfq")).sendKeys(sstr);
        return this;
    }

    public void clickSearchButton() {
        driver.findElement(By.id("gbqfb")).click();
    }
}
```

最終更新 May 17, 2023: [Consider Using a Fluent API - Fix usage (#1378) (332da70d909)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/332da70d90970623288d2e98fbcff098b7812995)

----
url: https://www.selenium.dev/_print/documentation/webdriver/troubleshooting/errors/
----

This is the multi-page printable view of this section. [Click here to print](#).

[Return to the regular view of this page](/documentation/webdriver/troubleshooting/errors/).

# Understanding Common Errors

How to solve various problems in your Selenium code.

* 1: [Unable to Locate Driver Error](#pg-5a7d28a8d143d2eaa2a6727d561e2164)

* Make sure you are using a proper [Waiting Strategy](https://www.selenium.dev/documentation/webdriver/waits/)

[Explicit Waits](https://www.selenium.dev/documentation/webdriver/waits/) will likely be your best friend in these instances. A great way is to use `ExpectedCondition.ToBeClickable()` with `WebDriverWait` to wait until the right moment.

As of Selenium 4.6, Selenium downloads the correct driver for you. You shouldn’t need to do anything. If you are using the latest version of Selenium and you are getting an error, please [turn on logging](https://www.selenium.dev/documentation/webdriver/troubleshooting/logging/) and [file a bug report](//github.com/seleniumhq/selenium/issues) with that information.

If you want to read more information about how Selenium manages driver downloads for you, you can read about the [Selenium Manager](https://www.selenium.dev/documentation/selenium_manager/).

### Use the `PATH` environment variable

This option first requires manually [downloading the driver](/documentation/webdriver/troubleshooting/errors/driver_location/#download-the-driver).

This is a flexible option to change location of drivers without having to update your code, and will work on multiple machines without requiring that each machine put the drivers in the same place.

You can either place the drivers in a directory that is already listed in `PATH`, or you can place them in a directory and add it to `PATH`.

*
*
*

To see what directories are already on `PATH`, open a Terminal and execute:

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.bash_profile
source ~/.bash_profile
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Terminal and execute:

```shell
echo $PATH
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
echo 'export PATH=$PATH:/path/to/driver' >> ~/.zshenv
source ~/.zshenv
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver --version
```

To see what directories are already on `PATH`, open a Command Prompt and execute:

```shell
echo %PATH%
```

If the location to your driver is not already in a directory listed, you can add a new directory to PATH:

```shell
setx PATH "%PATH%;C:\WebDriver\bin"
```

You can test if it has been added correctly by checking the version of the driver:

```shell
chromedriver.exe --version
```

| Browser           | Supported OS                | Maintained by    | Download                                                                     | Issue Tracker                                             |
| ----------------- | --------------------------- | ---------------- | ---------------------------------------------------------------------------- | --------------------------------------------------------- |
| Chromium/Chrome   | Windows/macOS/Linux         | Google           | [Downloads](/downloads/)                                                     | [Issues](//bugs.chromium.org/p/chromedriver/issues/list)  |
| Firefox           | Windows/macOS/Linux         | Mozilla          | [Downloads](//github.com/mozilla/geckodriver/releases)                       | [Issues](//github.com/mozilla/geckodriver/issues)         |
| Edge              | Windows/macOS/Linux         | Microsoft        | [Downloads](//developer.microsoft.com/en-us/microsoft-edge/tools/webdriver/) | [Issues](//github.com/MicrosoftEdge/EdgeWebDriver/issues) |
| Internet Explorer | Windows                     | Selenium Project | [Downloads](/downloads/)                                                     | [Issues](//github.com/SeleniumHQ/selenium/labels/D-IE)    |
| Safari            | macOS High Sierra and newer | Apple            | Built in                                                                     | [Issues](//bugreport.apple.com/logon)                     |

----
url: https://www.selenium.dev/documentation/webdriver/bidi/cdp/
----

# Chrome DevTools Protocol

Examples of working with Chrome DevTools Protocol in Selenium. CDP support is temporary until WebDriver BiDi has been implemented.

```java
    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);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/java/src/test/java/dev/selenium/bidi/cdp/CdpTest.java#L22-L27)

##### /examples/java/src/test/java/dev/selenium/bidi/cdp/CdpTest.java

```java
package dev.selenium.bidi.cdp;

import dev.selenium.BaseTest;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.openqa.selenium.Cookie;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.chromium.HasCdp;

import java.util.HashMap;
import java.util.Map;

public class CdpTest extends BaseTest {
  @BeforeEach
  public void createSession() {
    driver = new ChromeDriver();
  }

  @Test
  public void setCookie() {
    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);

    driver.get("https://www.selenium.dev");
    Cookie cheese = driver.manage().getCookieNamed("cheese");
    Assertions.assertEquals("gouda", cheese.getValue());
  }
}
```

```py
    cookie = {'name': 'cheese',
              'value': 'gouda',
              'domain': 'www.selenium.dev',
              'secure': True}

    driver.execute_cdp_cmd('Network.setCookie', cookie)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/python/tests/bidi/cdp/test_cdp.py#L2-L7)

##### /examples/python/tests/bidi/cdp/test\_cdp.py

```py
def test_set_cookie(driver):
    cookie = {'name': 'cheese',
              'value': 'gouda',
              'domain': 'www.selenium.dev',
              'secure': True}

    driver.execute_cdp_cmd('Network.setCookie', cookie)

    driver.get('https://www.selenium.dev')
    cheese = driver.get_cookie(cookie['name'])

    assert cheese['value'] == 'gouda'
```

```cs
            var cookie = new Dictionary<string, object>
            {
                { "name", "cheese" },
                { "value", "gouda" },
                { "domain", "www.selenium.dev" },
                { "secure", true }
            };
            ((ChromeDriver)driver).ExecuteCdpCommand("Network.setCookie", cookie);
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/dotnet/SeleniumDocs/BiDi/CDP/CDPTest.cs#L14-L21)

##### /examples/dotnet/SeleniumDocs/BiDi/CDP/CDPTest.cs

```cs
using System.Collections.Generic;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using OpenQA.Selenium;
using OpenQA.Selenium.Chrome;

namespace SeleniumDocs.BiDi.CDP
{
    [TestClass]
    public class CDPTest : BaseChromeTest
    {
        [TestMethod]
        public void SetCookie()
        {
            var cookie = new Dictionary<string, object>
            {
                { "name", "cheese" },
                { "value", "gouda" },
                { "domain", "www.selenium.dev" },
                { "secure", true }
            };
            ((ChromeDriver)driver).ExecuteCdpCommand("Network.setCookie", cookie);
            
            driver.Url = "https://www.selenium.dev";
            Cookie cheese = driver.Manage().Cookies.GetCookieNamed("cheese");
            Assert.AreEqual("gouda", cheese.Value);

        }
    }
}
```

```rb
    driver.execute_cdp('Network.setCookie',
                       name: 'cheese',
                       value: 'gouda',
                       domain: 'www.selenium.dev',
                       secure: true)
```

[View Complete Code ]()[**View on GitHub](https://github.com/SeleniumHQ/seleniumhq.github.io/blob/trunk//examples/ruby/spec/bidi/cdp/cdp_spec.rb#L9-L13)

##### /examples/ruby/spec/bidi/cdp/cdp\_spec.rb

```rb
# frozen_string_literal: true

require 'spec_helper'

RSpec.describe 'Logging' do
  let(:driver) { start_session }

  it 'sets cookie' do
    driver.execute_cdp('Network.setCookie',
                       name: 'cheese',
                       value: 'gouda',
                       domain: 'www.selenium.dev',
                       secure: true)

    driver.get('https://www.selenium.dev')
    cheese = driver.manage.cookie_named('cheese')

    expect(cheese[:value]).to eq 'gouda'
  end
end
```

***

##### [Chrome DevTools Logging Features](/documentation/webdriver/bidi/cdp/logging/)

Logging features using CDP.

##### [Chrome DevTools Network Features](/documentation/webdriver/bidi/cdp/network/)

Network features using CDP.

##### [Chrome DevTools Script Features](/documentation/webdriver/bidi/cdp/script/)

Script features using CDP.

Last modified July 10, 2024: [Release 4.22 Updates (#1765) (fa7b1165ed0)](https://github.com/SeleniumHQ/seleniumhq.github.io/commit/fa7b1165ed03cb8051d18522e1775a247f48ade9)

## Development Partners

[](https://www.browserstack.com/automate?utm_campaign=open-source-sponsor\&utm_campaigncode=701OW000009sQwVYAU\&utm_medium=partnered\&utm_source=seleniumorg)

[](https://saucelabs.com/resources/topic-hub/selenium?utm_source=selenium\&utm_medium=website\&utm_campaign=selenium-sponsorship-fy25)

[](https://www.testmuai.com)

## Selenium Level Sponsors

[](https://brightdata.com/?utm_source=brand\&utm_campaign=brnd-mkt_partners_selenium)

[](https://applitools.com/)

[](https://www.thordata.com/?ls=waOicIkB\&lk=selenium)

## Support the Selenium Project

Learn more or view the full list of sponsors.

[Learn more**](/sponsors)